All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
216 lines
5.7 KiB
Go
216 lines
5.7 KiB
Go
package message
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
|
"github.com/maximotejeda/us_dop_bot/internal/application/domain"
|
|
"github.com/maximotejeda/us_dop_bot/internal/application/static"
|
|
"github.com/maximotejeda/us_dop_bot/internal/ports"
|
|
)
|
|
|
|
var ChatPool *sync.Pool
|
|
|
|
type Message struct {
|
|
bot *tgbotapi.BotAPI
|
|
update *tgbotapi.Update
|
|
msg *tgbotapi.MessageConfig
|
|
log *slog.Logger
|
|
dolar ports.DolarService
|
|
user ports.UserService
|
|
}
|
|
|
|
// NewMessage
|
|
// Factory for message handler
|
|
func NewMessage(bot *tgbotapi.BotAPI, update *tgbotapi.Update, dolar ports.DolarService, 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.dolar = dolar
|
|
message.user = user
|
|
return message
|
|
}
|
|
|
|
// Empty
|
|
// Returns pointer to pool
|
|
func (m *Message) Empty() {
|
|
m.update = nil
|
|
m.msg = nil
|
|
m.log = nil
|
|
m.dolar = 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)
|
|
}
|
|
|
|
// Handler
|
|
// Manage features for messages
|
|
func (m *Message) Handler() {
|
|
msg := tgbotapi.NewMessage(m.update.Message.Chat.ID, "")
|
|
m.msg = &msg
|
|
msgtext := static.RemoveAccent(m.update.Message.Text)
|
|
re := regexp.MustCompile(`(?P<operacion>([cC]omprar?\s?(me)?|[vV]en(de)?(r)?(ta)?\s?(me)?))\s(?P<cantidad>[0-9.]{1,8})\s(?P<moneda>(dolar(e)?(s)?|peso(s)?|dollars?))\s?(?P<institucion>(.*))?`)
|
|
match := re.FindStringSubmatch(msgtext)
|
|
if len(match) != 0 {
|
|
operacion := match[1]
|
|
operacion = strings.ToLower(operacion)
|
|
cantidadStr := match[8]
|
|
cantidad, err := strconv.ParseFloat(cantidadStr, 64)
|
|
if err != nil {
|
|
m.log.Error("converting to float cantidad", "error", err)
|
|
m.msg.Text = "cantidad no reconocidad " + cantidadStr
|
|
m.Send()
|
|
return
|
|
}
|
|
moneda := match[9]
|
|
moneda = strings.ToLower(moneda)
|
|
institucion := match[14]
|
|
institucion = strings.ToLower(institucion)
|
|
switch {
|
|
case strings.Contains(operacion, "compra"):
|
|
txt := m.Compra(cantidad, moneda, institucion)
|
|
m.msg.Text = txt
|
|
case strings.Contains(operacion, "vend"):
|
|
txt := m.Venta(cantidad, moneda, institucion)
|
|
m.msg.Text = txt
|
|
|
|
default:
|
|
m.msg.Text = "operacion no reconocida"
|
|
}
|
|
|
|
m.Send()
|
|
}
|
|
}
|
|
|
|
func (m *Message) Compra(cantidad float64, moneda, institucion string) string {
|
|
txt := ""
|
|
inst := static.NewInstList()
|
|
list := []*domain.History{}
|
|
if institucion == "" {
|
|
brd, bp, bhd, bcd := m.getPrincipalBank()
|
|
list = []*domain.History{brd, bp, bhd, bcd}
|
|
} else {
|
|
|
|
txtList := inst.GetName(institucion)
|
|
if len(txtList) <= 0 {
|
|
txt = "no institution with name " + institucion
|
|
return txt
|
|
} else {
|
|
for _, v := range txtList {
|
|
i, err := m.dolar.GetLatest(v.Name)
|
|
if err != nil {
|
|
m.log.Error("getting latest", "inst", v, "error", err)
|
|
continue
|
|
}
|
|
list = append(list, i)
|
|
}
|
|
}
|
|
}
|
|
if strings.Contains(moneda, "peso") {
|
|
txt = fmt.Sprintf("Comprando dolares \nRD.$ %.2f pesos:\n", cantidad)
|
|
for _, it := range list {
|
|
compra := cantidad / it.Venta
|
|
txt = txt + fmt.Sprintf(" %s \t->\t USD$. %.2f\n", inst.GetAbbrev(it.Institution.Name), compra)
|
|
}
|
|
} else if strings.Contains(moneda, "dol") {
|
|
txt = fmt.Sprintf("Comprando %.2f dolares:\n", cantidad)
|
|
for _, it := range list {
|
|
compra := cantidad * it.Venta
|
|
txt = txt + fmt.Sprintf(" %s \t->\t RD$. %.2f\n", inst.GetAbbrev(it.Institution.Name), compra)
|
|
}
|
|
}
|
|
|
|
return txt
|
|
}
|
|
|
|
func (m *Message) Venta(cantidad float64, moneda, institucion string) string {
|
|
txt := ""
|
|
list := []*domain.History{}
|
|
|
|
inst := static.NewInstList()
|
|
if institucion == "" {
|
|
brd, bp, bhd, bcd := m.getPrincipalBank()
|
|
list = []*domain.History{brd, bp, bhd, bcd}
|
|
} else {
|
|
txtList := inst.GetName(institucion)
|
|
if len(txtList) <= 0 {
|
|
txt = "no institution with name " + institucion
|
|
return txt
|
|
} else {
|
|
for _, v := range txtList {
|
|
i, err := m.dolar.GetLatest(v.Name)
|
|
if err != nil {
|
|
m.log.Error("getting latest", "inst", v, "error", err)
|
|
continue
|
|
}
|
|
list = append(list, i)
|
|
}
|
|
}
|
|
|
|
}
|
|
if len(list) <= 0 {
|
|
return "no institutions found with name " + institucion
|
|
}
|
|
if strings.Contains(moneda, "peso") {
|
|
txt = fmt.Sprintf("Vendiendo equivalente a RD.$ %.2f pesos:\n", cantidad)
|
|
for _, it := range list {
|
|
venta := cantidad / it.Compra
|
|
txt = txt + fmt.Sprintf(" %s \t->\t USD$. %.2f\n", inst.GetAbbrev(it.Institution.Name), venta)
|
|
}
|
|
|
|
} else if strings.Contains(moneda, "dol") {
|
|
txt = fmt.Sprintf("Vendiendo USD.$ %.2f dolares\n", cantidad)
|
|
for _, it := range list {
|
|
venta := cantidad * it.Compra
|
|
txt = txt + fmt.Sprintf(" %s \t->\t RD$. %.2f\n", inst.GetAbbrev(it.Institution.Name), venta)
|
|
}
|
|
|
|
}
|
|
|
|
return txt
|
|
}
|
|
|
|
func (m *Message) getPrincipalBank() (brd, bp, bhd, bcd *domain.History) {
|
|
// principales bancos
|
|
// bhd reservas popular central
|
|
brd, err := m.dolar.GetLatest("banreservas")
|
|
if err != nil {
|
|
m.log.Error("query latest for banreservas", "error", err)
|
|
}
|
|
bp, err = m.dolar.GetLatest("banco popular")
|
|
if err != nil {
|
|
m.log.Error("query latest for banco popular")
|
|
}
|
|
bhd, err = m.dolar.GetLatest("banco hipotecario dominicano")
|
|
if err != nil {
|
|
m.log.Error("query latest for banreservas")
|
|
}
|
|
bcd, err = m.dolar.GetLatest("banco central dominicano")
|
|
if err != nil {
|
|
m.log.Error("query latest for banreservas")
|
|
}
|
|
return brd, bp, bhd, bcd
|
|
}
|