Skip to content

Instantly share code, notes, and snippets.

@negasus
Created May 4, 2024 09:33
Show Gist options
  • Save negasus/010aa334d857201a1fbea7e2f83e87b7 to your computer and use it in GitHub Desktop.
Save negasus/010aa334d857201a1fbea7e2f83e87b7 to your computer and use it in GitHub Desktop.
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(os.Getenv("EXAMPLE_TELEGRAM_BOT_TOKEN"), opts...)
if err != nil {
panic(err)
}
b.RegisterHandlerMatchFunc(isCommand(nil), commandHandler(nil, &additionalContext))
fmt.Println("Bot started")
b.Start(ctx)
fmt.Println("Bot stopped")
}
func isCommand(ce any) 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 any, 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