dcbot/cmd/dcbot/internal/run/run.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()
}