diff --git a/handlers/admin.go b/handlers/admin.go
index 42bf378..d25d57e 100644
--- a/handlers/admin.go
+++ b/handlers/admin.go
@@ -19,12 +19,10 @@ func (bot *Bot) HandleAdminCommands(update *api.Update) {
}
_, e := utils.SendMessage(bot.API, bot.API.Self.ID, 0, update.Message.CommandArguments())
- if e != nil {
- if strings.HasPrefix(e.Error(), "Bad Request:") {
- utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
- fmt.Sprintf("Unable to set entry message: %s", e))
- return
- }
+ if e != nil && strings.HasPrefix(e.Error(), "Bad Request:") {
+ utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
+ fmt.Sprintf("Unable to set entry message: %s", e))
+ return
}
bot.Config.EntryMessage = update.Message.CommandArguments()
@@ -57,23 +55,19 @@ func (bot *Bot) HandleAdminCommands(update *api.Update) {
update.Message.Chat.ID, topicID))
case "togglesendapproval":
- if bot.Config.ApprovalMessage != "" {
- switch bot.Config.SendApprovalMessage {
- case true:
- bot.Config.SendApprovalMessage = false
- case false:
- bot.Config.SendApprovalMessage = true
- }
- if err := bot.Config.SaveConfig(); err != nil {
- log.Printf("Failed to save config: %v", err)
- }
- utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
- fmt.Sprintf("Send approval message: %v", bot.Config.SendApprovalMessage))
- } else {
+ if bot.Config.ApprovalMessage == "" {
utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
"Please set an approval message with /setapprovalmessage")
+ return
}
+ bot.Config.SendApprovalMessage = !bot.Config.SendApprovalMessage
+ if err := bot.Config.SaveConfig(); err != nil {
+ log.Printf("Failed to save config: %v", err)
+ }
+ utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
+ fmt.Sprintf("Send approval message: %v", bot.Config.SendApprovalMessage))
+
case "setapprovalmessage":
if update.Message.CommandArguments() == "" {
utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
@@ -93,12 +87,14 @@ func (bot *Bot) HandleAdminCommands(update *api.Update) {
if *bot.Config.TargetChatId != 0 {
targetChatID = fmt.Sprintf("%d", *bot.Config.TargetChatId)
}
- infoMsg := fmt.Sprintf("%s\n%s\n%s\n%s\n%s",
- fmt.Sprintf("Admin Chat ID: %d", update.Message.Chat.ID),
- fmt.Sprintf("Admin Topic ID: %d", *bot.Config.AdminChatTopicId),
- fmt.Sprintf("Target Chat ID: %s", targetChatID),
- fmt.Sprintf("Entry Message: %s", bot.Config.EntryMessage),
- fmt.Sprintf("Approval Message: %s", bot.Config.ApprovalMessage))
- utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID, infoMsg)
+ utils.SendMessage(bot.API, update.Message.Chat.ID, update.Message.MessageThreadID,
+ fmt.Sprintf(
+ "Admin Chat ID: %d\nAdmin Topic ID: %d\nTarget Chat ID: %s\nEntry Message: %s\nApproval Message: %s",
+ update.Message.Chat.ID,
+ *bot.Config.AdminChatTopicId,
+ targetChatID,
+ bot.Config.EntryMessage,
+ bot.Config.ApprovalMessage,
+ ))
}
}
diff --git a/handlers/callbacks.go b/handlers/callbacks.go
index 3327b50..b7e2d8b 100644
--- a/handlers/callbacks.go
+++ b/handlers/callbacks.go
@@ -12,37 +12,21 @@ import (
// HandleCallbackQuery processes inline button callbacks (approve/decline/leave).
func (bot *Bot) HandleCallbackQuery(query *api.CallbackQuery) {
- data := strings.Join(strings.Split(query.Data, "_"), " ")
- var action string
- var args int64
- _, err := fmt.Sscanf(data, "%s %d", &action, &args)
+ action, args, err := parseCallbackData(query.Data)
if err != nil {
log.Printf("Failed to parse callback data: %v", err)
return
}
if action == "leave" {
- utils.LeaveChatRequest(bot.API, []int64{args})
- utils.EditMessage(bot.API, query.Message.Chat.ID, query.Message.MessageID,
- fmt.Sprintf("We have left chat %d", args))
- callback := api.NewCallback(query.ID, "")
- bot.API.Request(callback)
+ bot.handleLeaveAction(query, args)
return
}
user := bot.GetPendingUser(args)
if user == nil {
log.Printf("No pending request for user ID %d", args)
- msg := api.NewMessage(query.Message.Chat.ID, "Unable to find user, bot may have restarted")
- msg.ReplyParameters = api.ReplyParameters{MessageID: query.Message.MessageID, ChatID: query.Message.Chat.ID}
- r, _ := bot.API.Send(msg)
-
- edit := api.NewEditMessageText(query.Message.Chat.ID, r.ReplyToMessage.MessageID, r.ReplyToMessage.Text)
- edit.Entities = r.ReplyToMessage.Entities
- bot.API.Send(edit)
-
- callback := api.NewCallback(query.ID, "")
- bot.API.Request(callback)
+ bot.handleMissingUser(query)
return
}
@@ -56,98 +40,83 @@ func (bot *Bot) HandleCallbackQuery(query *api.CallbackQuery) {
bot.handleDeclineRequest(query, user, userString, adminUserString)
}
- if bot.Config.DeleteRequestAfterDecision {
- deleteTimer := time.NewTimer(10 * time.Second)
- go func() {
- defer deleteTimer.Stop()
- <-deleteTimer.C
- del := api.NewDeleteMessage(query.Message.Chat.ID, query.Message.MessageID)
- bot.API.Send(del)
- }()
- }
-
bot.DeletePendingUser(args)
+
+ if bot.Config.DeleteRequestAfterDecision {
+ go bot.scheduleMessageDeletion(query.Message.Chat.ID, query.Message.MessageID, 10*time.Second)
+ }
}
-// handleApproveRequest approves a join request and sends approval callback.
+// handleApproveRequest approves a join request and sends an approval callback.
func (bot *Bot) handleApproveRequest(query *api.CallbackQuery, user *ExtendedChatJoinRequest, userString, adminUserString string) {
r := api.ApproveChatJoinRequestConfig{
- ChatConfig: api.ChatConfig{
- ChatID: user.ChatJoinRequest.Chat.ID,
- },
- UserID: user.ChatJoinRequest.From.ID,
+ ChatConfig: api.ChatConfig{ChatID: user.ChatJoinRequest.Chat.ID},
+ UserID: user.ChatJoinRequest.From.ID,
}
- _, e := bot.API.Request(r)
- if e != nil {
- log.Println(e.Error())
- edit := api.NewEditMessageText(query.Message.Chat.ID, query.Message.MessageID, query.Message.Text)
- edit.Entities = query.Message.Entities
- bot.API.Send(edit)
+
+ if _, err := bot.API.Request(r); err != nil {
+ log.Println(err)
+ bot.restoreMessage(query)
return
}
utils.EditMessage(bot.API, query.Message.Chat.ID, query.Message.MessageID,
fmt.Sprintf(AdminApprovedMsg,
userString, user.From.ID, user.JoinReason, adminUserString,
- time.Now().Format("2006-01-02 15:04:05")))
+ time.Now().Format("2006-01-02 15:04:05"),
+ ),
+ )
if bot.Config.SendApprovalMessage {
utils.SendMessage(bot.API, user.From.ID, 0, bot.Config.ApprovalMessage)
}
- callback := api.NewCallback(query.ID, "Join request approved.")
- bot.API.Request(callback)
+ bot.API.Request(api.NewCallback(query.ID, "Join request approved."))
}
-// handleDeclineRequest declines a join request and sends decline callback.
+// handleDeclineRequest declines a join request and sends a decline callback.
func (bot *Bot) handleDeclineRequest(query *api.CallbackQuery, user *ExtendedChatJoinRequest, userString, adminUserString string) {
r := api.DeclineChatJoinRequest{
- ChatConfig: api.ChatConfig{
- ChatID: user.ChatJoinRequest.Chat.ID,
- },
- UserID: user.ChatJoinRequest.From.ID,
+ ChatConfig: api.ChatConfig{ChatID: user.ChatJoinRequest.Chat.ID},
+ UserID: user.ChatJoinRequest.From.ID,
}
- _, e := bot.API.Request(r)
- if e != nil {
- log.Println(e.Error())
- edit := api.NewEditMessageText(query.Message.Chat.ID, query.Message.MessageID, query.Message.Text)
- edit.Entities = query.Message.Entities
- bot.API.Send(edit)
+
+ if _, err := bot.API.Request(r); err != nil {
+ log.Println(err)
+ bot.restoreMessage(query)
return
}
utils.EditMessage(bot.API, query.Message.Chat.ID, query.Message.MessageID,
- fmt.Sprintf(AdminDeclinedMsg, userString, user.From.ID, user.JoinReason, adminUserString,
+ fmt.Sprintf(AdminDeclinedMsg,
+ userString, user.From.ID, user.JoinReason, adminUserString,
time.Now().Format("2006-01-02 15:04:05"),
- "(no reason provided, reply to this to set one, prepend with + to also send to user)"),
+ defaultReason,
+ ),
)
- callback := api.NewCallback(query.ID, "Join request declined.")
- bot.API.Request(callback)
+ bot.API.Request(api.NewCallback(query.ID, "Join request declined."))
}
// HandleDeclineReason allows admins to provide a decline reason by replying to decline messages.
func (bot *Bot) HandleDeclineReason(update *api.Update) {
repliedMsg := update.Message.ReplyToMessage
- if !strings.Contains(repliedMsg.Text,
- "(no reason provided, reply to this to set one, prepend with + to also send to user)") {
+ if !strings.Contains(repliedMsg.Text, defaultReason) {
return
}
lines := strings.Split(repliedMsg.Text, "\n")
userString := utils.BuildUserString(update.Message.From)
-
if strings.TrimPrefix(lines[3], "Declined by: ") != userString {
return
}
- reason := utils.EscapeHTML(update.Message.Text)
userID, username, joinReason, declinedBy, declinedAt := utils.GetInfoFromMsg(repliedMsg.Text)
- entities, _ := utils.FilterEntitiesByTypeWithContext(repliedMsg, "italic")
- if len(entities) >= 1 {
+ if entities, _ := utils.FilterEntitiesByTypeWithContext(repliedMsg, "italic"); len(entities) >= 1 {
username = fmt.Sprintf("%s", entities[0].Text)
}
+ reason := utils.EscapeHTML(update.Message.Text)
if strings.HasPrefix(update.Message.Text, "+") {
reason = utils.EscapeHTML(update.Message.Text[1:])
utils.SendMessage(bot.API, userID, 0,
@@ -157,3 +126,49 @@ func (bot *Bot) HandleDeclineReason(update *api.Update) {
utils.EditMessage(bot.API, update.Message.Chat.ID, repliedMsg.MessageID,
fmt.Sprintf(AdminDeclinedMsg, username, userID, joinReason, declinedBy, declinedAt, reason))
}
+
+// parseCallbackData parses the action and user ID from a callback query's data string.
+func parseCallbackData(data string) (action string, userID int64, err error) {
+ normalized := strings.Join(strings.Split(data, "_"), " ")
+ _, err = fmt.Sscanf(normalized, "%s %d", &action, &userID)
+ return
+}
+
+// handleLeaveAction handles the "leave" callback by leaving the specified chat.
+func (bot *Bot) handleLeaveAction(query *api.CallbackQuery, chatID int64) {
+ utils.LeaveChatRequest(bot.API, []int64{chatID})
+ utils.EditMessage(bot.API, query.Message.Chat.ID, query.Message.MessageID,
+ fmt.Sprintf("We have left chat %d", chatID))
+ bot.API.Request(api.NewCallback(query.ID, ""))
+}
+
+// handleMissingUser notifies the admin that the user's pending request could not be found.
+func (bot *Bot) handleMissingUser(query *api.CallbackQuery) {
+ msg := api.NewMessage(query.Message.Chat.ID, "Unable to find user, bot may have restarted")
+ msg.ReplyParameters = api.ReplyParameters{
+ MessageID: query.Message.MessageID,
+ ChatID: query.Message.Chat.ID,
+ }
+ r, _ := bot.API.Send(msg)
+
+ edit := api.NewEditMessageText(query.Message.Chat.ID, r.ReplyToMessage.MessageID, r.ReplyToMessage.Text)
+ edit.Entities = r.ReplyToMessage.Entities
+ bot.API.Send(edit)
+
+ bot.API.Request(api.NewCallback(query.ID, ""))
+}
+
+// restoreMessage restores a message to its original state after a failed API request.
+func (bot *Bot) restoreMessage(query *api.CallbackQuery) {
+ edit := api.NewEditMessageText(query.Message.Chat.ID, query.Message.MessageID, query.Message.Text)
+ edit.Entities = query.Message.Entities
+ bot.API.Send(edit)
+}
+
+// scheduleMessageDeletion deletes a message after a given delay.
+func (bot *Bot) scheduleMessageDeletion(chatID int64, messageID int, delay time.Duration) {
+ timer := time.NewTimer(delay)
+ defer timer.Stop()
+ <-timer.C
+ bot.API.Send(api.NewDeleteMessage(chatID, messageID))
+}
diff --git a/handlers/handlers.go b/handlers/handlers.go
index 661a9f2..ef704a6 100644
--- a/handlers/handlers.go
+++ b/handlers/handlers.go
@@ -12,6 +12,7 @@ const (
AdminApprovedMsg = "✅ Join #request approved for %s [%d]\n\nJoin reason: %s\nApproved by: %s\nApproved at: %s"
AdminDeclinedMsg = "❌ Join #request declined for %s [%d]\n\nJoin reason: %s\nDeclined by: %s\nDeclined at: %s\nDeclined reason: %s"
AdminFailedMsg = "⚠️ Join #request failed for %s [%d]\n\nJoin reason: %s\nFailure reason: %s"
+ defaultReason = "(no reason provided, reply to this to set one, prepend with + to also send to user)"
)
// Types shared by handler files
@@ -32,20 +33,13 @@ type Bot struct {
func (bot *Bot) GetPendingUser(userID int64) *ExtendedChatJoinRequest {
bot.mu.RLock()
defer bot.mu.RUnlock()
- user := bot.WaitingForApproval[userID]
- if user == nil {
- return nil
- }
- return user
+ return bot.WaitingForApproval[userID]
}
// SetPendingUser stores a pending user request (write-safe).
func (bot *Bot) SetPendingUser(userID int64, user *ExtendedChatJoinRequest) {
bot.mu.Lock()
defer bot.mu.Unlock()
- if _, ok := bot.WaitingForApproval[userID]; !ok {
- bot.WaitingForApproval = make(map[int64]*ExtendedChatJoinRequest)
- }
bot.WaitingForApproval[userID] = user
}
diff --git a/handlers/join.go b/handlers/join.go
index a67baa4..fc84837 100644
--- a/handlers/join.go
+++ b/handlers/join.go
@@ -10,35 +10,23 @@ import (
// HandleJoinRequestResponse records the user's join reason and notifies admins.
func (bot *Bot) HandleJoinRequestResponse(user *ExtendedChatJoinRequest, update *api.Message) {
- if user.JoinReason == "" {
- user.JoinReason = utils.EscapeHTML(update.Text)
- userString := utils.BuildUserString(&user.From)
-
- keyboard := utils.NewApprovalKeyboard(user.From.ID)
- utils.EditMessageWithKeyboard(bot.API, *bot.Config.AdminChatId, user.JoinRequestMessageID,
- fmt.Sprintf(AdminJoinRequestMsg,
- userString, user.From.ID, user.JoinReason), &keyboard)
-
- utils.SendMessage(bot.API, update.From.ID, 0, "Thank you! Your request has been sent to the admins for review.")
- } else {
+ if user.JoinReason != "" {
utils.SendMessage(bot.API, update.From.ID, 0, "Your request is already pending approval.")
- }
-}
-
-// HandleJoinRequest initiates join approval flow by sending entry message and admin notification.
-func (bot *Bot) HandleJoinRequest(request *api.ChatJoinRequest) {
- // if chat is not in config, ignore
- if *bot.Config.TargetChatId != request.Chat.ID {
- m := api.NewMessage(*bot.Config.AdminChatId,
- fmt.Sprintf("Received join request for chat %s (%d), but it's not in config, ignoring",
- request.Chat.Title, request.Chat.ID))
- leaveBtn := api.NewInlineKeyboardButtonData("Leave Chat", fmt.Sprintf("leave_%d", request.Chat.ID))
- m.ReplyMarkup = api.NewInlineKeyboardMarkup([]api.InlineKeyboardButton{leaveBtn})
- m.ParseMode = api.ModeHTML
- bot.API.Send(m)
return
}
+ user.JoinReason = utils.EscapeHTML(update.Text)
+ userString := utils.BuildUserString(&user.From)
+
+ keyboard := utils.NewApprovalKeyboard(user.From.ID)
+ utils.EditMessageWithKeyboard(bot.API, *bot.Config.AdminChatId, user.JoinRequestMessageID,
+ fmt.Sprintf(AdminJoinRequestMsg, userString, user.From.ID, user.JoinReason), &keyboard)
+
+ utils.SendMessage(bot.API, update.From.ID, 0, "Thank you! Your request has been sent to the admins for review.")
+}
+
+// HandleJoinRequest initiates the join approval flow by sending the entry message and admin notification.
+func (bot *Bot) HandleJoinRequest(request *api.ChatJoinRequest) {
utils.SendMessage(bot.API, request.From.ID, 0, bot.Config.EntryMessage)
userString := utils.BuildUserString(&request.From)
@@ -49,6 +37,7 @@ func (bot *Bot) HandleJoinRequest(request *api.ChatJoinRequest) {
if topic := *bot.Config.AdminChatTopicId; topic != 0 {
m.MessageThreadID = topic
}
+
r, err := bot.API.Send(m)
if err != nil {
log.Printf("Failed to send join request to admin chat: %v", err)
@@ -66,7 +55,5 @@ func (bot *Bot) HandleJoinRequest(request *api.ChatJoinRequest) {
func (bot *Bot) SendFailureMessage(user *ExtendedChatJoinRequest, query *api.CallbackQuery, userString string) {
utils.EditMessage(bot.API, *bot.Config.AdminChatId, user.JoinRequestMessageID,
fmt.Sprintf(AdminFailedMsg, userString, user.From.ID, utils.EscapeHTML(user.JoinReason), "User not found in requests."))
-
- callback := api.NewCallback(query.ID, "Join request failed.")
- bot.API.Request(callback)
+ bot.API.Request(api.NewCallback(query.ID, "Join request failed."))
}
diff --git a/main.go b/main.go
index 5246861..cbed5cf 100644
--- a/main.go
+++ b/main.go
@@ -9,58 +9,63 @@ import (
)
func main() {
- b := &handlers.Bot{}
- b.Config = config.Config{}
- err := b.Config.LoadConfig()
- if err != nil {
- log.Fatal(err.Error())
+ cfg := config.Config{}
+ if err := cfg.LoadConfig(); err != nil {
+ log.Fatal(err)
}
- if b.Config.BotToken == nil {
+ if cfg.BotToken == nil {
log.Fatal("Edit config.yaml and fill out bot token")
}
- bot, err := api.NewBotAPI(*b.Config.BotToken)
+
+ bot, err := api.NewBotAPI(*cfg.BotToken)
if err != nil {
- panic(err)
+ log.Fatal(err)
}
- b.API = bot
- b.WaitingForApproval = make(map[int64]*handlers.ExtendedChatJoinRequest)
+ b := &handlers.Bot{
+ API: bot,
+ Config: cfg,
+ WaitingForApproval: make(map[int64]*handlers.ExtendedChatJoinRequest),
+ }
log.Printf("Authorized on account %s", bot.Self.UserName)
updateConfig := api.NewUpdate(0)
updateConfig.Timeout = 60
- updatesChannel := b.API.GetUpdatesChan(updateConfig)
- for update := range updatesChannel {
- if update.ChatJoinRequest != nil {
- if update.ChatJoinRequest.Chat.ID == *b.Config.TargetChatId {
- b.HandleJoinRequest(update.ChatJoinRequest)
- }
- continue
- }
-
- if update.CallbackQuery != nil {
- b.HandleCallbackQuery(update.CallbackQuery)
- continue
- }
-
- if update.Message == nil {
- continue
- }
-
- if user, ok := b.WaitingForApproval[update.Message.From.ID]; ok {
- if update.Message.Chat.ID == update.Message.From.ID {
- b.HandleJoinRequestResponse(user, update.Message)
- }
- }
-
- if update.Message.Chat.ID == *b.Config.AdminChatId {
- if update.Message.ReplyToMessage != nil {
- b.HandleDeclineReason(&update)
- }
- b.HandleAdminCommands(&update)
- }
+ for update := range b.API.GetUpdatesChan(updateConfig) {
+ processUpdate(b, update)
+ }
+}
+
+func processUpdate(b *handlers.Bot, update api.Update) {
+ if update.ChatJoinRequest != nil {
+ if update.ChatJoinRequest.Chat.ID == *b.Config.TargetChatId {
+ b.HandleJoinRequest(update.ChatJoinRequest)
+ }
+ return
+ }
+
+ if update.CallbackQuery != nil {
+ b.HandleCallbackQuery(update.CallbackQuery)
+ return
+ }
+
+ if update.Message == nil || update.Message.From == nil {
+ return
+ }
+
+ if user := b.GetPendingUser(update.Message.From.ID); user != nil {
+ if update.Message.Chat.ID == update.Message.From.ID {
+ b.HandleJoinRequestResponse(user, update.Message)
+ }
+ }
+
+ if update.Message.Chat.ID == *b.Config.AdminChatId {
+ if update.Message.ReplyToMessage != nil {
+ b.HandleDeclineReason(&update)
+ }
+ b.HandleAdminCommands(&update)
}
}
diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go
index 0c646b3..5ec3057 100644
--- a/pkg/utils/utils.go
+++ b/pkg/utils/utils.go
@@ -10,27 +10,28 @@ import (
)
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...)
+ replacer := strings.NewReplacer(
+ "\\", "\\\\",
+ "*", "\\*",
+ "_", "\\_",
+ "`", "\\`",
+ "[", "\\[",
+ "]", "\\]",
+ "(", "\\(",
+ ")", "\\)",
+ "#", "\\#",
+ "-", "\\-",
+ )
return replacer.Replace(s)
}
func EscapeHTML(s string) string {
- toEscape := []string{"&", "<", ">", "\"", "'"}
-
- replacements := make([]string, 0, len(toEscape)*2)
- replacements = append(replacements, "&", "&")
- replacements = append(replacements, "<", "<")
- replacements = append(replacements, ">", ">")
- replacements = append(replacements, "\"", """)
-
- replacer := strings.NewReplacer(replacements...)
+ replacer := strings.NewReplacer(
+ "&", "&",
+ "<", "<",
+ ">", ">",
+ "\"", """,
+ )
return replacer.Replace(s)
}
@@ -109,7 +110,7 @@ func BuildUserString(user *api.User) string {
return name.String()
}
-func SendMessage(botAPI *api.BotAPI, chatID int64, topicID int, text string) (resp api.Message, err error) {
+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 {
@@ -118,22 +119,20 @@ func SendMessage(botAPI *api.BotAPI, chatID int64, topicID int, text string) (re
return botAPI.Send(msg)
}
-func EditMessage(botAPI *api.BotAPI, chatID int64, messageID int, text string) (resp api.Message, err error) {
+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 {
- var err error
for _, chatID := range chatIDs {
- leaveChatConfig := api.LeaveChatConfig{ChatConfig: api.ChatConfig{ChatID: chatID}}
- _, err = botAPI.Request(leaveChatConfig)
+ _, err := botAPI.Request(api.LeaveChatConfig{ChatConfig: api.ChatConfig{ChatID: chatID}})
if err != nil {
return err
}
}
- return err
+ return nil
}
func EditMessageWithKeyboard(botAPI *api.BotAPI, chatID int64, messageID int, text string, keyboard *api.InlineKeyboardMarkup) {
@@ -145,8 +144,7 @@ func EditMessageWithKeyboard(botAPI *api.BotAPI, chatID int64, messageID int, te
botAPI.Send(edit)
}
-// ParseIntArg parses a string argument as int, returns (value, error message).
-// Error message is empty on success.
+// 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 {
@@ -155,8 +153,7 @@ func ParseIntArg(arg string) (int, string) {
return val, ""
}
-// ParseInt64Arg parses a string argument as int64, returns (value, error message).
-// Error message is empty on success.
+// 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 {