ticket-pimp/cmd/main.go

183 lines
4.3 KiB
Go

package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"ticket-pimp/bot/handler"
discordbot "ticket-pimp/discord-bot"
"ticket-pimp/internal/domain"
"ticket-pimp/internal/services"
db "ticket-pimp/internal/storage/db/tickets"
"github.com/jackc/pgx/v5"
"github.com/joho/godotenv"
"github.com/mr-linch/go-tg"
"github.com/mr-linch/go-tg/tgb"
)
func main() {
log.Print("started")
config := env("develop.env")
run(config)
}
func run(conf domain.Config) {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill, syscall.SIGTERM)
defer cancel()
conn, err := pgx.Connect(
ctx,
fmt.Sprintf(
"postgresql://%s:%s@%s:%s/%s",
conf.DB.User,
conf.DB.Pass,
conf.DB.Host,
conf.DB.Port,
conf.DB.Name,
))
if err != nil {
log.Fatalf("DB connection failed: %v", err)
}
defer conn.Close(ctx)
opts := TelegramOptions{
ticketsRepo: db.New(conn),
gitService: services.NewGit(conf.Git),
cloudService: services.NewCloud(conf.Cloud),
coda: services.NewCodaClient(conf.Coda),
appConfig: &conf,
}
go func() {
if err := runDiscrodBot(conf); err != nil {
log.Fatalf("discord bot cannot be runned: %v", err)
}
}()
if err := runTgBot(ctx, opts); err != nil {
log.Fatalf("telegram bot cannot be runned: %v", err)
defer os.Exit(1)
}
}
// env
// env function reads provided file and setup envirmental variables;
func env(envFilePath string) domain.Config {
err := godotenv.Load(envFilePath)
if err != nil {
log.Fatal("Error while loading env file")
}
return domain.Config{
Git: domain.GitConfig{
BaseUrl: os.Getenv("GIT_BASE_URL"),
Token: os.Getenv("GIT_TOKEN"),
User: os.Getenv("GIT_USER"),
},
Cloud: domain.CloudConfig{
BaseUrl: os.Getenv("CLOUD_BASE_URL"),
User: os.Getenv("CLOUD_USER"),
Pass: os.Getenv("CLOUD_PASS"),
RootDir: os.Getenv("ROOTDIR"),
},
Coda: domain.CodaConfig{
Farm: os.Getenv("CODA_TOKEN1"),
Develop: os.Getenv("CODA_TOKEN2"),
},
DB: domain.DBConfig{
Host: os.Getenv("DB_HOST"),
Port: os.Getenv("DB_PORT"),
Name: os.Getenv("DB_NAME"),
User: os.Getenv("DB_USER"),
Pass: os.Getenv("DB_PASS"),
SslMode: os.Getenv("SSLMODE"),
},
Telegram: domain.TelegramConfig{
Token: os.Getenv("TG_API"),
},
Discord: domain.DiscordConfig{
Token: os.Getenv("DISCORD_TOKEN"),
},
}
}
func runDiscrodBot(conf domain.Config) error {
token := conf.Discord.Token
dbot, err := discordbot.NewDiscordBot(token)
if err != nil {
return err
}
createRepoHandler := discordbot.CreateRepoHandler(3)
dbot.Session.AddHandler(createRepoHandler.Handler)
if err := dbot.Session.Open(); err != nil {
return fmt.Errorf("cannot open the session: %v", err)
}
log.Println("Adding commands...")
cmd, err := dbot.Session.ApplicationCommandCreate(dbot.Session.State.User.ID, "", &createRepoHandler.Command)
if err != nil {
log.Panicf("Cannot create '%v' command: %v", createRepoHandler.Command.Name, err)
}
defer dbot.Session.Close()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
<-stop
log.Println("Graceful shutdown")
log.Println("Removing commands...")
err = dbot.Session.ApplicationCommandDelete(dbot.Session.State.User.ID, "", cmd.ID)
if err != nil {
log.Panicf("Cannot delete '%v' command: %v", cmd.Name, err)
}
return nil
}
type TelegramOptions struct {
ticketsRepo *db.Queries
gitService *services.Git
cloudService *services.Cloud
coda *services.Coda
appConfig *domain.Config
}
// runTgBot ...
// ..function creates new Telegram BOT instance
// ..throw env variables through bot's handlers
// ..setup tg bot router;
// and finally returns tgb.Poller
func runTgBot(ctx context.Context, opts TelegramOptions) error {
log.Print("Start telegram bot init..")
client := tg.New(opts.appConfig.Telegram.Token)
h := handler.NewHandler(
opts.gitService,
opts.cloudService,
opts.coda,
opts.ticketsRepo,
)
router := tgb.NewRouter().
Message(h.Init, tgb.Command("init")).
Message(h.PingHandler, tgb.Command("ping")).
Message(h.DevelopmentTaskHandler, tgb.TextHasPrefix("/new")).
Message(h.NewRepoHandler, tgb.TextHasPrefix("/repo")).
Message(h.NewFolderHandler, tgb.TextHasPrefix("/folder")).
Message(h.FarmTaskHandler, tgb.TextHasPrefix("/task"))
return tgb.NewPoller(
router,
client,
).Run(ctx)
}