telegram-join-approval-nuzzles/pkg/utils/utils.go
2026-02-17 20:17:58 +00:00

167 lines
4.3 KiB
Go

package utils
import (
"fmt"
"strconv"
"strings"
"unicode/utf16"
api "github.com/OvyFlash/telegram-bot-api"
)
func EscapeMarkdown(s string) string {
replacer := strings.NewReplacer(
"\\", "\\\\",
"*", "\\*",
"_", "\\_",
"`", "\\`",
"[", "\\[",
"]", "\\]",
"(", "\\(",
")", "\\)",
"#", "\\#",
"-", "\\-",
)
return replacer.Replace(s)
}
func EscapeHTML(s string) string {
replacer := strings.NewReplacer(
"&", "&",
"<", "&lt;",
">", "&gt;",
"\"", "&quot;",
)
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))
banBtn := api.NewInlineKeyboardButtonData("Ban", fmt.Sprintf("ban_%d", userID))
return api.NewInlineKeyboardMarkup(
[]api.InlineKeyboardButton{approveBtn, declineBtn},
[]api.InlineKeyboardButton{banBtn},
)
}
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) (api.Message, 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) (api.Message, error) {
edit := api.NewEditMessageText(chatID, messageID, text)
edit.ParseMode = api.ModeHTML
return botAPI.Send(edit)
}
func LeaveChatRequest(botAPI *api.BotAPI, chatIDs []int64) error {
for _, chatID := range chatIDs {
_, err := botAPI.Request(api.LeaveChatConfig{ChatConfig: api.ChatConfig{ChatID: chatID}})
if err != nil {
return err
}
}
return nil
}
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, errMsg); errMsg 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, errMsg); errMsg 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, ""
}