237 lines
10 KiB
Go
237 lines
10 KiB
Go
package telegram
|
|
|
|
import (
|
|
"jannex/telegram-bot-manager/modules/cache"
|
|
"jannex/telegram-bot-manager/modules/database"
|
|
"jannex/telegram-bot-manager/modules/logger"
|
|
"jannex/telegram-bot-manager/modules/structs"
|
|
"jannex/telegram-bot-manager/modules/utils"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
var bot *tgbotapi.BotAPI
|
|
|
|
func InitBot() {
|
|
var err error
|
|
|
|
bot, err = tgbotapi.NewBotAPI("6450280279:AAGxXdPv_YwRtl_pXIqYojqOecBrEjn3fJo")
|
|
|
|
if err != nil {
|
|
logger.AddSystemLog(rslogger.LogTypeError, "Failed to initialize Telegram bot, err: %v", err.Error())
|
|
log.Fatal().Err(err).Msgf("Failed to initialize Telegram bot, err: %v", err.Error())
|
|
}
|
|
|
|
//bot.Debug = false
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "Bot connected as %s", bot.Self.UserName)
|
|
|
|
go IncomingMessagesHandler()
|
|
}
|
|
|
|
func IncomingMessagesHandler() {
|
|
updateConfig := tgbotapi.NewUpdate(0)
|
|
updateConfig.Timeout = 60
|
|
|
|
updates, err := bot.GetUpdatesChan(updateConfig)
|
|
|
|
if err != nil {
|
|
logger.AddSystemLog(rslogger.LogTypeError, "Failed to get updates from Telegram bot, err: %v", err.Error())
|
|
log.Fatal().Err(err).Msgf("Failed to get updates from Telegram bot, err: %v", err.Error())
|
|
}
|
|
|
|
for update := range updates {
|
|
if update.Message == nil {
|
|
continue
|
|
}
|
|
|
|
chatID := update.Message.Chat.ID
|
|
text := update.Message.Text
|
|
|
|
if text == "" {
|
|
continue
|
|
}
|
|
|
|
regStart := regexp.MustCompile(`/start`)
|
|
regHelp := regexp.MustCompile(`/help`)
|
|
|
|
regVerify := regexp.MustCompile(`/verify (\w+)`)
|
|
regVerifyMatches := regVerify.FindStringSubmatch(text)
|
|
|
|
regUnsubscribe := regexp.MustCompile(`/unsubscribe`)
|
|
|
|
regFilter := regexp.MustCompile(`/filter`)
|
|
regFilterWithArgs := regexp.MustCompile(`/filter (.+)`)
|
|
regFilterMatches := regFilterWithArgs.FindStringSubmatch(text)
|
|
|
|
var replyMessage string
|
|
|
|
if regStart.MatchString(text) || regHelp.MatchString(text) { // command /start or /help
|
|
replyMessage = "Welcome!\n\n" +
|
|
"Type /verify <code> to start receiving notifications. The code can be found in the user profile on the dashboard.\n\n" +
|
|
"Type /unsubscribe to stop receiving notifications.\n\n" +
|
|
"Type /filter <filter> to filter notifications. Filter can be: success, info, warning, error. For example: /filter info,warning,error will filter all notifications except success."
|
|
|
|
SendNotification(chatID, replyMessage)
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "Received command %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName)
|
|
} else if len(regVerifyMatches) == 2 { // command /verify <code>
|
|
code := regVerifyMatches[1]
|
|
|
|
if len(code) != utils.VerifyCodeLength {
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "Received code with wrong length from user: %s %s. Message: %s", update.Message.From.FirstName, update.Message.From.LastName, code)
|
|
continue
|
|
}
|
|
|
|
var tempVerify structs.TempVerifyCode
|
|
var ok bool
|
|
|
|
if tempVerify, ok = cache.GetTempVerifyByCode(code); !ok {
|
|
// code not found in cache
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "Received code which was not found in cache from user: %s %s. Message: %s", update.Message.From.FirstName, update.Message.From.LastName, code)
|
|
|
|
replyMessage = "The code you entered is invalid. Please check the code and try again."
|
|
} else {
|
|
// code found in cache
|
|
|
|
var foundVerifiedUser structs.VerifiedUser
|
|
|
|
database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser)
|
|
|
|
if foundVerifiedUser.UserId != "" {
|
|
// user already verified
|
|
|
|
replyMessage = "You have already verified your account. You will continue to receive notifications. Type /unsubscribe to stop receiving notifications."
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to verify his account with code %s, but has already verified his account", update.Message.From.FirstName, update.Message.From.LastName, code)
|
|
} else {
|
|
// user not verified
|
|
|
|
replyMessage = "You have successfully verified your account. You will now receive notifications. Type /unsubscribe to stop receiving notifications."
|
|
|
|
database.DB.Create(&structs.VerifiedUser{
|
|
UserId: tempVerify.UserId,
|
|
ChatId: update.Message.From.ID,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has subscribed to receive notifications", update.Message.From.FirstName, update.Message.From.LastName)
|
|
}
|
|
|
|
cache.RemoveTempVerifyCode(tempVerify.UserId)
|
|
}
|
|
|
|
SendNotification(chatID, replyMessage)
|
|
} else if regUnsubscribe.MatchString(text) { // command /unsubscribe
|
|
res := database.DB.Delete(&structs.VerifiedUser{}, "chat_id = ?", update.Message.From.ID)
|
|
|
|
if res.Error != nil {
|
|
logger.AddSystemLog(rslogger.LogTypeError, "Failed to delete verified user from database, err: %v", res.Error.Error())
|
|
continue
|
|
}
|
|
|
|
if res.RowsAffected == 0 {
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to unsubscribe from receiving notifications, but has not been verified", update.Message.From.FirstName, update.Message.From.LastName)
|
|
replyMessage = "You have not been verified yet. Type /verify <code> to start receiving notifications. The code can be found in the user profile on the dashboard."
|
|
} else {
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has unsubscribed from receiving notifications", update.Message.From.FirstName, update.Message.From.LastName)
|
|
replyMessage = "You have unsubscribed from receiving notifications. Type /verify <code> to start receiving notifications again. The code can be found in the user profile on the dashboard."
|
|
}
|
|
|
|
SendNotification(chatID, replyMessage)
|
|
} else if len(regFilterMatches) == 2 { // command /filter <filters>
|
|
setFilter(chatID, update, text, regFilterMatches)
|
|
} else if regFilter.MatchString(text) { // command /filter
|
|
var foundVerifiedUser structs.VerifiedUser
|
|
database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser)
|
|
|
|
if foundVerifiedUser.UserId == "" {
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to get filter, but has not been verified", update.Message.From.FirstName, update.Message.From.LastName)
|
|
SendNotification(chatID, "You have not been verified yet. Type /verify <code> to start receiving notifications. The code can be found in the user profile on the dashboard.")
|
|
} else {
|
|
formattedFilters := utils.GetFormattedFilters(foundVerifiedUser.Filter)
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has requested filter, current filter: %s", update.Message.From.FirstName, update.Message.From.LastName, formattedFilters)
|
|
SendNotification(chatID, "Your current filter is: "+formattedFilters)
|
|
}
|
|
} else {
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "Received unknown message: %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName)
|
|
}
|
|
}
|
|
}
|
|
|
|
func SendNotification(chatId int64, message string) {
|
|
msg := tgbotapi.NewMessage(chatId, message)
|
|
|
|
if _, err := bot.Send(msg); err != nil {
|
|
logger.AddSystemLog(rslogger.LogTypeError, "Failed to send notification to chatId %v message: %s, err: %v", chatId, message, err.Error())
|
|
}
|
|
}
|
|
|
|
func setFilter(chatID int64, update tgbotapi.Update, text string, regFilterMatches []string) {
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "Received filter message: %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName)
|
|
|
|
filter := regFilterMatches[1]
|
|
filterValues := strings.Split(filter, ",")
|
|
|
|
for _, v := range filterValues {
|
|
switch v {
|
|
case utils.NotificationTypeSuccess,
|
|
utils.NotificationTypeInfoString,
|
|
utils.NotificationTypeWarningString,
|
|
utils.NotificationTypeErrorString:
|
|
continue
|
|
default:
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "Received unknown filter value: %s from user: %s %s", v, update.Message.From.FirstName, update.Message.From.LastName)
|
|
SendNotification(chatID, "You have entered an invalid filter value. Filter can be: success, info, warning, error. For example: /filter info,warning,error will filter all notifications except success.")
|
|
return
|
|
}
|
|
}
|
|
|
|
var filteredValues []string
|
|
var filteredTextValues []string
|
|
|
|
for _, v := range filterValues {
|
|
switch v {
|
|
case utils.NotificationTypeSuccessString:
|
|
filteredValues = append(filteredValues, utils.NotificationTypeSuccess)
|
|
filteredTextValues = append(filteredTextValues, utils.NotificationTypeSuccessString)
|
|
case utils.NotificationTypeInfoString:
|
|
filteredValues = append(filteredValues, utils.NotificationTypeInfo)
|
|
filteredTextValues = append(filteredTextValues, utils.NotificationTypeInfoString)
|
|
case utils.NotificationTypeWarningString:
|
|
filteredValues = append(filteredValues, utils.NotificationTypeWarning)
|
|
filteredTextValues = append(filteredTextValues, utils.NotificationTypeWarningString)
|
|
case utils.NotificationTypeErrorString:
|
|
filteredValues = append(filteredValues, utils.NotificationTypeError)
|
|
filteredTextValues = append(filteredTextValues, utils.NotificationTypeErrorString)
|
|
}
|
|
}
|
|
|
|
var foundVerifiedUser structs.VerifiedUser
|
|
database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser)
|
|
|
|
if foundVerifiedUser.UserId == "" {
|
|
logger.AddSystemLog(rslogger.LogTypeWarning, "User: %s %s has tried to set filter, but has not been verified", update.Message.From.FirstName, update.Message.From.LastName)
|
|
SendNotification(chatID, "You have not been verified yet. Type /verify <code> to start receiving notifications. The code can be found in the user profile on the dashboard.")
|
|
return
|
|
}
|
|
|
|
filter = strings.Join(filteredValues, ",")
|
|
|
|
database.DB.Model(&structs.VerifiedUser{}).
|
|
Where("chat_id = ?", update.Message.From.ID).
|
|
Updates(structs.VerifiedUser{Filter: filter})
|
|
|
|
formattedFilteredTextValues := strings.Join(filteredTextValues, ", ")
|
|
|
|
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has set filter to %s (%s)", update.Message.From.FirstName, update.Message.From.LastName, filter, formattedFilteredTextValues)
|
|
|
|
SendNotification(chatID, "You have successfully set filter to "+formattedFilteredTextValues+". You will now only receive notifications with the selected filter.")
|
|
}
|