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) {
|
||||
// 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
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.
|
||||
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,
|
||||
|
|
29
tg/bot.go
29
tg/bot.go
|
@ -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]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue