"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"
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)
}
// Set this to true to log all interactions with telegram servers
- telegram.Debug = false
+ telegram.Debug = DEBUG
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
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)
// 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 = "📺 <b>" + getFirstLine(getTextAfterDash(text)) + "</b>\n"
-
- case regexMovie.MatchString(text):
- response = "🎥 <b>" + getFirstLine(getTextAfterDash(text)) + "</b>\n"
- }
-
- switch {
- case regexAvailable.MatchString(text):
- response += "pedida por <b>" + getRequestedBy(text) + "</b>\n\n🎉 Ya disponible!"
-
- case regexNew.MatchString(text):
- response += "pedida para añadir por <b>" + getRequestedBy(text) + "</b>\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()
}
--- /dev/null
+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 = "📺 <b>" + getFirstLine(getTextAfterDash(text)) + "</b>\n"
+
+ case regexMovie.MatchString(text):
+ response = "🎥 <b>" + getFirstLine(getTextAfterDash(text)) + "</b>\n"
+ }
+
+ switch {
+ case regexAvailable.MatchString(text):
+ response += "pedida por <b>" + getRequestedBy(text) + "</b>\n\n🎉 Ya disponible!"
+
+ case regexNew.MatchString(text):
+ response += "pedida para añadir por <b>" + getRequestedBy(text) + "</b>\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
+}