package main import ( "fmt" "log" "os" "os/signal" "syscall" "nignoggobot/commands" "nignoggobot/metrics" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" _ "nignoggobot/commands" // ensure init() is called ) var ( devChannelID int64 = -1001327903329 AdminIDs = []int64{126131628} ) func notifyShutdown(reason string) { token := os.Getenv("TELEGRAM_TOKEN") bot, err := tgbotapi.NewBotAPI(token) if err != nil { log.Println("Failed to create bot for shutdown notification:", err) return } msg := tgbotapi.NewMessage(devChannelID, "Bot shutting down/crashed: "+reason) bot.Send(msg) } func main() { // Signal handling for SIGINT/SIGTERM sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-sigs notifyShutdown(fmt.Sprintf("Received signal: %v", sig)) os.Exit(0) }() defer func() { if r := recover(); r != nil { notifyShutdown("panic: " + fmt.Sprint(r)) panic(r) // re-throw after notifying } else { notifyShutdown("normal shutdown") } }() bot, err := tgbotapi.NewBotAPI(os.Getenv("TELEGRAM_TOKEN")) log.Println(os.Getenv("TELEGRAM_TOKEN")) if err != nil { log.Fatal(err) } log.Printf("Authorized on account %s", bot.Self.UserName) u := tgbotapi.NewUpdate(0) u.Timeout = 60 updates := bot.GetUpdatesChan(u) for update := range updates { if update.Message == nil || !update.Message.IsCommand() { continue } log.Printf("Received command: %s from chat %d (user %d)", update.Message.Command(), update.Message.Chat.ID, update.Message.From.ID) cmdName := update.Message.Command() isGroup := update.Message.Chat.IsGroup() || update.Message.Chat.IsSuperGroup() metrics.UpdateChat(update.Message.Chat.ID, isGroup) if cmd, ok := commands.All()[cmdName]; ok { log.Printf("Executing command: %s", cmdName) // Bottleneck here locking mutexes and writing to json every time but oh well metrics.IncrementCommandUsage(cmdName) cmd.Execute(update, bot) } else { log.Printf("Unknown command: %s", cmdName) msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Unknown command.") bot.Send(msg) } } }