package telegrampackage import ( "errors" "fmt" "log" "math/rand" "strings" "time" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/google/uuid" "gorm.io/gorm" ) type ChatIDMap struct { ID uuid.UUID `gorm:"primaryKey;type:uuid;default:uuid_generate_v4()"` CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` ChatID int64 ChatIDShort string } func (env *Env) TelegramSend(chatIDShort string, msg string) error { if chatIDShort == "" { return errors.New("no chat ID provided") } bot, err := tgbotapi.NewBotAPI(env.TelegramAPIKey) if err != nil { log.Println(err) return err } var chatIDMap ChatIDMap err = env.DB.Where(&ChatIDMap{ChatIDShort: chatIDShort}).Last(&chatIDMap).Error if err != nil { log.Println(err) log.Println("No such telegram chat ID") return err } chatMsg := tgbotapi.NewMessage(chatIDMap.ChatID, msg) _, err = bot.Send(chatMsg) if err != nil { log.Println(err) } return nil } func (env *Env) TelegramListenAndGen() error { for { bot, err := tgbotapi.NewBotAPI(env.TelegramAPIKey) if err != nil { log.Println(err) log.Println("Error occured on Telegram listen. Waiting 1 minute") time.Sleep(60 * time.Second) } u := tgbotapi.NewUpdate(0) u.Timeout = 60 updates := bot.GetUpdatesChan(u) for update := range updates { if update.Message == nil { // ignore any non-Message Updates continue } log.Printf("New message: [%s] %s", update.Message.From.UserName, update.Message.Text) // check if contains registration if strings.Compare(update.Message.Text, "/register") == 0 { var chatIDMap ChatIDMap err := env.DB.Where(&ChatIDMap{ChatID: update.Message.Chat.ID}).Last(&chatIDMap).Error // chatID already exists if err == nil { msg := tgbotapi.NewMessage(update.Message.Chat.ID, "You already have a chat ID") _, err := bot.Send(msg) if err != nil { log.Println(err) } msg = tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("Your chat ID is: %s", chatIDMap.ChatIDShort)) _, err = bot.Send(msg) if err != nil { log.Println(err) } } else { currChatCode := genShortCode(5) chatIDMap.ChatIDShort = currChatCode chatIDMap.ChatID = update.Message.Chat.ID err := env.DB.Create(&chatIDMap).Error if err != nil { fmt.Println(err) } msg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("Your chat ID is: %s", chatIDMap.ChatIDShort)) _, err = bot.Send(msg) if err != nil { log.Println(err) } } } else { // Get his current chat ID var chatIDMap ChatIDMap err := env.DB.Where(&ChatIDMap{ChatID: update.Message.Chat.ID}).Last(&chatIDMap).Error if err != nil { fmt.Println(err) } var handled = false for _, currFunc := range env.HandlerFunctions { currHandled, responseText := currFunc(chatIDMap.ChatIDShort, update.Message.Text) handled = handled || currHandled if responseText != nil { splitSendMessage(bot, update.Message.Chat.ID, *responseText) } } if !handled { msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Please send /register to register for a chat ID") _, err := bot.Send(msg) if err != nil { log.Println(err) } } } } } } func genShortCode(n int) string { var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") runeCode := make([]rune, n) for i := range runeCode { runeCode[i] = letters[rand.Intn(len(letters))] } return string(runeCode) } func splitSendMessage(bot *tgbotapi.BotAPI, chatID int64, message string) { MAXMESSAGELENGTH := 2000 leftoverMessage := []rune(tgbotapi.EscapeText("HTML", message)) if len(leftoverMessage) > MAXMESSAGELENGTH { for len(leftoverMessage) > 0 { var currMessage []rune if len(leftoverMessage) <= MAXMESSAGELENGTH { currMessage = leftoverMessage[:] leftoverMessage = []rune("") } else { currMessage = leftoverMessage[:MAXMESSAGELENGTH] leftoverMessage = leftoverMessage[MAXMESSAGELENGTH:] } msg := tgbotapi.NewMessage(chatID, string(currMessage)) msg.ParseMode = "HTML" msg.DisableWebPagePreview = true _, err := bot.Send(msg) if err != nil { msg := tgbotapi.NewMessage(chatID, err.Error()) bot.Send(msg) log.Println(err) } } } else { msg := tgbotapi.NewMessage(chatID, string(message)) msg.ParseMode = "HTML" msg.DisableWebPagePreview = true _, err := bot.Send(msg) if err != nil { msg := tgbotapi.NewMessage(chatID, err.Error()) bot.Send(msg) log.Println(err) } } }