Code refactor

This commit is contained in:
Astra 2026-02-16 16:49:20 +00:00
parent 5e37545782
commit d2f7297d92
7 changed files with 534 additions and 330 deletions

166
pkg/utils/utils.go Normal file
View file

@ -0,0 +1,166 @@
package utils
import (
"fmt"
"strconv"
"strings"
"unicode/utf16"
api "github.com/OvyFlash/telegram-bot-api"
)
func EscapeMarkdown(s string) string {
toEscape := []string{"*", "_", "`", "[", "]", "(", ")", "\\", "#", "-"}
replacements := make([]string, 0, len(toEscape)*2)
for _, char := range toEscape {
replacements = append(replacements, char, "\\"+char)
}
replacer := strings.NewReplacer(replacements...)
return replacer.Replace(s)
}
func EscapeHTML(s string) string {
toEscape := []string{"&", "<", ">", "\"", "'"}
replacements := make([]string, 0, len(toEscape)*2)
replacements = append(replacements, "&", "&amp;")
replacements = append(replacements, "<", "&lt;")
replacements = append(replacements, ">", "&gt;")
replacements = append(replacements, "\"", "&quot;")
replacer := strings.NewReplacer(replacements...)
return replacer.Replace(s)
}
func NewApprovalKeyboard(userID int64) api.InlineKeyboardMarkup {
approveBtn := api.NewInlineKeyboardButtonData("Approve", fmt.Sprintf("approve_%d", userID))
declineBtn := api.NewInlineKeyboardButtonData("Decline", fmt.Sprintf("decline_%d", userID))
return api.NewInlineKeyboardMarkup([]api.InlineKeyboardButton{approveBtn, declineBtn})
}
func GetInfoFromMsg(msg string) (userId int64, username, joinReason, declinedBy, declinedAt string) {
lines := strings.Split(msg, "\n")
joinReason = string([]rune(lines[2])[len([]rune("Join reason: ")):])
declinedBy = string([]rune(lines[3])[len([]rune("Declined by: ")):])
declinedAt = string([]rune(lines[4])[len([]rune("Declined at: ")):])
index := LastIndexRuneInRunes([]rune(lines[0]), '[')
userID, _ := strconv.Atoi(string([]rune(lines[0])[index+1 : len([]rune(lines[0]))-1]))
return int64(userID), EscapeHTML(username), EscapeHTML(joinReason), declinedBy, declinedAt
}
func LastIndexRuneInRunes(runes []rune, r rune) int {
for i := len(runes) - 1; i >= 0; i-- {
if runes[i] == r {
return i
}
}
return -1
}
type EntityWithText struct {
Type string `json:"type"`
Offset int `json:"offset"`
Length int `json:"length"`
Text string `json:"text"`
}
func FilterEntitiesByTypeWithContext(payload *api.Message, entityType string) ([]EntityWithText, error) {
textRunes := utf16.Encode([]rune(payload.Text))
var filtered []EntityWithText
for _, entity := range payload.Entities {
if entity.Type == entityType {
endOffset := entity.Offset + entity.Length
entityText := ""
if entity.Offset < len(textRunes) {
entityText = string(utf16.Decode(textRunes[entity.Offset:endOffset]))
}
filtered = append(filtered, EntityWithText{
Type: entity.Type,
Offset: entity.Offset,
Length: entity.Length,
Text: entityText,
})
}
}
return filtered, nil
}
func BuildUserString(user *api.User) string {
if user.UserName != "" {
return "@" + user.UserName
}
var name strings.Builder
name.WriteString("<i>")
if user.FirstName != "" {
fmt.Fprint(&name, EscapeHTML(user.FirstName))
}
if user.LastName != "" {
fmt.Fprintf(&name, " %s", EscapeHTML(user.LastName))
}
name.WriteString("</i>")
return name.String()
}
func SendMessage(botAPI *api.BotAPI, chatID int64, topicID int, text string) (resp api.Message, err error) {
msg := api.NewMessage(chatID, text)
msg.ParseMode = api.ModeHTML
if topicID != 0 {
msg.MessageThreadID = topicID
}
return botAPI.Send(msg)
}
func EditMessage(botAPI *api.BotAPI, chatID int64, messageID int, text string) (resp api.Message, err error) {
edit := api.NewEditMessageText(chatID, messageID, text)
edit.ParseMode = api.ModeHTML
return botAPI.Send(edit)
}
func LeaveChatRequest(botAPI *api.BotAPI, chatIDs []int64) error {
var err error
for _, chatID := range chatIDs {
leaveChatConfig := api.LeaveChatConfig{ChatConfig: api.ChatConfig{ChatID: chatID}}
_, err = botAPI.Request(leaveChatConfig)
if err != nil {
return err
}
}
return err
}
func EditMessageWithKeyboard(botAPI *api.BotAPI, chatID int64, messageID int, text string, keyboard *api.InlineKeyboardMarkup) {
edit := api.NewEditMessageText(chatID, messageID, text)
edit.ParseMode = api.ModeHTML
if keyboard != nil {
edit.ReplyMarkup = keyboard
}
botAPI.Send(edit)
}
// ParseIntArg parses a string argument as int, returns (value, error message).
// Error message is empty on success.
func ParseIntArg(arg string) (int, string) {
val, err := strconv.Atoi(arg)
if err != nil {
return 0, "Invalid value"
}
return val, ""
}
// ParseInt64Arg parses a string argument as int64, returns (value, error message).
// Error message is empty on success.
func ParseInt64Arg(arg string) (int64, string) {
val, err := strconv.ParseInt(arg, 10, 64)
if err != nil {
return 0, "Invalid value"
}
return val, ""
}