package command import ( "log/slog" "slices" "strings" "sync" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/maximotejeda/us_dop_bot/internal/application/helpers" "github.com/maximotejeda/us_dop_bot/internal/ports" ) var commandPool *sync.Pool type Command struct { bot *tgbotapi.BotAPI update *tgbotapi.Update msg *tgbotapi.MessageConfig log *slog.Logger dolar ports.DolarService user ports.UserService } // NewCommand // Factory for Command Handler func NewCommand(bot *tgbotapi.BotAPI, update *tgbotapi.Update, dolar ports.DolarService, 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.Chat.ID, "userid", update.Message.From.ID, "username", update.Message.From.UserName) commands := commandPool.Get().(*Command) commands.update = update commands.bot = bot commands.log = log commands.dolar = dolar commands.user = user return commands } // Empty // Returns pointer to command pool func (c *Command) Empty() { c.update = nil c.msg = nil c.log = nil c.dolar = nil commandPool.Put(c) } // Send // Process command handlers func (c *Command) Send() { defer c.Empty() c.bot.Send(*c.msg) del := tgbotapi.NewDeleteMessage(c.update.Message.From.ID, c.update.Message.MessageID) c.bot.Send(del) } // Handler // Manage command message for chat func (c *Command) Handler() { msg := tgbotapi.NewMessage(c.update.Message.Chat.ID, "command") c.msg = &msg command := c.update.Message.Command() switch strings.ToLower(command) { case "list", "lista": msg.Text = "list todo" case "listabancos": bancos, err := c.lista("bancos") if err != nil { c.log.Error("query bancos", "error", err) return } msg = bancos case "listacajas": cajas, err := c.lista("cajas") if err != nil { c.log.Error("query cajas", "error", err) return } msg = cajas case "listagentes": agentes, err := c.lista("agentes") if err != nil { c.log.Error("query bancos", "error", err) return } msg = agentes case "consulta": instSubs, err := c.dolar.GetSubscribedInsts(c.update.Message.From.ID) if err != nil { c.log.Error("command-consulta", "err", err) } if len(instSubs) > 0 { btnSTR := map[string]string{} for _, inst := range instSubs { switch inst { case "asociacion popular de ahorros y prestamos": btnSTR[inst] = "consultar=true&name=apap" case "asociacion cibao de ahorros y prestamos": btnSTR[inst] = "consultar=true&name=acap" case "asociacion la nacional de ahorros y prestamos": btnSTR[inst] = "consultar=true&name=anap" case "asociacion peravia de ahorros y prestamos": btnSTR[inst] = "consultar=true&name=aperap" default: btnSTR[inst] = "consultar=true&name=" + inst } } btnSTR["cancelar ❌"] = "cancelar=true" keyboard := helpers.CreateKeyboard(btnSTR) msg.ReplyMarkup = keyboard msg.Text = "Suscripciones actuales πŸ’°\nPuedes hacer click para Ver cambios en los precios de las suscripcion\n o presionar cancelar" } else { msg.Text = "No existen subscripciones actualmente" } case "status", "info": instSubbed, err := c.dolar.GetSubscribedInsts(c.update.Message.From.ID) if err != nil { c.log.Error("command-status", "err", err) } if len(instSubbed) > 0 { btnSTR := map[string]string{} for _, inst := range instSubbed { btnSTR[inst] = "unsubs=true&name=" + inst } btnSTR["cancelar ❌"] = "cancelar=true" keyboard := helpers.CreateKeyboard(btnSTR) msg.ReplyMarkup = keyboard msg.Text = "Suscripciones actuales πŸ’°\n Puedes hacer click en una para eliminar su subscripcion\nPresionar cancelar para omitir." } else { msg.Text = "No existen subscripciones actualmente" } case "reset": reset := map[string]string{"Reset": "reset=true", "cancelar ❌": "cancelar=true"} keyboard := helpers.CreateKeyboard(reset) msg.ReplyMarkup = keyboard msg.Text = "Esta Seguro DE Eliminar todas las suscripciones del usuario." case "help", "start", "ayuda", "h": help := ` Asistente de cambio US <-> DOP πŸ‡ΊπŸ‡Έ ↔️ πŸ‡©πŸ‡΄ Tracker del precio del dolar para RD. Funciona suscribiendo instituciones πŸ’Έ. - Tracker precio del dolar ❇️. - Notificacion mensaje automatico πŸ“ˆ. - Precio actual ⌚. - Historico de precios πŸ“…. Comandos Conocidos por el bot: /help: Muestra este mensaje ❓ /listabancos: Muestra bancos 🏦 /listacajas: Muestra asociaciones /listagentes: Muestra agentes πŸ“Š /consulta: Consulta entidad suscrita πŸ›ŽοΈ /reset: Borra tada suscripcion 🧹 /status: Estado del usuario πŸ“‹ ` msg.Text = help default: msg.Text = "Commando desconocido intenta con\n/help: to get bot info." } c.Send() } func (c *Command) lista(instSTR string) (msg tgbotapi.MessageConfig, err error) { var instList []string msg = tgbotapi.MessageConfig{} msg.ChatID = c.update.Message.Chat.ID instList, err = c.dolar.GetInstByType(instSTR) if err != nil { c.log.Error("[inst-list-query]", "error", err) return msg, err } instMap := map[string]string{} subscribed, err := c.dolar.GetSubscribedInsts(c.update.Message.From.ID) if err != nil { c.log.Error("getting subscription", "error", err) } for _, i := range instList { if slices.Contains(subscribed, i) { continue } instMap[i] = "subs=true&name=" + i } instMap["cancelar ❌"] = "cancelar=true" keyboard := helpers.CreateKeyboard(instMap) switch instSTR { case "bancos": msg.Text = "Differentes Bancos disponibles para track el precio del cambio ejemplos:\n\n\tBanco Popular\n\n\tBanreservas\n\n" case "agentes": msg.Text = "Differentes Agentes disponibles para track el precio del cambio ejemplos:\n\n\trm\n\n\tgirosol\n\n" case "cajas": msg.Text = "Differentes cajas disponibles para track el precio del cambio ejemplos\n\n\tasociacion popular\n\n\tasociacion cibao\n\n" default: msg.Text = "lista de instuiticiones no reconocidad Opciones disponibles:\n\n\tbancos\n\n\tcajas\n\n\tagentes" } msg.ReplyMarkup = keyboard return msg, nil }