Compare commits
13 Commits
50bcb37513
...
8df3679e6f
| Author | SHA1 | Date | |
|---|---|---|---|
| 8df3679e6f | |||
| 695116cea3 | |||
| 858e647e24 | |||
| 169937bebd | |||
| b8fa3d2594 | |||
| a6a4328ed5 | |||
| 01585ea59b | |||
| 0f2762d53c | |||
| 0f2ba7af44 | |||
| cd51d2df09 | |||
| 325cd21f5d | |||
| 81a4a6c767 | |||
| 8372d75457 |
2
Makefile
2
Makefile
@ -39,6 +39,8 @@ 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
|
||||||
|
|||||||
13
Readme.org
13
Readme.org
@ -63,6 +63,14 @@ 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
|
||||||
@ -99,6 +107,10 @@ 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
|
||||||
@ -109,6 +121,7 @@ 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.
|
||||||
|
|||||||
@ -10,6 +10,7 @@ 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"
|
||||||
@ -19,15 +20,14 @@ 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,6 +37,16 @@ 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)
|
||||||
@ -51,13 +61,12 @@ 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)
|
||||||
}
|
}
|
||||||
@ -76,6 +85,11 @@ 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,41 @@ 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
9
go.mod
@ -5,13 +5,18 @@ 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.26.0 // indirect
|
golang.org/x/sys v0.27.0 // indirect
|
||||||
golang.org/x/text v0.19.0 // indirect
|
golang.org/x/text v0.20.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
30
go.sum
@ -1,5 +1,9 @@
|
|||||||
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=
|
||||||
@ -12,6 +16,18 @@ 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=
|
||||||
@ -24,13 +40,19 @@ 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.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||||
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=
|
||||||
|
|||||||
@ -1 +1,39 @@
|
|||||||
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -186,17 +186,13 @@ ChatID: %d
|
|||||||
}
|
}
|
||||||
|
|
||||||
bn, _ := b.GetMe(context.Background())
|
bn, _ := b.GetMe(context.Background())
|
||||||
kbd := &models.InlineKeyboardMarkup{
|
options := [][]string{
|
||||||
InlineKeyboard: [][]models.InlineKeyboardButton{
|
{"Grant", fmt.Sprintf("operation=grant&userID=%d&bot=%s", up.ID, bn.Username)},
|
||||||
{
|
{"Deny", fmt.Sprintf("operation=deny&userID=%d&bot=%s", up.ID, bn.Username)},
|
||||||
{Text: "Grant", CallbackData: fmt.Sprintf("operation=grant&userID=%d&bot=%s", up.ID, bn.Username)},
|
// {"Deny", fmt.Sprintf("operation=ignore&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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ package helpers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/go-telegram/bot/models"
|
"github.com/go-telegram/bot/models"
|
||||||
)
|
)
|
||||||
@ -34,7 +33,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,
|
||||||
@ -42,7 +41,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)
|
||||||
|
|
||||||
@ -54,15 +53,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{
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@ -40,16 +40,15 @@ 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.Info("emoji message reaction encounter", "reactions", update.MessageReaction.NewReaction)
|
log.Debug("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.Info("not a reaction")
|
log.Debug("not a reaction")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,6 +39,17 @@ 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +91,7 @@ func SetAuthRequired(svc ports.UserService, log *slog.Logger) func(bot.HandlerFu
|
|||||||
} else {
|
} else {
|
||||||
key = update.CallbackQuery.From.ID
|
key = update.CallbackQuery.From.ID
|
||||||
}
|
}
|
||||||
slog.Debug("executing auth func","user", key)
|
log.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 {
|
||||||
@ -89,7 +100,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.Info("user Authenticated", "user", key, "time", time.Now())
|
log.Debug("user Authenticated", "user", key, "time", time.Now())
|
||||||
next(ctx, b, update)
|
next(ctx, b, update)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +108,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.Info("user on cache available", "user", key, "time", when)
|
log.Debug("user on cache available", "user", key, "time", when)
|
||||||
next(ctx, b, update)
|
next(ctx, b, update)
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
@ -190,7 +201,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.Info("user loaded on map")
|
log.Debug("user loaded on map")
|
||||||
dt, _ := rl.Load(key)
|
dt, _ := rl.Load(key)
|
||||||
dtl := dt.(data)
|
dtl := dt.(data)
|
||||||
|
|
||||||
@ -207,11 +218,11 @@ func CreateRateLimitUser(ctx context.Context, log *slog.Logger, delay float64, h
|
|||||||
return
|
return
|
||||||
case false:
|
case false:
|
||||||
|
|
||||||
log.Info("user rl not execeed", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount)
|
log.Debug("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.Info("user time", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount)
|
log.Debug("user time", "since", time.Since(dtl.when).Seconds(), "amount", dtl.amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user