package message import ( "bytes" "context" "fmt" "log/slog" "strconv" "strings" "sync" "git.maximotejeda.com/maximo/cedulados-bot/internal/adapter/helper" "git.maximotejeda.com/maximo/cedulados-bot/internal/application/domain" "git.maximotejeda.com/maximo/cedulados-bot/internal/ports" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) var ChatPool *sync.Pool type Message struct { bot *tgbotapi.BotAPI update *tgbotapi.Update msg *tgbotapi.MessageConfig log *slog.Logger ce ports.CeduladosService user ports.UserService } // NewMessage // Factory for message handler func NewMessage(bot *tgbotapi.BotAPI, update *tgbotapi.Update, cSVC ports.CeduladosService, user ports.UserService) *Message { if ChatPool == nil { ChatPool = &sync.Pool{ New: func() any { return &Message{} }, } for i := 0; i < 20; i++ { ChatPool.Put(ChatPool.New()) } } log := slog.Default() log = log.With("function", "message", "chat", update.Message.Chat.ID, "userid", update.Message.From.ID, "username", update.Message.From.UserName) message := ChatPool.Get().(*Message) message.update = update message.bot = bot message.log = log message.ce = cSVC message.user = user return message } // Empty // Returns pointer to pool func (m *Message) Empty() { m.update = nil m.msg = nil m.log = nil m.ce = nil m.user = nil ChatPool.Put(m) } // Send // Process message sending to bot func (m *Message) Send() { defer m.Empty() m.bot.Send(m.msg) } func (m *Message) Handler(){ msg := tgbotapi.NewMessage(m.update.Message.Chat.ID, "") m.msg = &msg text := helper.RemoveAccent(m.update.Message.Text) textList := strings.Split(text, " ") if len(textList) >= 1 && helper.MessageChecker(text) == "digit" { // in case of message match a cedula ced, err := helper.NewCedula(context.Background(), text) if err != nil { msg.Text = "cedula no reconocida " + err.Error() } else { msg, photoMsg := ProcessByCedula(context.Background(), m.ce, m.user, ced) msg.ChatID = m.update.Message.Chat.ID if photoMsg != nil { photoMsg.ChatID = m.update.Message.Chat.ID m.bot.Send(photoMsg) } m.bot.Send(msg) return } } else if len(textList) >= 2 && helper.MessageChecker(text) == "word" { msg := ProcessByName(context.Background(), m.ce, m.user, textList) msg.ChatID = m.update.Message.Chat.ID m.bot.Send(msg) } msg.ReplyToMessageID = m.update.Message.MessageID m.bot.Send(msg) } // ProcessByCedula // // When a text arrives the chat if it match a cedula try to query db func ProcessByCedula(ctx context.Context, cSVC ports.CeduladosService, uSVC ports.UserService, ced *domain.Cedula) (message *tgbotapi.MessageConfig, fotoMsg *tgbotapi.PhotoConfig) { msg := tgbotapi.NewMessage(0, "") message = &msg info , err := cSVC.CeduladoByCedula(context.Background(), ced) if err != nil { fmt.Println("error on query ", err) } fmt.Println("!!!!success on query", info) if info != nil { msg.Text = fmt.Sprintf(` Nombres: %s Apellidos: %s %s Cedula: %s Direccion: %s Telefono: %s `, strings.ToLower(info.Nombres), strings.ToLower(info.Apellido1), strings.ToLower(info.Apellido2), info.MunCed+info.SeqCed+info.VerCed, helper.RemoveSpaces(info.Direccion), info.Telefono) } foto, err := cSVC.QueryFotoByCedula(ctx, ced) if err != nil { fmt.Println("Photo not found", err.Error()) return } if foto != nil { rq := tgbotapi.FileReader{Name: fmt.Sprintf("%s-%s-%s", ced.MunCed, ced.SeqCed, ced.VerCed), Reader: bytes.NewReader(foto.Imagen)} fotost := tgbotapi.NewPhoto(msg.ChatID, rq) fotoMsg = &fotost } return } func ProcessByName(ctx context.Context, cSVC ports.CeduladosService, uSVC ports.UserService, nameList []string) (message *tgbotapi.MessageConfig) { var err error page := int64(0) // look for if the last part of the list is a number lastItem := nameList[len(nameList)-1] if helper.MessageChecker(lastItem) == "digit" && !strings.HasPrefix(lastItem, "0") { pageInt, err := strconv.ParseInt(lastItem, 10, 64) if err != nil { fmt.Println(err) } nameList = nameList[:len(nameList)-1] if pageInt < 20 { page = pageInt } } rows := &domain.MultipleResults{} message = &tgbotapi.MessageConfig{} text := strings.Join(nameList, " ") res, err := cSVC.CeduladoByFTS(ctx, text, 0) if err != nil { fmt.Println("error oon fts", err) } fmt.Println("sucess", res) rows, err = cSVC.CeduladoByFTS(ctx, text, page) if err != nil { message.Text = "no hubo resultados para la busqueda" return } textToSend := fmt.Sprintf(` Busqueda: Texto: %s Pagina: %d resultados desde: %d A %d De un total de: %d `, text, (rows.Page), (rows.Page*10)-9, (rows.Page)*10, rows.Total) for _, v := range rows.Data { textToSend = textToSend + fmt.Sprintf("\n %s %s %s \n %s-%s-%s\n", strings.ToLower(v.Nombres), strings.ToLower(v.Apellido1), strings.ToLower(v.Apellido2), v.MunCed, v.SeqCed, v.VerCed) } message.Text = textToSend return }