From d93287a12c4ef8cb36eda42716701255719b4a5a Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 28 Mar 2024 18:57:35 +0100 Subject: [PATCH] added debug constant and moved telegram crap to its file --- bot.go | 213 +++++----------------------------------------------- telegram.go | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 224 insertions(+), 196 deletions(-) create mode 100644 telegram.go diff --git a/bot.go b/bot.go index 7debfb9..e5350fa 100644 --- a/bot.go +++ b/bot.go @@ -5,14 +5,16 @@ import ( "log" "os" "os/signal" - "regexp" - "strings" "syscall" "github.com/bwmarrin/discordgo" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) +const ( + DEBUG bool = true +) + var ( TgApiToken = "6444047266:AAH86vKKDeMktgpqDIwWElH_s9nu-ZgqdB8" DiscApiToken = "MTIwMzg0MzAyMDg5ODgzMjM5NA.G6e3Eo.yU90uQzHOMCw-cHguOhzwlXhnIcHo5YId60U64" @@ -44,6 +46,10 @@ var ( usersInVoiceChat []string ) +// main is the entry point of the program. +// It initializes the Telegram bot, sets up the necessary configurations, +// starts receiving updates from Telegram, and opens a connection to Discord. +// It also handles the cancellation of updates and waits for a termination signal. func main() { var err error telegram, err = tgbotapi.NewBotAPI(TgApiToken) @@ -53,7 +59,7 @@ func main() { } // Set this to true to log all interactions with telegram servers - telegram.Debug = false + telegram.Debug = DEBUG u := tgbotapi.NewUpdate(0) u.Timeout = 60 @@ -77,7 +83,12 @@ func main() { log.Println("error creating Discord session,", err) return } - discord.LogLevel = discordgo.LogDebug + + if DEBUG { + discord.LogLevel = discordgo.LogDebug + } else { + discord.LogLevel = discordgo.LogInformational + } discord.AddHandlerOnce(ready) discord.AddHandlerOnce(guildCreated) discord.AddHandler(voiceChatUpdate) @@ -94,201 +105,11 @@ func main() { // Tell the user the bot is online log.Println("Discord Bot ready.") + // Block until a termination signal is received done := make(chan os.Signal, 1) signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) log.Println("Blocking, press ctrl+c to continue...") - // Wait for a ctrl+c, then cancel handling updates <-done cancel() -} - -func receiveUpdates(ctx context.Context, updates tgbotapi.UpdatesChannel) { - // `for {` means the loop is infinite until we manually stop it - for { - select { - // stop looping if ctx is cancelled - case <-ctx.Done(): - return - // receive update from channel and then handle it - case update := <-updates: - handleUpdate(update) - } - } -} - -func handleUpdate(update tgbotapi.Update) { - switch { - // Handle messages - case update.Message != nil: - handleMessage(update.Message) - - // handle buttons click - case update.CallbackQuery != nil: - handleButton(update.CallbackQuery) - } -} - -func handleMessage(message *tgbotapi.Message) { - lastMsg = message - - user := message.From - text := message.Text - - if text == "" { - text = message.Caption - } - - if user == nil { - return - } - - // Print to console - log.Printf("%s wrote %s", user.FirstName, text) - - var err error - if strings.HasPrefix(text, "/") { - err = handleCommand(message.Chat.ID, text) - } else { - err = handleConversation(message.Chat.ID, text) - } - - if err != nil { - log.Printf("An error occured: %s", err.Error()) - } -} - -// When we get a command, we react accordingly -func handleCommand(chatId int64, command string) error { - var err error - - switch command { - case "/start": - err = sendMenu(chatId) - - case "/help": - err = sendTelegramMessage(chatId, "Currently my only comands are /start, /help and /sylph\n I'm a work in progress, please don't tease me.") - - case "/sylph": - err = sendTelegramMessage(chatId, "Hola!") - } - - return err -} - -func handleConversation(chatId int64, text string) error { - var err error - text = strings.ToLower(text) - - var regexIssue = regexp.MustCompile(`(?i)\bIssue\b`) - var regexRequest = regexp.MustCompile(`(?i)\bRequest\b`) - - switch { - case text == "hola", - text == "hola sylph": - err = sendTelegramMessage(chatId, "Hola!") - - case regexIssue.MatchString(text): - err = manageIssueMessage(chatId, text) - - case regexRequest.MatchString(text): - err = manageSerieRequest(chatId, text) - - default: - err = sendTelegramMessage(chatId, "Jej. No entiendi. 🤣") - } - - return err -} - -func manageIssueMessage(chatId int64, text string) error { - var err error - - // issue can be: comment, resolved, reported - // issues can be type: video, audio, subtitle - - //TODO: manage issues - - return err -} - -func manageSerieRequest(chatId int64, text string) error { - var err error - var response string = "" - - // request can be: new, available - // request can be type: series, movie - var regexNew = regexp.MustCompile(`(?i)\bNew\b`) - var regexAvailable = regexp.MustCompile(`(?i)\bAvailable\b`) - var regexSeries = regexp.MustCompile(`(?i)\bSeries\b`) - var regexMovie = regexp.MustCompile(`(?i)\bMovie\b`) - - switch { - case regexSeries.MatchString(text): - // get from text whatever is after the first - and the end of the line - response = "📺 " + getFirstLine(getTextAfterDash(text)) + "\n" - - case regexMovie.MatchString(text): - response = "🎥 " + getFirstLine(getTextAfterDash(text)) + "\n" - } - - switch { - case regexAvailable.MatchString(text): - response += "pedida por " + getRequestedBy(text) + "\n\n🎉 Ya disponible!" - - case regexNew.MatchString(text): - response += "pedida para añadir por " + getRequestedBy(text) + "\n\n(en cola)" - } - - // TODO: remove sent message to replace with ours? - err = sendTelegramPhoto(chatId, lastMsg.Photo[0].FileID, response) - return err -} - -func sendMenu(chatId int64) error { - msg := tgbotapi.NewMessage(chatId, botText) - msg.ParseMode = tgbotapi.ModeHTML - msg.ReplyMarkup = menuTextMarkup - msg.DisableNotification = true - resMsg, err := telegram.Send(msg) - botMsg = &resMsg - return err -} - -func sendTelegramMessage(chatId int64, text string) error { - msg := tgbotapi.NewMessage(chatId, text) - msg.ParseMode = tgbotapi.ModeHTML - _, err := telegram.Send(msg) - return err -} - -func sendTelegramPhoto(chatId int64, photo string, text string) error { - msg := tgbotapi.NewPhoto(chatId, tgbotapi.FileURL(photo)) - msg.ParseMode = tgbotapi.ModeHTML - msg.Caption = text - _, err := telegram.Send(msg) - return err -} - -func handleButton(query *tgbotapi.CallbackQuery) { - var text string - - markup := tgbotapi.NewInlineKeyboardMarkup() - message := query.Message - - if botMsg == nil { - botMsg = message - } - - if query.Data == UpdateTextBtn { - text = botText - markup = menuTextMarkup - } - - callbackCfg := tgbotapi.NewCallback(query.ID, "") - telegram.Send(callbackCfg) - - // Replace menu text and keyboard - msg := tgbotapi.NewEditMessageTextAndMarkup(message.Chat.ID, message.MessageID, text, markup) - msg.ParseMode = tgbotapi.ModeHTML - telegram.Send(msg) + discord.Close() } diff --git a/telegram.go b/telegram.go new file mode 100644 index 0000000..d15b61c --- /dev/null +++ b/telegram.go @@ -0,0 +1,207 @@ +package main + +import ( + "context" + "log" + "regexp" + "strings" + + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" +) + +// All Telegram bot related crap will be here, even if it's not directly related to Telegram + +func receiveUpdates(ctx context.Context, updates tgbotapi.UpdatesChannel) { + // `for {` means the loop is infinite until we manually stop it + for { + select { + // stop looping if ctx is cancelled + case <-ctx.Done(): + return + // receive update from channel and then handle it + case update := <-updates: + handleUpdate(update) + } + } +} + +func handleUpdate(update tgbotapi.Update) { + switch { + // Handle messages + case update.Message != nil: + handleMessage(update.Message) + + // handle buttons click + case update.CallbackQuery != nil: + handleButton(update.CallbackQuery) + } +} + +func handleMessage(message *tgbotapi.Message) { + lastMsg = message + + user := message.From + text := message.Text + + if text == "" { + text = message.Caption + } + + if user == nil { + return + } + + // Print to console + if DEBUG { + log.Printf("%s wrote %s", user.FirstName, text) + } + + var err error + if strings.HasPrefix(text, "/") { + err = handleCommand(message.Chat.ID, text) + } else { + err = handleConversation(message.Chat.ID, text) + } + + if err != nil { + log.Printf("An error occured: %s", err.Error()) + } +} + +func sendMenu(chatId int64) error { + msg := tgbotapi.NewMessage(chatId, botText) + msg.ParseMode = tgbotapi.ModeHTML + msg.ReplyMarkup = menuTextMarkup + msg.DisableNotification = true + resMsg, err := telegram.Send(msg) + botMsg = &resMsg + return err +} + +func handleButton(query *tgbotapi.CallbackQuery) { + var text string + + markup := tgbotapi.NewInlineKeyboardMarkup() + message := query.Message + + if botMsg == nil { + botMsg = message + } + + if query.Data == UpdateTextBtn { + text = botText + markup = menuTextMarkup + } + + callbackCfg := tgbotapi.NewCallback(query.ID, "") + telegram.Send(callbackCfg) + + // Replace menu text and keyboard + msg := tgbotapi.NewEditMessageTextAndMarkup(message.Chat.ID, message.MessageID, text, markup) + msg.ParseMode = tgbotapi.ModeHTML + telegram.Send(msg) +} + +// When we get a command, we react accordingly +func handleCommand(chatId int64, command string) error { + var err error + + switch command { + case "/start": + err = sendMenu(chatId) + + case "/help": + err = sendTelegramMessage(chatId, "Currently my only comands are /start, /help and /sylph\n I'm a work in progress, please don't tease me.") + + case "/sylph": + err = sendTelegramMessage(chatId, "Hola!") + } + + return err +} + +func handleConversation(chatId int64, text string) error { + var err error + text = strings.ToLower(text) + + var regexIssue = regexp.MustCompile(`(?i)\bIssue\b`) + var regexRequest = regexp.MustCompile(`(?i)\bRequest\b`) + + switch { + case text == "hola", + text == "hola sylph": + err = sendTelegramMessage(chatId, "Hola!") + + case regexIssue.MatchString(text): + err = manageIssueMessage(chatId, text) + + case regexRequest.MatchString(text): + err = manageSerieRequest(chatId, text) + + default: + err = sendTelegramMessage(chatId, "Jej. No entiendi. 🤣") + } + + return err +} + +func manageSerieRequest(chatId int64, text string) error { + var err error + var response string = "" + + // request can be: new, available + // request can be type: series, movie + var regexNew = regexp.MustCompile(`(?i)\bNew\b`) + var regexAvailable = regexp.MustCompile(`(?i)\bAvailable\b`) + var regexSeries = regexp.MustCompile(`(?i)\bSeries\b`) + var regexMovie = regexp.MustCompile(`(?i)\bMovie\b`) + + switch { + case regexSeries.MatchString(text): + // get from text whatever is after the first - and the end of the line + response = "📺 " + getFirstLine(getTextAfterDash(text)) + "\n" + + case regexMovie.MatchString(text): + response = "🎥 " + getFirstLine(getTextAfterDash(text)) + "\n" + } + + switch { + case regexAvailable.MatchString(text): + response += "pedida por " + getRequestedBy(text) + "\n\n🎉 Ya disponible!" + + case regexNew.MatchString(text): + response += "pedida para añadir por " + getRequestedBy(text) + "\n\n(en cola)" + } + + // TODO: remove sent message to replace with ours? + err = sendTelegramPhoto(chatId, lastMsg.Photo[0].FileID, response) + return err +} + +func manageIssueMessage(chatId int64, text string) error { + var err error + + // issue can be: comment, resolved, reported + // issues can be type: video, audio, subtitle + + //TODO: manage issues + + return err +} + +func sendTelegramMessage(chatId int64, text string) error { + msg := tgbotapi.NewMessage(chatId, text) + msg.ParseMode = tgbotapi.ModeHTML + _, err := telegram.Send(msg) + return err +} + +// Send a photo to a chat. +// Photo must be a URL, can be the link from a previous telegram message photo. +func sendTelegramPhoto(chatId int64, photo string, text string) error { + msg := tgbotapi.NewPhoto(chatId, tgbotapi.FileURL(photo)) + msg.ParseMode = tgbotapi.ModeHTML + msg.Caption = text + _, err := telegram.Send(msg) + return err +} -- 2.30.2