Compare commits

..

No commits in common. "8df3679e6fedad06446a31a95da9483a6646f6af" and "50bcb375139468287e093716a1494afc7a7a647a" have entirely different histories.

12 changed files with 75 additions and 177 deletions

View File

@ -39,8 +39,6 @@ run-image-debug: build-image-debug
run-local:clean build run-local:clean build
@bin/$(BINAME) @bin/$(BINAME)
debug-local: clean build
@dlv debug ./cmd/bot/.
run-webapp: clean build run-webapp: clean build
@bin/$(BINAME)-webapp @bin/$(BINAME)-webapp

View File

@ -63,14 +63,6 @@ ADMINS=admin_ids_comma_separated // id for admins, those will not need auth
RATE_LIMIT_SEC=12 // amount of time to limit hits in sec RATE_LIMIT_SEC=12 // amount of time to limit hits in sec
RATE_LIMIT_AMOUNT=2 // amount of hit limits in x times RATE_LIMIT_AMOUNT=2 // amount of hit limits in x times
AI_SERVER_URI=http://10.0.0.164
AI_CHAT_SERVER_PORT=11434
AI_CHAT_MODEL=deepseek-r1:8b
AI_CHAT_MODEL_FAST=llama3.2:latest
AI_CHAT_IMAGE=llava:7b
AI_TRANSCRIBE_SERVER_PORT=8080
AI_TRANSCRIBE_MODEL=whisper-1
#+END_SRC #+END_SRC
** Running the Bot ** Running the Bot
@ -107,10 +99,6 @@ In the functions added for the template you can find things like:
- Command Handlers - Command Handlers
- Callback Query Handlers - Callback Query Handlers
- Interactions Handlers - Interactions Handlers
- Photos Hanlder
- Voice Note Handler
- Location Handler
- Document Handlers
- Middlewares - Middlewares
- Singleflight - Singleflight
- Loging - Loging
@ -121,7 +109,6 @@ In the functions added for the template you can find things like:
- File - File
- Photo - Photo
- Keyboard - Keyboard
- Folder creation to handle photos voice or documents
This template heavily relies on the **[[tgbuser]]** microservice for This template heavily relies on the **[[tgbuser]]** microservice for
handling user authentication and permissions. handling user authentication and permissions.

View File

@ -10,7 +10,6 @@ import (
"git.maximotejeda.com/maximo/telegram-base-bot/config" "git.maximotejeda.com/maximo/telegram-base-bot/config"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/adapters/grpc/tgbuser" "git.maximotejeda.com/maximo/telegram-base-bot/internal/adapters/grpc/tgbuser"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/commands" "git.maximotejeda.com/maximo/telegram-base-bot/internal/application/commands"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/helpers"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/messages" "git.maximotejeda.com/maximo/telegram-base-bot/internal/application/messages"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/middlewares" "git.maximotejeda.com/maximo/telegram-base-bot/internal/application/middlewares"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/queries" "git.maximotejeda.com/maximo/telegram-base-bot/internal/application/queries"
@ -20,14 +19,15 @@ import (
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
) )
var log *slog.Logger var log *slog.Logger
func main() { func main() {
lvelEnv := config.GetEnvironment() lvelEnv:= config.GetEnvironment()
var lvel slog.Level var lvel slog.Level
if lvelEnv == "dev" || lvelEnv == "development" { if lvelEnv == "dev" || lvelEnv == "development"{
lvel = slog.LevelDebug lvel = slog.LevelDebug
} else { }else {
lvel = slog.LevelInfo lvel = slog.LevelInfo
} }
log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ log = slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
@ -37,16 +37,6 @@ func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel() defer cancel()
// a folder will be mounted and save dirs will be created on them
// assets for the bot
// assets sent from users for temp use
r, err := helpers.OpenBotDir(ctx, log, nil, "bot_media/", 0777)
if err != nil {
panic(err)
}
defer r.Close()
userSVC, conn := CreateAdaptersGRPC() userSVC, conn := CreateAdaptersGRPC()
defer conn.Close() defer conn.Close()
authRequired := middlewares.SetAuthRequired(userSVC, log) authRequired := middlewares.SetAuthRequired(userSVC, log)
@ -61,12 +51,13 @@ func main() {
"callback_query", "callback_query",
"id", "id",
}), }),
// bot.WithDefaultHandler(api.Handler),
} }
b, err := bot.New(config.GetToken(), opts...) b, err := bot.New(config.GetToken(), opts...)
if err != nil { if err != nil {
panic(err) panic(err)
} }
bInfo, err := b.GetMe(ctx) bInfo , err := b.GetMe(ctx)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -85,11 +76,6 @@ func main() {
messages.RegisterMessageHandler(ctx, log, b) messages.RegisterMessageHandler(ctx, log, b)
queries.RegisterQueries(ctx, log, b) queries.RegisterQueries(ctx, log, b)
messages.RegisterMessageReactionHandler(ctx, log, b) messages.RegisterMessageReactionHandler(ctx, log, b)
messages.RegisterLocationHandler(ctx, log, b)
messages.RegisterVoiceHandler(ctx, log, b, r)
messages.RegisterDocumentHandler(ctx, log, b, r)
messages.RegisterPhotosHandler(ctx, log, b, r)
b.Start(ctx) b.Start(ctx)
} }

View File

@ -6,41 +6,6 @@ import (
"strconv" "strconv"
) )
// GetAIServerURI ...
func GetAIServerURI()string {
return getEnvVariable("AI_SERVER_URI")
}
// GetAIChatServerPort ...
func GetAIChatServerPort()string {
return getEnvVariable("AI_CHAT_SERVER_PORT")
}
// GetAIChatModel ...
func GetAIChatModel()string {
return getEnvVariable("AI_CHAT_MODEL")
}
// GetAIChatModelFast ...
func GetAIChatModelFast()string {
return getEnvVariable("AI_CHAT_MODEL_FAST")
}
// GetAITranscribeServerPort ...
func GetAITranscribeServerPort()string {
return getEnvVariable("AI_TRANSCRIBE_SERVER_PORT")
}
// GetAITranscribeModel ...
func GetAITranscribeModel()string{
return getEnvVariable("AI_TRANSCRIBE_MODEL")
}
// GetAIChatImageModel ...
func GetAIChatImageModel()string {
return getEnvVariable("AI_CHAT_IMAGE")
}
// GetRateLimitSec // GetRateLimitSec
// Get the rate limit time amount to limit user request // Get the rate limit time amount to limit user request
// for example a user can make 1 request each sec "1 req x sec" // for example a user can make 1 request each sec "1 req x sec"

9
go.mod
View File

@ -5,18 +5,13 @@ go 1.23.2
require ( require (
git.maximotejeda.com/maximo/tgb-user v0.0.5 git.maximotejeda.com/maximo/tgb-user v0.0.5
github.com/go-telegram/bot v1.12.1 github.com/go-telegram/bot v1.12.1
github.com/mattn/go-sqlite3 v1.14.24
github.com/tmc/langchaingo v0.1.13
google.golang.org/grpc v1.69.2 google.golang.org/grpc v1.69.2
) )
require ( require (
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/pkoukk/tiktoken-go v0.1.6 // indirect
golang.org/x/net v0.30.0 // indirect golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.27.0 // indirect golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect golang.org/x/text v0.19.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
google.golang.org/protobuf v1.35.1 // indirect google.golang.org/protobuf v1.35.1 // indirect
) )

30
go.sum
View File

@ -1,9 +1,5 @@
git.maximotejeda.com/maximo/tgb-user v0.0.5 h1:OTACcjzOld9TsQHqzDqGXgdN3CqWrZ2p1ro0mUErCR0= git.maximotejeda.com/maximo/tgb-user v0.0.5 h1:OTACcjzOld9TsQHqzDqGXgdN3CqWrZ2p1ro0mUErCR0=
git.maximotejeda.com/maximo/tgb-user v0.0.5/go.mod h1:7KpTUAnwap6cp5pHRKgJygxrN3rftAdTkpCG2zJIpYI= git.maximotejeda.com/maximo/tgb-user v0.0.5/go.mod h1:7KpTUAnwap6cp5pHRKgJygxrN3rftAdTkpCG2zJIpYI=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
@ -16,18 +12,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pkoukk/tiktoken-go v0.1.6 h1:JF0TlJzhTbrI30wCvFuiw6FzP2+/bR+FIxUdgEAcUsw=
github.com/pkoukk/tiktoken-go v0.1.6/go.mod h1:9NiV+i9mJKGj1rYOT+njbv+ZwA/zJxYdewGl6qVatpg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tmc/langchaingo v0.1.13 h1:rcpMWBIi2y3B90XxfE4Ao8dhCQPVDMaNPnN5cGB1CaA=
github.com/tmc/langchaingo v0.1.13/go.mod h1:vpQ5NOIhpzxDfTZK9B6tf2GM/MoaHewPWM5KXXGh7hg=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
@ -40,19 +24,13 @@ go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HY
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@ -1,39 +1 @@
package db package db
import (
"context"
"database/sql"
"fmt"
"time"
_"embed"
_ "github.com/mattn/go-sqlite3"
)
//go:embed schema.sql
var schema string
func NewDB(ctx context.Context, URI string)(db *sql.DB, err error) {
params := "cache=shared&_foreign_keys=on&_busy_timeout=3000&_journal_mode=WAL"
db, err = sql.Open("sqlite3", fmt.Sprintf("%s?%s", URI, params))
if err != nil {
return nil, fmt.Errorf("connecting %w", err)
}
// test conn
err = db.PingContext(ctx)
if err != nil {
return nil, fmt.Errorf("ping Error %w", err)
}
db.SetConnMaxIdleTime(5*time.Second)
CreateTables(db)
return db, nil
}
func CreateTables(db *sql.DB) {
_, err := db.Exec(schema)
if err != nil {
panic(err)
}
}

View File

@ -186,13 +186,17 @@ ChatID: %d
} }
bn, _ := b.GetMe(context.Background()) bn, _ := b.GetMe(context.Background())
options := [][]string{ kbd := &models.InlineKeyboardMarkup{
{"Grant", fmt.Sprintf("operation=grant&userID=%d&bot=%s", up.ID, bn.Username)}, InlineKeyboard: [][]models.InlineKeyboardButton{
{"Deny", fmt.Sprintf("operation=deny&userID=%d&bot=%s", up.ID, bn.Username)}, {
// {"Deny", fmt.Sprintf("operation=ignore&userID=%d&bot=%s", up.ID, bn.Username)}, {Text: "Grant", CallbackData: fmt.Sprintf("operation=grant&userID=%d&bot=%s", up.ID, bn.Username)},
{Text: "Deny", CallbackData: fmt.Sprintf("operation=deny&userID=%d&bot=%s", up.ID, bn.Username)},
},
{
{Text: "Ignore", CallbackData: fmt.Sprintf("operation=ignore&userID=%d&bot=%s", up.ID, bn.Username)},
},
},
} }
kbd := KeyboardWithCancel(options, 2, false)
msg.ReplyMarkup = kbd msg.ReplyMarkup = kbd
return msg return msg
} }

View File

@ -2,6 +2,7 @@ package helpers
import ( import (
"errors" "errors"
"fmt"
"github.com/go-telegram/bot/models" "github.com/go-telegram/bot/models"
) )
@ -33,7 +34,7 @@ func AddButton(ik *InlineKeyboard, text, data string) {
if len(r.Buttons) < r.Len { if len(r.Buttons) < r.Len {
button := Button{Text: text, Data: data} button := Button{Text: text, Data: data}
r.Buttons = append(r.Buttons, button) r.Buttons = append(r.Buttons, button)
// fmt.Println("ADD BUTTON ", r, ik) fmt.Println("ADD BUTTON ", r, ik)
}else { }else {
r = &Row{ r = &Row{
Len: r.Len, Len: r.Len,
@ -41,7 +42,7 @@ func AddButton(ik *InlineKeyboard, text, data string) {
} }
button := Button{Text: text, Data: data} button := Button{Text: text, Data: data}
r.Buttons = append(r.Buttons, button) r.Buttons = append(r.Buttons, button)
// fmt.Println("ADD BUTTON ", r, ik) fmt.Println("ADD BUTTON ", r, ik)
ik.Rows = append(ik.Rows, *r) ik.Rows = append(ik.Rows, *r)
@ -53,15 +54,15 @@ func AddButton(ik *InlineKeyboard, text, data string) {
func AddRow(ik *InlineKeyboard, len int){ func AddRow(ik *InlineKeyboard, len int){
row := &Row{Len: len, Buttons: []Button{}} row := &Row{Len: len, Buttons: []Button{}}
ik.Rows = append(ik.Rows, *row) ik.Rows = append(ik.Rows, *row)
// fmt.Println("ADD Row ", row.Len) fmt.Println("ADD Row ", row.Len)
} }
// CreateKeyBoard // CreateKeyBoard
// render the structure into a models.InlineKeyboardMarkup // render the structure into a models.InlineKeyboardMarkup
func (ik *InlineKeyboard) CreateKeyBoard()models.InlineKeyboardMarkup{ func (ik *InlineKeyboard) CreateKeyBoard()models.InlineKeyboardMarkup{
kbd := models.InlineKeyboardMarkup{} kbd := models.InlineKeyboardMarkup{}
// fmt.Println("creating keyboard ---- ", fmt.Sprintf("%#v", ik)) fmt.Println("creating keyboard ---- ", fmt.Sprintf("%#v", ik))
// fmt.Println("row 0 ", ik.Rows[0]) fmt.Println("row 0 ", ik.Rows[0])
for _, row := range ik.Rows { for _, row := range ik.Rows {
r := []models.InlineKeyboardButton{} r := []models.InlineKeyboardButton{}
for _, button := range row.Buttons{ for _, button := range row.Buttons{

View File

@ -0,0 +1,32 @@
package messages
import (
"context"
"fmt"
"log/slog"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/helpers"
"git.maximotejeda.com/maximo/telegram-base-bot/internal/application/middlewares"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
)
func RegisterMessageHandler(ctx context.Context, log *slog.Logger, b *bot.Bot){
messageRL := middlewares.CreateRateLimitUser(ctx, log, 15, 1)
// b.RegisterHandler(bot.HandlerTypeMessageText, "hello", bot.MatchTypeExact, HandleHelloMessage, messageRL)
b.RegisterHandler(bot.HandlerTypeMessageText, "h", bot.MatchTypeContains, HandleHelloMessage, messageRL)
}
func HandleHelloMessage(ctx context.Context, b *bot.Bot, update *models.Update){
// kbd := &helpers.InlineKeyboard{}
it := [][]string{}
for x := range 9{
it = append(it, []string{fmt.Sprintf("%d", x), fmt.Sprintf("button_%d", x)})
}
kb:= helpers.KeyboardWithCancel(it, 3, false)
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.Message.Chat.ID,
Text: "managing text",
ReplyMarkup: kb,
})
}

View File

@ -40,15 +40,16 @@ func matchReaction(emoji string)func(*models.Update)bool{
if update.MessageReaction != nil && len(update.MessageReaction.NewReaction) > 0{ if update.MessageReaction != nil && len(update.MessageReaction.NewReaction) > 0{
switch reaction := update.MessageReaction.NewReaction[0].Type; reaction { switch reaction := update.MessageReaction.NewReaction[0].Type; reaction {
case models.ReactionTypeTypeEmoji: case models.ReactionTypeTypeEmoji:
log.Debug("emoji message reaction encounter", "reactions", update.MessageReaction.NewReaction) log.Info("emoji message reaction encounter", "reactions", update.MessageReaction.NewReaction)
if update.MessageReaction.NewReaction[0].ReactionTypeEmoji.Emoji == emoji{ if update.MessageReaction.NewReaction[0].ReactionTypeEmoji.Emoji == emoji{
return true return true
} }
} }
}else{ }else{
log.Info("not the same character")
return false return false
} }
log.Debug("not a reaction") log.Info("not a reaction")
return false return false
} }

View File

@ -39,17 +39,6 @@ func SingleFlight(next bot.HandlerFunc) bot.HandlerFunc {
} }
defer sf.Delete(key) defer sf.Delete(key)
next(ctx, b, update) next(ctx, b, update)
}else if update.Message != nil {
key := update.Message.From.ID
if _, loaded := sf.LoadOrStore(key, struct{}{}); loaded{
log.Debug("key alredy loaded", "key", key)
b.SendMessage(ctx, &bot.SendMessageParams{ChatID: update.Message.From.ID, Text: "IA esta aun procesando su respuesta, por favor espere!!!"})
return
}else{
log.Debug("key not loaded", "key", key)
}
defer sf.Delete(key)
next(ctx, b, update)
} }
} }
} }
@ -91,7 +80,7 @@ func SetAuthRequired(svc ports.UserService, log *slog.Logger) func(bot.HandlerFu
} else { } else {
key = update.CallbackQuery.From.ID key = update.CallbackQuery.From.ID
} }
log.Debug("executing auth func","user", key) slog.Debug("executing auth func","user", key)
authMe := func() { authMe := func() {
k := helpers.Authenticate(ctx, log, b, update, svc) k := helpers.Authenticate(ctx, log, b, update, svc)
if !k { if !k {
@ -100,7 +89,7 @@ func SetAuthRequired(svc ports.UserService, log *slog.Logger) func(bot.HandlerFu
} }
log.Debug("storing user last auth to map") log.Debug("storing user last auth to map")
userLastAuth.Store(key, time.Now()) userLastAuth.Store(key, time.Now())
log.Debug("user Authenticated", "user", key, "time", time.Now()) log.Info("user Authenticated", "user", key, "time", time.Now())
next(ctx, b, update) next(ctx, b, update)
} }
@ -108,7 +97,7 @@ func SetAuthRequired(svc ports.UserService, log *slog.Logger) func(bot.HandlerFu
when, _ := userLastAuth.Load(key) when, _ := userLastAuth.Load(key)
switch { switch {
case time.Since(when.(time.Time)).Minutes() < 3: // the time user will remain auth on the bot case time.Since(when.(time.Time)).Minutes() < 3: // the time user will remain auth on the bot
log.Debug("user on cache available", "user", key, "time", when) log.Info("user on cache available", "user", key, "time", when)
next(ctx, b, update) next(ctx, b, update)
return return
default: default:
@ -201,7 +190,7 @@ func CreateRateLimitUser(ctx context.Context, log *slog.Logger, delay float64, h
} }
log.Info("got key ", "key ", key) log.Info("got key ", "key ", key)
if _, loaded := rl.LoadOrStore(key, data{when: time.Now(), amount: 0}); loaded { if _, loaded := rl.LoadOrStore(key, data{when: time.Now(), amount: 0}); loaded {
log.Debug("user loaded on map") log.Info("user loaded on map")
dt, _ := rl.Load(key) dt, _ := rl.Load(key)
dtl := dt.(data) dtl := dt.(data)
@ -218,11 +207,11 @@ func CreateRateLimitUser(ctx context.Context, log *slog.Logger, delay float64, h
return return
case false: case false:
log.Debug("user rl not execeed", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount) log.Info("user rl not execeed", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount)
} }
case false: case false:
rl.Store(key, data{when: time.Now(), amount: 1}) rl.Store(key, data{when: time.Now(), amount: 1})
log.Debug("user time", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount) log.Info("user time", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount)
} }
} else { } else {