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( "&", "&", "<", "<", ">", ">", "\"", """, ) 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("") if user.FirstName != "" { fmt.Fprint(&name, EscapeHTML(user.FirstName)) } if user.LastName != "" { fmt.Fprintf(&name, " %s", EscapeHTML(user.LastName)) } name.WriteString("") 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, "" }