Implemented the PreStart handler.

This commit is contained in:
Andrey Parhomenko 2023-09-07 15:45:38 +03:00
parent fc91490c18
commit b2748a8cee
6 changed files with 66 additions and 17 deletions

View file

@ -84,8 +84,10 @@ var beh = tg.NewBehaviour().
WithInitFunc(func(c *tg.Context) {
// The session initialization.
c.Session.Value = &UserData{}
c.ChangeScreen("start")
}). // On any message update before the bot created session.
WithPreStartFunc(func(c *tg.Context){
c.Send("Please, use the /start command to start the bot")
}).WithScreens(
tg.NewScreen("start").
WithText(
@ -141,6 +143,11 @@ var beh = tg.NewBehaviour().
),
),
).WithCommands(
tg.NewCommand("start").
Desc("start the bot").
ActionFunc(func(c *tg.Context){
c.ChangeScreen("start")
}),
tg.NewCommand("hello").
Desc("sends the 'Hello, World!' message back").
ActionFunc(func(c *tg.Context) {

BIN
media/bot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 KiB

View file

@ -5,6 +5,7 @@ package tg
// The type describes behaviour for the bot in personal chats.
type Behaviour struct {
PreStart *action
Init *action
Screens ScreenMap
Keyboards KeyboardMap
@ -27,12 +28,27 @@ func (b *Behaviour) WithInit(a Action) *Behaviour {
return b
}
// Alias to WithInit to simplify behaviour definitions.
func (b *Behaviour) WithInitFunc(
fn ActionFunc,
) *Behaviour {
return b.WithInit(fn)
}
// Defines pre-start action.
// E. g. when the user has not type the "/start" command.
// Mostly used to send the "/start" command back
// with some warning.
func (b *Behaviour) WithPreStart(a Action) *Behaviour {
b.PreStart = newAction(a)
return b
}
// Alias for WithPreStart to be used with function inside.
func (b *Behaviour) WithPreStartFunc(fn ActionFunc) *Behaviour {
return b.WithPreStart(fn)
}
// The function sets screens.
func (b *Behaviour) WithScreens(
screens ...*Screen,

View file

@ -168,6 +168,9 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
session, sessionOk := bot.sessions[sid]
chn, chnOk := chans[sid]
if sessionOk {
// Creating new goroutine for
// the session that exists
// but has none.
if !chnOk {
ctx := &context{
Bot: bot,
@ -178,21 +181,19 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
chans[sid] = chn
go ctx.handleUpdateChan(chn)
}
} else {
if u.Message != nil && u.Message.Command() == "start" {
if !sessionOk {
bot.sessions.Add(sid)
}
lsession := bot.sessions[sid]
ctx := &context{
Bot: bot,
Session: lsession,
updates: make(chan *Update),
}
chn := make(chan *Update)
chans[sid] = chn
go ctx.handleUpdateChan(chn)
} else if u.Message != nil {
// Create session on any message
// if we have no one.
bot.sessions.Add(sid)
lsession := bot.sessions[sid]
ctx := &context{
Bot: bot,
Session: lsession,
updates: make(chan *Update),
}
chn := make(chan *Update)
chans[sid] = chn
go ctx.handleUpdateChan(chn)
}
chn, ok := chans[sid]

View file

@ -23,6 +23,8 @@ type context struct {
func (c *context) handleUpdateChan(updates chan *Update) {
beh := c.Bot.behaviour
session := c.Session
preStart := beh.PreStart
if beh.Init != nil {
c.run(beh.Init, nil)
}
@ -31,14 +33,34 @@ func (c *context) handleUpdateChan(updates chan *Update) {
screen := c.curScreen
// The part is added to implement custom update handling.
if u.Message != nil {
if u.Message.IsCommand() && !c.readingUpdate {
if !session.Started {
if u.Message.IsCommand() &&
u.Message.Command() == "start" {
// Special treatment for the "/start"
// command.
session.Started = true
cmdName := CommandName("start")
cmd, ok := beh.Commands[cmdName]
if ok {
act = cmd.Action
} else {
// Some usage.
}
} else {
// Prestart handling.
act = preStart
}
} else if u.Message.IsCommand() {
// Command handling.
cmdName := CommandName(u.Message.Command())
cmd, ok := beh.Commands[cmdName]
if ok {
act = cmd.Action
} else {
// Some usage.
}
} else {
// Simple messages handling.
kbd := screen.Keyboard
if kbd == nil {
if c.readingUpdate {
@ -69,7 +91,7 @@ func (c *context) handleUpdateChan(updates chan *Update) {
act = btn.Action
}
}
} else if u.CallbackQuery != nil {
} else if u.CallbackQuery != nil && session.Started {
cb := tgbotapi.NewCallback(
u.CallbackQuery.ID,
u.CallbackQuery.Data,

View file

@ -14,6 +14,9 @@ func (si SessionId) ToApi() int64 {
type Session struct {
// Id of the chat of the user.
Id SessionId
// True if the session started.
// (got the '/start' command.
Started bool
// Custom value for each user.
Value any
}