diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 0b8d51ac..68cb3047 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -20,4 +20,4 @@ services: - ADMINER_PLUGINS=enum-types enum-option json-column volumes: postgres: - driver: local \ No newline at end of file + driver: local diff --git a/go.mod b/go.mod index bda9fbf8..a32f0593 100644 --- a/go.mod +++ b/go.mod @@ -12,11 +12,11 @@ require ( github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.10.9 github.com/mattn/go-sqlite3 v1.14.16 - github.com/mr-linch/go-tg v0.11.0 + github.com/mr-linch/go-tg v0.14.0 github.com/nicklaw5/helix/v2 v2.25.2 github.com/samber/lo v1.38.1 github.com/sourcegraph/conc v0.3.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.26.0 ) @@ -32,12 +32,12 @@ require ( github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.5.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect github.com/zclconf/go-cty v1.14.1 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/go.sum b/go.sum index 81d31621..1a2bc065 100644 --- a/go.sum +++ b/go.sum @@ -10,7 +10,6 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= @@ -50,14 +49,18 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3v github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mr-linch/go-tg v0.11.0 h1:vgL9TaKGHxA5Iid5bNyHUQMeTExwthVNJTkG2wHh2tA= -github.com/mr-linch/go-tg v0.11.0/go.mod h1:ySHBZ68Wl5Vgd6RAjNf9wbnwEN1P8deawEB/qr3GbDM= +github.com/mr-linch/go-tg v0.14.0 h1:dlARQM+DszkraRPOueq0eTw6/YM9ZsfvLBr1famKwE0= +github.com/mr-linch/go-tg v0.14.0/go.mod h1:poS5Fu8a76VHcoG0QOjYzytuMIs0570DkITujOtdOI8= github.com/nicklaw5/helix/v2 v2.25.2 h1:diGnmRnUpNk8vYVM1vOjUo5PGZnr8atbkUYT78T6evc= github.com/nicklaw5/helix/v2 v2.25.2/go.mod h1:zZcKsyyBWDli34x3QleYsVMiiNGMXPAEU5NjsiZDtvY= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -72,17 +75,15 @@ github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= -github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc= github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= @@ -93,17 +94,20 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/message_sender/message_sender_impl.go b/internal/message_sender/message_sender_impl.go index 95c9f491..040a6e07 100644 --- a/internal/message_sender/message_sender_impl.go +++ b/internal/message_sender/message_sender_impl.go @@ -63,7 +63,9 @@ func (m *MessageSender) SendMessage(ctx context.Context, chat *db_models.Chat, o } else { query := m.telegram. SendMessage(tg.ChatID(chatId), opts.Text). - DisableWebPagePreview(true) + LinkPreviewOptions(tg.LinkPreviewOptions{ + IsDisabled: true, + }) if keyboard != nil && keyboard.InlineKeyboard != nil && len(keyboard.InlineKeyboard) > 0 { query = query.ReplyMarkup(keyboard) diff --git a/internal/telegram/commands/follows.go b/internal/telegram/commands/follows.go index 8c908c45..626ec5cf 100644 --- a/internal/telegram/commands/follows.go +++ b/internal/telegram/commands/follows.go @@ -197,7 +197,7 @@ func (c *FollowsCommand) prevPageQuery(ctx context.Context, msg *tgb.CallbackQue } return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -215,7 +215,7 @@ func (c *FollowsCommand) nextPageQuery(ctx context.Context, msg *tgb.CallbackQue } return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } diff --git a/internal/telegram/commands/language_picker.go b/internal/telegram/commands/language_picker.go index bd5c1422..b2ec16f6 100644 --- a/internal/telegram/commands/language_picker.go +++ b/internal/telegram/commands/language_picker.go @@ -4,13 +4,14 @@ import ( "context" "errors" "fmt" + "strings" + "github.com/mr-linch/go-tg" "github.com/mr-linch/go-tg/tgb" "github.com/satont/twitch-notifier/internal/db" "github.com/satont/twitch-notifier/internal/db/db_models" tgtypes "github.com/satont/twitch-notifier/internal/telegram/types" "go.uber.org/zap" - "strings" ) type LanguagePicker struct { @@ -49,7 +50,7 @@ func (c *LanguagePicker) HandleCallback(ctx context.Context, msg *tgb.CallbackQu } return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.Message.ID). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -69,7 +70,7 @@ func (c *LanguagePicker) handleSetLanguage(ctx context.Context, msg *tgb.Callbac _, err := c.Services.Chat.Update( ctx, - msg.Message.Chat.ID.PeerID(), + msg.Message.Chat().ID.PeerID(), db_models.ChatServiceTelegram, &db.ChatUpdateQuery{ Settings: &db.ChatUpdateSettingsQuery{ diff --git a/internal/telegram/commands/language_picker_test.go b/internal/telegram/commands/language_picker_test.go index f134383b..7c8024f8 100644 --- a/internal/telegram/commands/language_picker_test.go +++ b/internal/telegram/commands/language_picker_test.go @@ -3,16 +3,17 @@ package commands import ( "context" "fmt" - "github.com/satont/twitch-notifier/internal/db" - "github.com/satont/twitch-notifier/internal/db/db_models" - "github.com/satont/twitch-notifier/internal/telegram/types" - "github.com/satont/twitch-notifier/internal/types" "io" "net/http" "net/http/httptest" "net/url" "testing" + "github.com/satont/twitch-notifier/internal/db" + "github.com/satont/twitch-notifier/internal/db/db_models" + tg_types "github.com/satont/twitch-notifier/internal/telegram/types" + "github.com/satont/twitch-notifier/internal/types" + "github.com/google/uuid" "github.com/mr-linch/go-tg" "github.com/mr-linch/go-tg/tgb" @@ -135,11 +136,8 @@ func TestLanguagePicker_HandleCallback(t *testing.T) { err := cmd.HandleCallback(ctx, &tgb.CallbackQueryUpdate{ Client: test_utils.NewTelegramClient(server), CallbackQuery: &tg.CallbackQuery{ - Message: &tg.Message{ - ID: 1, - Chat: tg.Chat{ - ID: tg.ChatID(1), - }, + Message: &tg.MaybeInaccessibleMessage{ + InaccessibleMessage: &tg.InaccessibleMessage{MessageID: 1, Chat: tg.Chat{ID: tg.ChatID(1)}}, }, }, }) @@ -197,10 +195,12 @@ func TestLanguagePicker_handleSetLanguage(t *testing.T) { err := cmd.handleSetLanguage(ctx, &tgb.CallbackQueryUpdate{ Client: test_utils.NewTelegramClient(server), CallbackQuery: &tg.CallbackQuery{ - Message: &tg.Message{ - ID: 1, - Chat: tg.Chat{ - ID: tg.ChatID(1), + Message: &tg.MaybeInaccessibleMessage{ + Message: &tg.Message{ + ID: 1, + Chat: tg.Chat{ + ID: tg.ChatID(1), + }, }, }, Data: "language_picker_set_ru", diff --git a/internal/telegram/commands/live.go b/internal/telegram/commands/live.go index 5de5cf2a..6d367550 100644 --- a/internal/telegram/commands/live.go +++ b/internal/telegram/commands/live.go @@ -3,14 +3,15 @@ package commands import ( "context" "fmt" + "strings" + "time" + "github.com/mr-linch/go-tg" "github.com/mr-linch/go-tg/tgb" "github.com/samber/lo" "github.com/satont/twitch-notifier/internal/db/db_models" tgtypes "github.com/satont/twitch-notifier/internal/telegram/types" "go.uber.org/zap" - "strings" - "time" ) type LiveCommand struct { @@ -132,7 +133,7 @@ func (c *LiveCommand) HandleCommand(ctx context.Context, msg *tgb.MessageUpdate) return msg. Answer(strings.Join(message, "\n\n")). ParseMode(tg.MD). - DisableWebPagePreview(true). + LinkPreviewOptions(tg.LinkPreviewOptions{IsDisabled: true}). DoVoid(ctx) } diff --git a/internal/telegram/commands/start.go b/internal/telegram/commands/start.go index b14714e5..3a59d977 100644 --- a/internal/telegram/commands/start.go +++ b/internal/telegram/commands/start.go @@ -133,7 +133,7 @@ func (c *StartCommand) handleCallback(ctx context.Context, msg *tgb.CallbackQuer keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -162,7 +162,7 @@ func (c *StartCommand) handleImageInNotificationSettings( keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -193,7 +193,7 @@ func (c *StartCommand) handleTitleNotificationSettings( keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -224,7 +224,7 @@ func (c *StartCommand) handleGameNotificationSettings( keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -254,7 +254,7 @@ func (c *StartCommand) handleGameAndTitleNotificationSettings( keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) } @@ -285,7 +285,7 @@ func (c *StartCommand) handleOfflineNotificationSettings( keyboard := c.buildKeyboard(ctx) return msg.Client. - EditMessageReplyMarkup(msg.Message.Chat.ID, msg.Message.ID). + EditMessageReplyMarkup(msg.Message.Chat().ID, msg.Message.MessageID()). ReplyMarkup(*keyboard). DoVoid(ctx) }