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

159
handlers/callbacks.go Normal file
View file

@ -0,0 +1,159 @@
package handlers
import (
"fmt"
"log"
"strings"
"time"
utils "git.zio.sh/astra/telegram-approval-join/pkg/utils"
api "github.com/OvyFlash/telegram-bot-api"
)
// 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)
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 <i>%d</i>", args))
callback := api.NewCallback(query.ID, "")
bot.API.Request(callback)
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)
return
}
userString := utils.BuildUserString(&user.From)
adminUserString := utils.BuildUserString(query.From)
switch action {
case "approve":
bot.handleApproveRequest(query, user, userString, adminUserString)
case "decline":
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)
}
// handleApproveRequest approves a join request and sends 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,
}
_, 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)
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")))
if bot.Config.ApprovalMessage != "" {
utils.SendMessage(bot.API, user.From.ID, 0, bot.Config.ApprovalMessage)
}
callback := api.NewCallback(query.ID, "Join request approved.")
bot.API.Request(callback)
}
// handleDeclineRequest declines a join request and sends 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,
}
_, 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)
return
}
utils.EditMessage(bot.API, query.Message.Chat.ID, query.Message.MessageID,
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)"),
)
callback := api.NewCallback(query.ID, "Join request declined.")
bot.API.Request(callback)
}
// 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)") {
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 {
username = fmt.Sprintf("<i>%s</i>", entities[0].Text)
}
if strings.HasPrefix(update.Message.Text, "+") {
reason = utils.EscapeHTML(update.Message.Text[1:])
utils.SendMessage(bot.API, userID, 0,
fmt.Sprintf("Your join request was declined for the following reason:\n\n%s", reason))
}
utils.EditMessage(bot.API, update.Message.Chat.ID, repliedMsg.MessageID,
fmt.Sprintf(AdminDeclinedMsg, username, userID, joinReason, declinedBy, declinedAt, reason))
}