Files
webhook-everything/backend/internal/telegrampackage/telegram.go
Samuel Pua 5de4e97add
All checks were successful
Webhook-Everything/Webhook-Everything/pipeline/head This commit looks good
Feat(send-message): Use html if html tags found
2025-12-08 02:12:42 +08:00

201 lines
5.2 KiB
Go

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)
htmlTags := []string{"<b>", "</b>", "<i>", "</i>", "<u>", "</u>", "<a ", "</a>", "<code>", "</code>", "<pre>", "</pre>"}
for _, tag := range htmlTags {
if strings.Contains(msg, tag) {
chatMsg.ParseMode = "HTML"
break
}
}
_, err = bot.Send(chatMsg)
if err != nil {
log.Println(err)
chatMsg.ParseMode = ""
log.Println("Retrying without parse mode")
_, err = bot.Send(chatMsg)
if err != nil {
log.Println(err)
return 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)
}
if chatIDMap.ChatIDShort == "" {
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)
}
continue
}
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)
}
}
}