start, help and filter command

main
alex 2023-10-21 17:06:56 +02:00
parent 534694a220
commit c714aff989
9 changed files with 185 additions and 71 deletions

53
main.go
View File

@ -61,7 +61,10 @@ MARIADB_DATABASE_NAME=db_database_name`)
} }
func main() { func main() {
app := fiber.New() app := fiber.New(fiber.Config{
// deactivate zero allocation
Immutable: true,
})
app.Use(cors.New()) app.Use(cors.New())
@ -79,51 +82,3 @@ func main() {
app.Listen(config.Cfg.Host + ":" + config.Cfg.Port) app.Listen(config.Cfg.Host + ":" + config.Cfg.Port)
} }
/*
func main() {
// Setze deinen Telegram Bot Token hier ein
bot, err := tgbotapi.NewBotAPI("6450280279:AAGxXdPv_YwRtl_pXIqYojqOecBrEjn3fJo")
if err != nil {
log.Panic(err)
}
bot.Debug = true
log.Printf("Angemeldet als %s", bot.Self.UserName)
// Erstelle eine Nachricht, die du senden möchtest
msg := tgbotapi.NewMessage(935432572, "Das freut mich mein Hase. Ich liebe dich.")
// Sende die Nachricht
_, err = bot.Send(msg)
if err != nil {
log.Panic(err)
}
// Erstelle eine Update-Konfiguration, um auf eingehende Nachrichten zu reagieren
updateConfig := tgbotapi.NewUpdate(0)
updateConfig.Timeout = 60
updates, err := bot.GetUpdatesChan(updateConfig)
for update := range updates {
if update.Message == nil {
continue
}
chatID := update.Message.Chat.ID
text := update.Message.Text
log.Printf("[%s] %s", update.Message.From.UserName, text)
// Hier kannst du auf die empfangene Nachricht reagieren
// Zum Beispiel, eine Antwort senden
reply := tgbotapi.NewMessage(chatID, "Du hast folgende Nachricht gesendet: "+text)
_, err := bot.Send(reply)
if err != nil {
log.Panic(err)
}
}
}
*/

View File

@ -15,17 +15,17 @@ func AddTempVerifyCode(tempVerifyCode structs.TempVerifyCode) {
tempVerifyCodes[tempVerifyCode.UserId] = tempVerifyCode tempVerifyCodes[tempVerifyCode.UserId] = tempVerifyCode
} }
func GetTempVerifyByCode(code string) (userId string, found bool) { func GetTempVerifyByCode(code string) (tempVerify structs.TempVerifyCode, found bool) {
tMu.RLock() tMu.RLock()
defer tMu.RUnlock() defer tMu.RUnlock()
for _, v := range tempVerifyCodes { for _, v := range tempVerifyCodes {
if v.Code == code { if v.Code == code {
return v.UserId, true return v, true
} }
} }
return "", false return structs.TempVerifyCode{}, false
} }
func GetTempVerifyCode(userId string) (string, bool) { func GetTempVerifyCode(userId string) (string, bool) {

View File

@ -5,6 +5,7 @@ import "time"
type VerifiedUser struct { type VerifiedUser struct {
UserId string UserId string
ChatId int ChatId int
Filter string
CreatedAt time.Time CreatedAt time.Time
} }

View File

@ -7,6 +7,7 @@ import (
"jannex/telegram-bot-manager/modules/structs" "jannex/telegram-bot-manager/modules/structs"
"jannex/telegram-bot-manager/modules/utils" "jannex/telegram-bot-manager/modules/utils"
"regexp" "regexp"
"strings"
"time" "time"
"git.ex.umbach.dev/Alex/roese-utils/rslogger" "git.ex.umbach.dev/Alex/roese-utils/rslogger"
@ -56,14 +57,30 @@ func IncomingMessagesHandler() {
continue continue
} }
regStart := regexp.MustCompile(`/start`)
regHelp := regexp.MustCompile(`/help`)
regVerify := regexp.MustCompile(`/verify (\w+)`) regVerify := regexp.MustCompile(`/verify (\w+)`)
regVerifyMatches := regVerify.FindStringSubmatch(text) regVerifyMatches := regVerify.FindStringSubmatch(text)
regUnsubscribe := regexp.MustCompile(`/unsubscribe`) regUnsubscribe := regexp.MustCompile(`/unsubscribe`)
regFilter := regexp.MustCompile(`/filter`)
regFilterWithArgs := regexp.MustCompile(`/filter (.+)`)
regFilterMatches := regFilterWithArgs.FindStringSubmatch(text)
var replyMessage string var replyMessage string
if len(regVerifyMatches) == 2 { 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] code := regVerifyMatches[1]
if len(code) != utils.VerifyCodeLength { if len(code) != utils.VerifyCodeLength {
@ -71,10 +88,10 @@ func IncomingMessagesHandler() {
continue continue
} }
var userId string var tempVerify structs.TempVerifyCode
var ok bool var ok bool
if userId, ok = cache.GetTempVerifyByCode(code); !ok { if tempVerify, ok = cache.GetTempVerifyByCode(code); !ok {
// code not found in cache // 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) 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)
@ -83,8 +100,6 @@ func IncomingMessagesHandler() {
} else { } else {
// code found in cache // code found in cache
cache.RemoveTempVerifyCode(userId)
var foundVerifiedUser structs.VerifiedUser var foundVerifiedUser structs.VerifiedUser
database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser) database.DB.Where("chat_id = ?", update.Message.From.ID).First(&foundVerifiedUser)
@ -101,17 +116,19 @@ func IncomingMessagesHandler() {
replyMessage = "You have successfully verified your account. You will now receive notifications. Type /unsubscribe to stop receiving notifications." replyMessage = "You have successfully verified your account. You will now receive notifications. Type /unsubscribe to stop receiving notifications."
database.DB.Create(&structs.VerifiedUser{ database.DB.Create(&structs.VerifiedUser{
UserId: userId, UserId: tempVerify.UserId,
ChatId: update.Message.From.ID, ChatId: update.Message.From.ID,
CreatedAt: time.Now(), CreatedAt: time.Now(),
}) })
logger.AddSystemLog(rslogger.LogTypeInfo, "User: %s %s has subscribed to receive notifications", update.Message.From.FirstName, update.Message.From.LastName) 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) SendNotification(chatID, replyMessage)
} else if regUnsubscribe.MatchString(text) { } else if regUnsubscribe.MatchString(text) { // command /unsubscribe
res := database.DB.Delete(&structs.VerifiedUser{}, "chat_id = ?", update.Message.From.ID) res := database.DB.Delete(&structs.VerifiedUser{}, "chat_id = ?", update.Message.From.ID)
if res.Error != nil { if res.Error != nil {
@ -128,6 +145,20 @@ func IncomingMessagesHandler() {
} }
SendNotification(chatID, replyMessage) 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 { } else {
logger.AddSystemLog(rslogger.LogTypeWarning, "Received unknown message: %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName) logger.AddSystemLog(rslogger.LogTypeWarning, "Received unknown message: %s from user: %s %s", text, update.Message.From.FirstName, update.Message.From.LastName)
} }
@ -141,3 +172,65 @@ func SendNotification(chatId int64, message string) {
logger.AddSystemLog(rslogger.LogTypeError, "Failed to send notification to chatId %v message: %s, err: %v", chatId, message, err.Error()) 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.")
}

View File

@ -1,6 +1,8 @@
package utils package utils
import "time" import (
"time"
)
const ( const (
VerifyCodeLength = 6 VerifyCodeLength = 6
@ -10,4 +12,14 @@ const (
NotificationSymbolInfo = "🔵" NotificationSymbolInfo = "🔵"
NotificationSymbolWarnung = "🟠" NotificationSymbolWarnung = "🟠"
NotificationSymbolError = "🔴" NotificationSymbolError = "🔴"
NotificationTypeSuccess = "1"
NotificationTypeInfo = "2"
NotificationTypeWarning = "3"
NotificationTypeError = "4"
NotificationTypeSuccessString = "success"
NotificationTypeInfoString = "info"
NotificationTypeWarningString = "warning"
NotificationTypeErrorString = "error"
) )

View File

@ -1,6 +1,11 @@
package utils package utils
import "jannex/telegram-bot-manager/modules/structs" import (
"jannex/telegram-bot-manager/modules/logger"
"strings"
"git.ex.umbach.dev/Alex/roese-utils/rslogger"
)
func GetNotificationIconByType(notificationType uint8) string { func GetNotificationIconByType(notificationType uint8) string {
switch notificationType { switch notificationType {
@ -13,16 +18,52 @@ func GetNotificationIconByType(notificationType uint8) string {
case 4: case 4:
return NotificationSymbolError return NotificationSymbolError
default: default:
return "X" logger.AddSystemLog(rslogger.LogTypeError, "Unknown notification type: %v", notificationType)
return ""
} }
} }
func GetUserIds(list []structs.VerifiedUser) []string { func GetFormattedFilters(filter string) string {
var userIds []string filterValues := strings.Split(filter, ",")
var formattedFilters []string
for _, v := range list { for _, v := range filterValues {
userIds = append(userIds, v.UserId) switch v {
case NotificationTypeSuccess:
formattedFilters = append(formattedFilters, NotificationTypeSuccessString)
case NotificationTypeInfo:
formattedFilters = append(formattedFilters, NotificationTypeInfoString)
case NotificationTypeWarning:
formattedFilters = append(formattedFilters, NotificationTypeWarningString)
case NotificationTypeError:
formattedFilters = append(formattedFilters, NotificationTypeErrorString)
}
} }
return userIds return strings.Join(formattedFilters, ", ")
}
func IsNotificationTypeInFilter(filter []string, notificationType uint8) bool {
for _, v := range filter {
switch v {
case NotificationTypeSuccess:
if notificationType == 1 {
return true
}
case NotificationTypeInfo:
if notificationType == 2 {
return true
}
case NotificationTypeWarning:
if notificationType == 3 {
return true
}
case NotificationTypeError:
if notificationType == 4 {
return true
}
}
}
return false
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

@ -6,6 +6,7 @@ import (
"jannex/telegram-bot-manager/modules/structs" "jannex/telegram-bot-manager/modules/structs"
"jannex/telegram-bot-manager/modules/telegram" "jannex/telegram-bot-manager/modules/telegram"
"jannex/telegram-bot-manager/modules/utils" "jannex/telegram-bot-manager/modules/utils"
"strings"
"git.ex.umbach.dev/Alex/roese-utils/rslogger" "git.ex.umbach.dev/Alex/roese-utils/rslogger"
"git.ex.umbach.dev/Alex/roese-utils/rsutils" "git.ex.umbach.dev/Alex/roese-utils/rsutils"
@ -46,12 +47,26 @@ func SendNotification(c *fiber.Ctx) error {
formattedMessage := utils.GetNotificationIconByType(body.Type) + " " + body.Title formattedMessage := utils.GetNotificationIconByType(body.Type) + " " + body.Title
var notifiedUsers []string
// send message to all verified users // send message to all verified users
for _, user := range foundVerifiedUsers { for _, user := range foundVerifiedUsers {
telegram.SendNotification(int64(user.ChatId), formattedMessage) if user.Filter == "" {
continue
} }
logger.AddSystemLog(rslogger.LogTypeInfo, "Sent notification: %s to %d users: %v", formattedMessage, len(foundVerifiedUsers), utils.GetUserIds(foundVerifiedUsers)) filter := strings.Split(user.Filter, ",")
if !utils.IsNotificationTypeInFilter(filter, body.Type) {
continue
}
telegram.SendNotification(int64(user.ChatId), formattedMessage)
notifiedUsers = append(notifiedUsers, user.UserId)
}
logger.AddSystemLog(rslogger.LogTypeInfo, "Sent notification: %s to %d users: %v", formattedMessage, len(notifiedUsers), notifiedUsers)
return c.SendStatus(fiber.StatusOK) return c.SendStatus(fiber.StatusOK)
} }

View File

@ -6,7 +6,6 @@ import (
"git.ex.umbach.dev/Alex/roese-utils/rsutils" "git.ex.umbach.dev/Alex/roese-utils/rsutils"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/rs/zerolog/log"
) )
func UserVerified(c *fiber.Ctx) error { func UserVerified(c *fiber.Ctx) error {
@ -42,7 +41,5 @@ func UserVerified(c *fiber.Ctx) error {
// get verified user by userId // get verified user by userId
database.DB.Where("user_id = ?", params.UserId).First(&foundVerifiedUser) database.DB.Where("user_id = ?", params.UserId).First(&foundVerifiedUser)
log.Info().Msgf("Found verified user: %v", foundVerifiedUser)
return c.JSON(structs.StatusResponse{Status: foundVerifiedUser.UserId != ""}) return c.JSON(structs.StatusResponse{Status: foundVerifiedUser.UserId != ""})
} }