383 lines
10 KiB
Go
383 lines
10 KiB
Go
package command
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"slices"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"git.maximotejeda.com/maximo/cedulados-bot/internal/application/auth"
|
|
"git.maximotejeda.com/maximo/cedulados-bot/internal/ports"
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
|
)
|
|
|
|
var CommandPool *sync.Pool
|
|
|
|
type command struct {
|
|
bot *tgbotapi.BotAPI
|
|
update *tgbotapi.Update
|
|
msg *tgbotapi.MessageConfig
|
|
delMSG *tgbotapi.DeleteMessageConfig
|
|
log *slog.Logger
|
|
ce ports.CeduladosService
|
|
uSVC ports.UserService
|
|
}
|
|
|
|
// NewMessage
|
|
// Factory for query handler
|
|
func Newcommand(bot *tgbotapi.BotAPI, update *tgbotapi.Update, cSVC ports.CeduladosService, user ports.UserService) *command {
|
|
if CommandPool == nil {
|
|
CommandPool = &sync.Pool{
|
|
New: func() any { return &command{} },
|
|
}
|
|
for i := 0; i < 20; i++ {
|
|
CommandPool.Put(CommandPool.New())
|
|
}
|
|
}
|
|
log := slog.Default()
|
|
log = log.With("function", "command", "chat", update.Message.From.ID, "userid", update.Message.From.ID, "username", update.Message.From.UserName)
|
|
query := CommandPool.Get().(*command)
|
|
query.update = update
|
|
query.bot = bot
|
|
query.log = log
|
|
query.ce = cSVC
|
|
query.uSVC = user
|
|
return query
|
|
}
|
|
|
|
// Empty
|
|
// Returns pointer to pool
|
|
func (c *command) Empty() {
|
|
c.update = nil
|
|
c.msg = nil
|
|
c.log = nil
|
|
c.ce = nil
|
|
c.uSVC = nil
|
|
CommandPool.Put(c)
|
|
}
|
|
|
|
// Send
|
|
// Process message sending to bot
|
|
func (c *command) Send() {
|
|
defer c.Empty()
|
|
c.bot.Send(c.msg)
|
|
if c.delMSG != nil {
|
|
c.bot.Send(c.delMSG)
|
|
}
|
|
}
|
|
|
|
func (c *command) Handler(){
|
|
msg := tgbotapi.NewMessage(c.update.Message.From.ID, "")
|
|
delMSG := tgbotapi.NewDeleteMessage(c.update.Message.From.ID, c.update.Message.MessageID)
|
|
|
|
c.msg = &msg
|
|
c.delMSG = &delMSG
|
|
command := c.update.Message.Command()
|
|
|
|
switch strings.ToLower(command) {
|
|
case "baned":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
bannedUserCommand(c, msg)
|
|
case "appeal":
|
|
appealUserCommand(c, msg)
|
|
case "pending":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
pendingUserCommand(c, msg)
|
|
case "users":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
usersCommand(c, msg)
|
|
case "user":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
userCommand(c)
|
|
case "userid":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
userIDCommand(c)
|
|
case "ban":
|
|
if !checkUserIsAdmin(c){
|
|
return
|
|
}
|
|
banCommand(c, msg)
|
|
}
|
|
}
|
|
|
|
func GenerateAppealRequestMessage(up *tgbotapi.User, adm int64, bn string) *tgbotapi.MessageConfig {
|
|
txt := fmt.Sprintf(`User %s appeal
|
|
ID: %d
|
|
FirstName: %s
|
|
LastName: %s
|
|
ChatID: %d
|
|
`, up.UserName, up.ID, up.FirstName, up.LastName, up.ID)
|
|
msg := tgbotapi.NewMessage(adm, txt)
|
|
keyboard := tgbotapi.InlineKeyboardMarkup{}
|
|
row := tgbotapi.NewInlineKeyboardRow()
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("Unban", fmt.Sprintf("operation=unban&userID=%d&bot=%s", up.ID, bn)))
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("Delete", fmt.Sprintf("operation=delete&userID=%d&bot=%s", up.ID, bn)))
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("Ignore", fmt.Sprintf("operation=ignore&userID=%d&bot=%s", up.ID, bn)))
|
|
keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row)
|
|
msg.ReplyMarkup = keyboard
|
|
return &msg
|
|
}
|
|
|
|
func GenerateUserMessage(up *tgbotapi.User, adm int64, bn string) *tgbotapi.MessageConfig {
|
|
txt := fmt.Sprintf(`User %s
|
|
ID: %d
|
|
FirstName: %s
|
|
LastName: %s
|
|
ChatID: %d
|
|
`, up.UserName, up.ID, up.FirstName, up.LastName, up.ID)
|
|
msg := tgbotapi.NewMessage(adm, txt)
|
|
keyboard := tgbotapi.InlineKeyboardMarkup{}
|
|
row := tgbotapi.NewInlineKeyboardRow()
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("ban", fmt.Sprintf("operation=ban&userID=%d&bot=%s", up.ID, bn)))
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("Delete", fmt.Sprintf("operation=delete&userID=%d&bot=%s", up.ID, bn)))
|
|
row = append(row, tgbotapi.NewInlineKeyboardButtonData("Ignore", fmt.Sprintf("operation=ignore&userID=%d&bot=%s", up.ID, bn)))
|
|
keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row)
|
|
msg.ReplyMarkup = keyboard
|
|
return &msg
|
|
}
|
|
|
|
// checkUserIsAdmin
|
|
// if user is admin return true else false
|
|
func checkUserIsAdmin(c *command)bool{
|
|
if !auth.IsUserAdmin(c.update.Message.From.ID){
|
|
text := "only admin can execute this command"
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// bannedUserCommand
|
|
// check for user banned on the bot and send all for revision to admin requesting it
|
|
func bannedUserCommand(c *command, msg tgbotapi.MessageConfig){
|
|
buser, err := c.uSVC.GetAllBannedUsers(c.bot.Self.UserName)
|
|
if err != nil {
|
|
c.log.Error("error querying banned user")
|
|
}
|
|
if len(buser.Bans) <=0{
|
|
|
|
msg.Text = "users baned not found"
|
|
c.bot.Send(msg )
|
|
return
|
|
}
|
|
for _, u := range buser.GetBans(){
|
|
us, _ := c.uSVC.Get(u.TgbId)
|
|
tgbUs := tgbotapi.User{
|
|
ID: us.TguID,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
UserName: us.Username,
|
|
}
|
|
// send message to issuer
|
|
msg := GenerateAppealRequestMessage(&tgbUs, c.update.SentFrom().ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg )
|
|
}
|
|
}
|
|
|
|
// appealUserCommand
|
|
// user banned has the oportunity to appeal a command if is unjustify its banning
|
|
func appealUserCommand(c *command, msg tgbotapi.MessageConfig){
|
|
buser, err := c.uSVC.GetAllBannedUsers(c.bot.Self.UserName)
|
|
if err != nil {
|
|
c.log.Error("error querying banned user")
|
|
}
|
|
if len(buser.GetBans())<= 0{
|
|
msg.Text = "users baned not found"
|
|
c.bot.Send(msg )
|
|
return
|
|
}
|
|
for _, u := range buser.GetBans(){
|
|
adms, _:= auth.GetAdminFromEnv()
|
|
if u.TgbId == c.update.SentFrom().ID{
|
|
for _, adm := range adms{
|
|
// send message to all admins
|
|
msg := GenerateAppealRequestMessage(c.update.SentFrom(), adm, c.bot.Self.UserName)
|
|
c.bot.Send(msg )
|
|
|
|
}
|
|
|
|
c.bot.Send(msg)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// pendingUserCommand
|
|
// render pending access request for bot
|
|
func pendingUserCommand(c *command, msg tgbotapi.MessageConfig){
|
|
pac, _ := c.uSVC.GetAllAccessRequest(c.bot.Self.UserName)
|
|
if len(pac.Access) <= 0 {
|
|
msg.Text = "there are no users access request"
|
|
c.bot.Send(msg )
|
|
return
|
|
}
|
|
for _, ac := range pac.Access {
|
|
us, err := c.uSVC.Get(ac.TgbId)
|
|
if err != nil{
|
|
c.log.Error("geting user", "tgbID", us.TguID)
|
|
return
|
|
}
|
|
tgbUS := tgbotapi.User{
|
|
UserName: us.Username,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
ID: us.TguID,
|
|
}
|
|
msg := auth.GenerateAccessRequestMessage(&tgbUS, c.update.Message.From.ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg)
|
|
}
|
|
|
|
}
|
|
|
|
// usersCommand
|
|
// render all users on the bot to ban or delete
|
|
func usersCommand(c *command, msg tgbotapi.MessageConfig){
|
|
usL , err :=c.uSVC.GetAllBotsUsers(c.bot.Self.UserName)
|
|
if err != nil {
|
|
c.log.Error("geting users from bot")
|
|
return
|
|
}
|
|
if len(usL) <= 0 {
|
|
msg.Text = "users not found registered"
|
|
c.bot.Send(msg )
|
|
return
|
|
}
|
|
for _, us := range usL{
|
|
if auth.IsUserAdmin(us.TguID){
|
|
continue
|
|
}
|
|
tgbUS := tgbotapi.User{
|
|
UserName: us.Username,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
ID: us.TguID,
|
|
}
|
|
msg := GenerateUserMessage(&tgbUS, c.update.SentFrom().ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg)
|
|
}
|
|
|
|
}
|
|
|
|
// userCommand
|
|
// render an user message with querys ban delete
|
|
func userCommand(c *command){
|
|
msgTXT := strings.Split(c.update.Message.Text, " ")
|
|
if len(msgTXT) <= 1{
|
|
text := "command require username argument"
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
userName := msgTXT[1]
|
|
usL , err :=c.uSVC.GetAllBotsUsers(c.bot.Self.UserName)
|
|
if err != nil {
|
|
c.log.Error("geting users from bot")
|
|
return
|
|
}
|
|
for _, us := range usL{
|
|
if us.Username == userName{
|
|
tgbUS := tgbotapi.User{
|
|
UserName: us.Username,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
ID: us.TguID,
|
|
}
|
|
msg := GenerateUserMessage(&tgbUS, c.update.SentFrom().ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// userIDCommand
|
|
// Render a message with user info and querys ban delete
|
|
func userIDCommand(c *command){
|
|
msgTXT := strings.Split(c.update.Message.Text, " ")
|
|
if len(msgTXT) <= 1{
|
|
text := "command require username argument"
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
userIDSTR := msgTXT[1]
|
|
userID, err := strconv.ParseInt(userIDSTR, 10, 64)
|
|
if err != nil {
|
|
c.log.Error("geting users from bot", "error", err)
|
|
text := "wrong userID argument "+ err.Error()
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
us , err :=c.uSVC.Get(userID)
|
|
if err != nil {
|
|
c.log.Error("geting user from bot", "error", err)
|
|
text := "ERROR: "+ err.Error()
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
bots , err := c.uSVC.GetBots(us.TguID)
|
|
if err != nil {
|
|
c.log.Error("geting bots for user ", "error", err)
|
|
text := "ERROR: "+ err.Error()
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
if !slices.Contains(bots, c.bot.Self.UserName){
|
|
c.log.Error("user is not part of bot list")
|
|
text := "user is not part of bot list"
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
tgbUS := tgbotapi.User{
|
|
UserName: us.Username,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
ID: us.TguID,
|
|
}
|
|
msg := GenerateUserMessage(&tgbUS, c.update.SentFrom().ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg)
|
|
}
|
|
|
|
// banCommand
|
|
// ban an user by its user name as param
|
|
func banCommand(c *command, msg tgbotapi.MessageConfig){
|
|
msgTXT := strings.Split(c.update.Message.Text, " ")
|
|
if len(msgTXT) <= 1{
|
|
text := "command require username argument"
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
userName := msgTXT[1]
|
|
usL , err :=c.uSVC.GetAllBotsUsers(c.bot.Self.UserName)
|
|
if err != nil {
|
|
c.log.Error("geting users from bot")
|
|
text := "ERROR: "+ err.Error()
|
|
c.bot.Send(tgbotapi.NewMessage(c.update.FromChat().ID, text))
|
|
return
|
|
}
|
|
for _, us := range usL{
|
|
if us.Username == userName{
|
|
tgbUS := tgbotapi.User{
|
|
UserName: us.Username,
|
|
FirstName: us.FirstName,
|
|
LastName: us.LastName,
|
|
ID: us.TguID,
|
|
}
|
|
msg := GenerateUserMessage(&tgbUS, c.update.SentFrom().ID, c.bot.Self.UserName)
|
|
c.bot.Send(msg)
|
|
return
|
|
}
|
|
}
|
|
msg.Text = "user not foun on bot list"
|
|
c.bot.Send(msg)
|
|
}
|