229 lines
5.7 KiB
Go
229 lines
5.7 KiB
Go
package chat
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"unicode"
|
|
|
|
"git.maximotejeda.com/maximo/cedulados-bot/config"
|
|
"git.maximotejeda.com/maximo/cedulados-bot/internal/adapter/grpc/cedulados"
|
|
"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"
|
|
tgb "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
|
"golang.org/x/text/runes"
|
|
"golang.org/x/text/transform"
|
|
"golang.org/x/text/unicode/norm"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
)
|
|
|
|
var ChatPool *sync.Pool
|
|
|
|
type ChatObj struct {
|
|
ctx context.Context
|
|
update *tgb.Update
|
|
bot *tgb.BotAPI
|
|
u ports.UserService
|
|
c ports.CeduladosService
|
|
}
|
|
|
|
func NewChatObj(bot *tgb.BotAPI, updt *tgb.Update) (chat *ChatObj) {
|
|
if ChatPool == nil {
|
|
ChatPool = &sync.Pool{
|
|
New: func() any { return &ChatObj{} },
|
|
}
|
|
for i := 0; i < 20; i++ {
|
|
ChatPool.Put(ChatPool.New())
|
|
}
|
|
} else {
|
|
fmt.Println("alredy populated")
|
|
}
|
|
|
|
chat = ChatPool.Get().(*ChatObj)
|
|
chat.update = updt
|
|
chat.bot = bot
|
|
return chat
|
|
}
|
|
|
|
func (ch *ChatObj)Empty() {
|
|
ch.update = nil
|
|
ch.c = nil
|
|
ch.u = nil
|
|
ChatPool.Put(ch)
|
|
}
|
|
|
|
func (ch *ChatObj)Send(){
|
|
|
|
}
|
|
|
|
func (ch *ChatObj)Handler( cSVC ports.CeduladosService, uSVC ports.UserService) {
|
|
text := NormalizeText(ch.update.Message.Text)
|
|
textList := strings.Split(text, " ")
|
|
msg := tgb.NewMessage(ch.update.Message.Chat.ID, "")
|
|
if len(textList) >= 1 && MessageChecker(text) == "digit" {
|
|
// in case of message match a cedula
|
|
ced, err := helper.NewCedula(ch.ctx, text)
|
|
if err != nil {
|
|
msg.Text = "cedula no reconocida " + err.Error()
|
|
} else {
|
|
msg, photoMsg := ProcessByCedula(ch.ctx, cSVC, uSVC, ced)
|
|
msg.ChatID = ch.update.Message.Chat.ID
|
|
if photoMsg != nil {
|
|
photoMsg.ChatID = ch.update.Message.Chat.ID
|
|
ch.bot.Send(photoMsg)
|
|
}
|
|
ch.bot.Send(msg)
|
|
return
|
|
}
|
|
} else if len(textList) >= 2 && MessageChecker(text) == "word" {
|
|
msg := ProcessByName(ch.ctx, cSVC, uSVC, textList)
|
|
msg.ChatID = ch.update.Message.Chat.ID
|
|
ch.bot.Send(msg)
|
|
}
|
|
|
|
msg.ReplyToMessageID = ch.update.Message.MessageID
|
|
ch.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 *tgb.MessageConfig, fotoMsg *tgb.PhotoConfig) {
|
|
msg := tgb.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, RemoveSpaces(info.Direccion), info.Telefono)
|
|
}
|
|
var opts []grpc.DialOption
|
|
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
cedConn, err := grpc.NewClient(config.GetCeduladosServiceURL(), opts...)
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
}
|
|
c, err := cedulados.NewAdapter(cedConn)
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
}
|
|
defer cedConn.Close()
|
|
|
|
foto, err := c.QueryFotoByID(ctx, 1)
|
|
if err != nil {
|
|
fmt.Println("Photo not found", err.Error())
|
|
return
|
|
}
|
|
if foto != nil {
|
|
rq := tgb.FileReader{Name: fmt.Sprintf("%s-%s-%s", ced.MunCed, ced.SeqCed, ced.VerCed), Reader: bytes.NewReader(foto.Imagen)}
|
|
fotost := tgb.NewPhoto(msg.ChatID, rq)
|
|
fotoMsg = &fotost
|
|
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func ProcessByName(ctx context.Context, cSVC ports.CeduladosService, uSVC ports.UserService, nameList []string) (message *tgb.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 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 = &tgb.MessageConfig{}
|
|
text := strings.Join(nameList, " ")
|
|
|
|
res, err := cSVC.CeduladoByFTS(ctx, "maximo tejeda", 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
|
|
}
|
|
|
|
func MessageChecker(text string) string {
|
|
// Check is text start with number
|
|
checkSpace := regexp.MustCompile(`^[\s]+.*`)
|
|
checkNumber := regexp.MustCompile(`^[\d]+.*`)
|
|
checkWord := regexp.MustCompile(`^[a-zA-Z% ]+.*`)
|
|
|
|
if checkNumber.MatchString(text) {
|
|
return "digit"
|
|
} else if checkWord.MatchString(text) {
|
|
return "word"
|
|
} else if checkSpace.MatchString(text) {
|
|
t := strings.TrimSpace(text)
|
|
return MessageChecker(t)
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// NormalizeText
|
|
// remove foreign accent
|
|
func NormalizeText(text string) string {
|
|
t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
|
|
result, _, _ := transform.String(t, text)
|
|
return result
|
|
}
|
|
|
|
func RemoveSpaces(text string) (res string) {
|
|
re := regexp.MustCompile(`[\s]+`)
|
|
|
|
res = re.ReplaceAllString(text, " ")
|
|
return
|
|
}
|