105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package run
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"gitea.dwysokinski.me/twhelp/dcbot/cmd/dcbot/internal"
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/adapter"
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/discord"
|
|
"gitea.dwysokinski.me/twhelp/dcbot/internal/service"
|
|
"github.com/kelseyhightower/envconfig"
|
|
"github.com/urfave/cli/v2"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
const (
|
|
healthyFilePath = "/tmp/healthy"
|
|
healthyFilePerm = 0644
|
|
)
|
|
|
|
func New() *cli.Command {
|
|
return &cli.Command{
|
|
Name: "run",
|
|
Usage: "Runs the dc bot",
|
|
Action: func(c *cli.Context) error {
|
|
logger := zap.L()
|
|
|
|
cfg, err := newBotConfig()
|
|
if err != nil {
|
|
return fmt.Errorf("newBotConfig: %w", err)
|
|
}
|
|
|
|
db, err := internal.NewBunDB()
|
|
if err != nil {
|
|
return fmt.Errorf("internal.NewBunDB: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = db.Close()
|
|
}()
|
|
|
|
redisClient, err := internal.NewRedisClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
twhelpService, err := internal.NewTWHelpService(c.App.Version)
|
|
if err != nil {
|
|
return fmt.Errorf("internal.NewTWHelpService: %w", err)
|
|
}
|
|
|
|
groupRepo := adapter.NewGroupBun(db)
|
|
villageRepo := adapter.NewVillageRedis(redisClient)
|
|
|
|
choiceSvc := service.NewChoice(twhelpService)
|
|
groupSvc := service.NewGroup(groupRepo, twhelpService, logger, cfg.MaxGroupsPerServer, cfg.MaxMonitorsPerGroup)
|
|
villageSvc := service.NewVillage(villageRepo, twhelpService)
|
|
|
|
bot, err := discord.NewBot(cfg.Token, groupSvc, choiceSvc, villageSvc, logger)
|
|
if err != nil {
|
|
return fmt.Errorf("discord.NewBot: %w", err)
|
|
}
|
|
defer func() {
|
|
_ = bot.Close()
|
|
}()
|
|
|
|
go func() {
|
|
if runErr := bot.Run(); runErr != nil {
|
|
logger.Fatal("something went wrong while starting the bot", zap.Error(runErr))
|
|
}
|
|
}()
|
|
|
|
if err = os.WriteFile(healthyFilePath, []byte("healthy"), healthyFilePerm); err != nil {
|
|
return fmt.Errorf("couldn't create file (path=%s): %w", healthyFilePath, err)
|
|
}
|
|
|
|
waitForSignal(c.Context)
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
type botConfig struct {
|
|
Token string `envconfig:"TOKEN" required:"true"`
|
|
MaxGroupsPerServer int `envconfig:"MAX_GROUPS_PER_SERVER" default:"5"`
|
|
MaxMonitorsPerGroup int `envconfig:"MAX_MONITORS_PER_GROUP" default:"10"`
|
|
}
|
|
|
|
func newBotConfig() (botConfig, error) {
|
|
var cfg botConfig
|
|
if err := envconfig.Process("BOT", &cfg); err != nil {
|
|
return botConfig{}, fmt.Errorf("envconfig.Process: %w", err)
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func waitForSignal(ctx context.Context) {
|
|
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
<-ctx.Done()
|
|
}
|