package main import ( "fmt" "log" "os" "os/signal" "strings" "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 handleCallbackQuery(update tgbotapi.Update, bot *tgbotapi.BotAPI) { query := update.CallbackQuery // Answer the callback query to remove the loading state callback := tgbotapi.NewCallback(query.ID, "") bot.Request(callback) // Parse callback data format: "command:param1:param2:..." parts := strings.Split(query.Data, ":") if len(parts) < 2 { log.Printf("Invalid callback data format: %s", query.Data) return } commandName := parts[0] switch commandName { case "medchem": // Get the medchem command and handle callback if cmd, ok := commands.All()["medchem"]; ok { if medchemCmd, ok := cmd.(interface { HandleCallback(tgbotapi.Update, *tgbotapi.BotAPI, []string) }); ok { medchemCmd.HandleCallback(update, bot, parts[1:]) } } case "osrs": // Get the OSRS command and handle callback if cmd, ok := commands.All()["osrs"]; ok { if osrsCmd, ok := cmd.(interface { HandleCallback(tgbotapi.Update, *tgbotapi.BotAPI, []string) }); ok { osrsCmd.HandleCallback(update, bot, parts[1:]) } } default: log.Printf("Unknown callback command: %s", commandName) } } 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 { // Handle callback queries (inline keyboard button presses) if update.CallbackQuery != nil { log.Printf("Received callback query: %s from user %d", update.CallbackQuery.Data, update.CallbackQuery.From.ID) handleCallbackQuery(update, bot) continue } if update.Message == nil || !update.Message.IsCommand() { continue } log.Printf("Received command: %s with args %s from chat %d (user %d)", update.Message.Command(), update.Message.CommandArguments(), 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) } } }