Implemented the PreStart handler.
This commit is contained in:
parent
fc91490c18
commit
b2748a8cee
6 changed files with 66 additions and 17 deletions
|
@ -84,8 +84,10 @@ var beh = tg.NewBehaviour().
|
||||||
WithInitFunc(func(c *tg.Context) {
|
WithInitFunc(func(c *tg.Context) {
|
||||||
// The session initialization.
|
// The session initialization.
|
||||||
c.Session.Value = &UserData{}
|
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(
|
}).WithScreens(
|
||||||
tg.NewScreen("start").
|
tg.NewScreen("start").
|
||||||
WithText(
|
WithText(
|
||||||
|
@ -141,6 +143,11 @@ var beh = tg.NewBehaviour().
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
).WithCommands(
|
).WithCommands(
|
||||||
|
tg.NewCommand("start").
|
||||||
|
Desc("start the bot").
|
||||||
|
ActionFunc(func(c *tg.Context){
|
||||||
|
c.ChangeScreen("start")
|
||||||
|
}),
|
||||||
tg.NewCommand("hello").
|
tg.NewCommand("hello").
|
||||||
Desc("sends the 'Hello, World!' message back").
|
Desc("sends the 'Hello, World!' message back").
|
||||||
ActionFunc(func(c *tg.Context) {
|
ActionFunc(func(c *tg.Context) {
|
||||||
|
|
BIN
media/bot.png
Normal file
BIN
media/bot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 723 KiB |
16
tg/beh.go
16
tg/beh.go
|
@ -5,6 +5,7 @@ package tg
|
||||||
|
|
||||||
// The type describes behaviour for the bot in personal chats.
|
// The type describes behaviour for the bot in personal chats.
|
||||||
type Behaviour struct {
|
type Behaviour struct {
|
||||||
|
PreStart *action
|
||||||
Init *action
|
Init *action
|
||||||
Screens ScreenMap
|
Screens ScreenMap
|
||||||
Keyboards KeyboardMap
|
Keyboards KeyboardMap
|
||||||
|
@ -27,12 +28,27 @@ func (b *Behaviour) WithInit(a Action) *Behaviour {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alias to WithInit to simplify behaviour definitions.
|
||||||
func (b *Behaviour) WithInitFunc(
|
func (b *Behaviour) WithInitFunc(
|
||||||
fn ActionFunc,
|
fn ActionFunc,
|
||||||
) *Behaviour {
|
) *Behaviour {
|
||||||
return b.WithInit(fn)
|
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.
|
// The function sets screens.
|
||||||
func (b *Behaviour) WithScreens(
|
func (b *Behaviour) WithScreens(
|
||||||
screens ...*Screen,
|
screens ...*Screen,
|
||||||
|
|
29
tg/bot.go
29
tg/bot.go
|
@ -168,6 +168,9 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
||||||
session, sessionOk := bot.sessions[sid]
|
session, sessionOk := bot.sessions[sid]
|
||||||
chn, chnOk := chans[sid]
|
chn, chnOk := chans[sid]
|
||||||
if sessionOk {
|
if sessionOk {
|
||||||
|
// Creating new goroutine for
|
||||||
|
// the session that exists
|
||||||
|
// but has none.
|
||||||
if !chnOk {
|
if !chnOk {
|
||||||
ctx := &context{
|
ctx := &context{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
|
@ -178,21 +181,19 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
||||||
chans[sid] = chn
|
chans[sid] = chn
|
||||||
go ctx.handleUpdateChan(chn)
|
go ctx.handleUpdateChan(chn)
|
||||||
}
|
}
|
||||||
} else {
|
} else if u.Message != nil {
|
||||||
if u.Message != nil && u.Message.Command() == "start" {
|
// Create session on any message
|
||||||
if !sessionOk {
|
// if we have no one.
|
||||||
bot.sessions.Add(sid)
|
bot.sessions.Add(sid)
|
||||||
}
|
lsession := bot.sessions[sid]
|
||||||
lsession := bot.sessions[sid]
|
ctx := &context{
|
||||||
ctx := &context{
|
Bot: bot,
|
||||||
Bot: bot,
|
Session: lsession,
|
||||||
Session: lsession,
|
updates: make(chan *Update),
|
||||||
updates: make(chan *Update),
|
|
||||||
}
|
|
||||||
chn := make(chan *Update)
|
|
||||||
chans[sid] = chn
|
|
||||||
go ctx.handleUpdateChan(chn)
|
|
||||||
}
|
}
|
||||||
|
chn := make(chan *Update)
|
||||||
|
chans[sid] = chn
|
||||||
|
go ctx.handleUpdateChan(chn)
|
||||||
}
|
}
|
||||||
|
|
||||||
chn, ok := chans[sid]
|
chn, ok := chans[sid]
|
||||||
|
|
|
@ -23,6 +23,8 @@ type context struct {
|
||||||
func (c *context) handleUpdateChan(updates chan *Update) {
|
func (c *context) handleUpdateChan(updates chan *Update) {
|
||||||
beh := c.Bot.behaviour
|
beh := c.Bot.behaviour
|
||||||
|
|
||||||
|
session := c.Session
|
||||||
|
preStart := beh.PreStart
|
||||||
if beh.Init != nil {
|
if beh.Init != nil {
|
||||||
c.run(beh.Init, nil)
|
c.run(beh.Init, nil)
|
||||||
}
|
}
|
||||||
|
@ -31,14 +33,34 @@ func (c *context) handleUpdateChan(updates chan *Update) {
|
||||||
screen := c.curScreen
|
screen := c.curScreen
|
||||||
// The part is added to implement custom update handling.
|
// The part is added to implement custom update handling.
|
||||||
if u.Message != nil {
|
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())
|
cmdName := CommandName(u.Message.Command())
|
||||||
cmd, ok := beh.Commands[cmdName]
|
cmd, ok := beh.Commands[cmdName]
|
||||||
if ok {
|
if ok {
|
||||||
act = cmd.Action
|
act = cmd.Action
|
||||||
} else {
|
} else {
|
||||||
|
// Some usage.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Simple messages handling.
|
||||||
kbd := screen.Keyboard
|
kbd := screen.Keyboard
|
||||||
if kbd == nil {
|
if kbd == nil {
|
||||||
if c.readingUpdate {
|
if c.readingUpdate {
|
||||||
|
@ -69,7 +91,7 @@ func (c *context) handleUpdateChan(updates chan *Update) {
|
||||||
act = btn.Action
|
act = btn.Action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if u.CallbackQuery != nil {
|
} else if u.CallbackQuery != nil && session.Started {
|
||||||
cb := tgbotapi.NewCallback(
|
cb := tgbotapi.NewCallback(
|
||||||
u.CallbackQuery.ID,
|
u.CallbackQuery.ID,
|
||||||
u.CallbackQuery.Data,
|
u.CallbackQuery.Data,
|
||||||
|
|
|
@ -14,6 +14,9 @@ func (si SessionId) ToApi() int64 {
|
||||||
type Session struct {
|
type Session struct {
|
||||||
// Id of the chat of the user.
|
// Id of the chat of the user.
|
||||||
Id SessionId
|
Id SessionId
|
||||||
|
// True if the session started.
|
||||||
|
// (got the '/start' command.
|
||||||
|
Started bool
|
||||||
// Custom value for each user.
|
// Custom value for each user.
|
||||||
Value any
|
Value any
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue