2023-08-10 15:49:25 +03:00
|
|
|
package tx
|
2023-07-09 01:28:59 +03:00
|
|
|
|
|
|
|
import (
|
2023-08-12 14:35:33 +03:00
|
|
|
"fmt"
|
|
|
|
|
2023-08-10 15:49:25 +03:00
|
|
|
apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
2023-07-09 01:28:59 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// The wrapper around Telegram API.
|
|
|
|
type Bot struct {
|
|
|
|
*apix.BotAPI
|
|
|
|
*Behaviour
|
|
|
|
sessions SessionMap
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the new bot for running the Behaviour.
|
|
|
|
func NewBot(token string, beh *Behaviour, sessions SessionMap) (*Bot, error) {
|
2023-08-10 15:49:25 +03:00
|
|
|
bot, err := apix.NewBotAPI(token)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make new sessions if no current are provided.
|
|
|
|
if sessions == nil {
|
|
|
|
sessions = make(SessionMap)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Bot{
|
|
|
|
BotAPI: bot,
|
2023-07-09 01:28:59 +03:00
|
|
|
Behaviour: beh,
|
2023-08-10 15:49:25 +03:00
|
|
|
sessions: make(SessionMap),
|
|
|
|
}, nil
|
2023-07-09 01:28:59 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Run the bot with the Behaviour.
|
|
|
|
func (bot *Bot) Run() error {
|
|
|
|
bot.Debug = true
|
2023-07-12 00:33:51 +03:00
|
|
|
uc := apix.NewUpdate(0)
|
2023-07-09 01:28:59 +03:00
|
|
|
uc.Timeout = 60
|
|
|
|
updates := bot.GetUpdatesChan(uc)
|
2023-08-12 14:35:33 +03:00
|
|
|
privateChans := make(map[SessionId]chan *Update)
|
|
|
|
groupChans := make(map[SessionId]chan *Update)
|
2023-07-09 01:28:59 +03:00
|
|
|
for u := range updates {
|
2023-08-12 14:35:33 +03:00
|
|
|
var chatType string
|
2023-08-10 15:49:25 +03:00
|
|
|
|
2023-08-12 14:35:33 +03:00
|
|
|
if u.Message != nil {
|
|
|
|
chatType = u.Message.Chat.Type
|
2023-07-12 14:20:52 +03:00
|
|
|
} else if u.CallbackQuery != nil {
|
2023-08-12 14:35:33 +03:00
|
|
|
chatType = u.Message.Chat.Type
|
2023-07-12 14:20:52 +03:00
|
|
|
}
|
2023-08-12 14:35:33 +03:00
|
|
|
|
|
|
|
switch chatType {
|
|
|
|
case "private":
|
|
|
|
bot.handlePrivate(&u, privateChans)
|
|
|
|
case "group", "supergroup":
|
|
|
|
bot.handleGroup(&u, groupChans)
|
2023-07-12 14:20:52 +03:00
|
|
|
}
|
2023-07-09 01:28:59 +03:00
|
|
|
}
|
2023-08-10 15:49:25 +03:00
|
|
|
|
2023-07-09 01:28:59 +03:00
|
|
|
return nil
|
|
|
|
}
|
2023-08-12 14:35:33 +03:00
|
|
|
|
|
|
|
// The function handles updates supposed for the private
|
|
|
|
// chat with the bot.
|
|
|
|
func (bot *Bot) handlePrivate(u *Update, chans map[SessionId]chan *Update) {
|
|
|
|
var sid SessionId
|
|
|
|
if u.Message != nil {
|
|
|
|
msg := u.Message
|
|
|
|
|
|
|
|
if bot.Debug {
|
|
|
|
fmt.Printf("is command: %q\n", u.Message.IsCommand())
|
|
|
|
fmt.Printf("command itself: %q\n", msg.Command())
|
|
|
|
fmt.Printf("command arguments: %q\n", msg.CommandArguments())
|
|
|
|
fmt.Printf("is to me: %q\n", bot.IsMessageToMe(*msg))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create new session if the one does not exist
|
|
|
|
// for this user.
|
|
|
|
sid = SessionId(u.Message.Chat.ID)
|
|
|
|
if _, ok := bot.sessions[sid]; !ok {
|
|
|
|
bot.sessions.Add(sid)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The "start" command resets the bot
|
|
|
|
// by executing the Start Action.
|
|
|
|
if u.Message.IsCommand() {
|
|
|
|
cmdName := CommandName(u.Message.Command())
|
|
|
|
if cmdName == "start" {
|
|
|
|
// Getting current session and context.
|
|
|
|
session := bot.sessions[sid]
|
|
|
|
ctx := &Context{
|
|
|
|
B: bot,
|
|
|
|
Session: session,
|
|
|
|
updates: make(chan *Update),
|
|
|
|
}
|
|
|
|
|
|
|
|
chn := make(chan *Update)
|
|
|
|
chans[sid] = chn
|
|
|
|
// Starting the goroutine for the user.
|
|
|
|
go ctx.handleUpdateChan(chn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if u.CallbackQuery != nil {
|
|
|
|
sid = SessionId(u.CallbackQuery.Message.Chat.ID)
|
|
|
|
}
|
|
|
|
chn, ok := chans[sid]
|
|
|
|
// The bot MUST get the "start" command.
|
|
|
|
// It will do nothing otherwise.
|
|
|
|
if ok {
|
|
|
|
chn <- u
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Not implemented yet.
|
|
|
|
func (bot *Bot) handleGroup(u *Update, chans map[SessionId]chan *Update) {
|
|
|
|
}
|