Skip to content

Instantly share code, notes, and snippets.

@NihadBadalov
Last active May 3, 2024 19:58
Show Gist options
  • Save NihadBadalov/5eb3d5f776f37d2aa3b49133b11da06a to your computer and use it in GitHub Desktop.
Save NihadBadalov/5eb3d5f776f37d2aa3b49133b11da06a to your computer and use it in GitHub Desktop.
Telegram bot main.go - Keyboard Issue
package main
import (
"context"
"fmt"
"os"
"os/signal"
"reflect"
"strings"
"sync"
"github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
"oris/commands"
)
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
additionalContext, cancelInput := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancelInput()
defer cancel()
ce := &commands.CommandExecutor{}
// user_inputs is id->unix
additionalContext = context.WithValue(additionalContext, "user_inputs", &sync.Map{})
opts := []bot.Option{
bot.WithDefaultHandler(handler(&additionalContext)),
bot.WithCallbackQueryDataHandler("button", bot.MatchTypePrefix, keyboardHandler),
}
b, err := bot.New("token_redacted", opts...)
if err != nil {
panic(err)
}
b.RegisterHandlerMatchFunc(isCommand(ce), commandHandler(ce, &additionalContext))
fmt.Println("Bot started")
b.Start(ctx)
fmt.Println("Bot stopped")
}
func isCommand(ce *commands.CommandExecutor) func(*models.Update) bool {
return func(update *models.Update) bool {
if update.Message.Text[0] != '/' || len([]rune(update.Message.Text)) < 2 {
return false
}
cmdName := strings.Split(update.Message.Text, " ")[0]
executeFunctionName := "Execute" + strings.ToUpper(string(rune(cmdName[1]))) + cmdName[2:]
cmdValue := reflect.ValueOf(ce).MethodByName(executeFunctionName)
if !cmdValue.IsValid() {
return false
}
return true
}
}
func commandHandler(ce *commands.CommandExecutor, additionalContext *context.Context) func(context.Context, *bot.Bot, *models.Update) {
return func(ctx context.Context, b *bot.Bot, update *models.Update) {
if update.Message.Text[0] != '/' {
return
}
cmdName := strings.Split(update.Message.Text, " ")[0]
executeFunctionName := "Execute" + strings.ToUpper(string(rune(cmdName[1]))) + cmdName[2:]
cmdValue := reflect.ValueOf(ce).MethodByName(executeFunctionName)
if !cmdValue.IsValid() {
return
}
args := []reflect.Value{
reflect.ValueOf(ctx),
reflect.ValueOf(b),
reflect.ValueOf(update),
reflect.ValueOf(additionalContext),
}
go cmdValue.Call(args)
}
}
func handler(additionalContext *context.Context) func(context.Context, *bot.Bot, *models.Update) {
return func(ctx context.Context, b *bot.Bot, update *models.Update) {
// Handler for other messages that are NOT commands
if val, ok := (*additionalContext).Value("user_inputs").(*sync.Map).Load(update.Message.Chat.ID); ok && val != nil {
v, success := (*additionalContext).Value("user_inputs").(*sync.Map).Load(update.Message.Chat.ID)
if success {
v.(*sync.Map).Store("Value", update.Message.Text)
}
}
if update.Message.Text == "yep" {
kb := &models.InlineKeyboardMarkup{
InlineKeyboard: [][]models.InlineKeyboardButton{
{
{Text: "Button 1", CallbackData: "button_1"},
{Text: "Button 2", CallbackData: "button_2"},
}, {
{Text: "Button 3", CallbackData: "button_3"}, },
},
}
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.Message.Chat.ID,
Text: "Click by button",
ReplyMarkup: kb,
})
}
}
}
func keyboardHandler(ctx context.Context, b *bot.Bot, update *models.Update) {
fmt.Println("wassup G?")
b.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{
CallbackQueryID: update.CallbackQuery.ID,
ShowAlert: false,
})
b.SendMessage(ctx, &bot.SendMessageParams{
ChatID: update.CallbackQuery.Message.Message.Chat.ID,
Text: "You selected the button: " + update.CallbackQuery.Data,
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment