Finally implemented JSON-ing of behaviours.
This commit is contained in:
parent
772adb7b8b
commit
94d8c38dd5
14 changed files with 257 additions and 143 deletions
109
cmd/json/main.go
109
cmd/json/main.go
|
@ -18,9 +18,18 @@ type UserData struct {
|
||||||
Counter int
|
Counter int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Code string
|
type Code struct {
|
||||||
|
Code string
|
||||||
|
Add int
|
||||||
|
}
|
||||||
|
|
||||||
func (c Code) Act(a *tx.A) {
|
func NewCode(code string) *Code {
|
||||||
|
return &Code{
|
||||||
|
Code: code,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Code) Act(a *tx.A) {
|
||||||
var err error
|
var err error
|
||||||
fmt.Println("In Act")
|
fmt.Println("In Act")
|
||||||
e := env.NewEnv()
|
e := env.NewEnv()
|
||||||
|
@ -32,52 +41,46 @@ func (c Code) Act(a *tx.A) {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = vm.Execute(e, nil, string(c))
|
_, err = vm.Execute(e, nil, c.Code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var startScreenButton = tx.NewButton("🏠 To the start screen").
|
func main() {
|
||||||
WithAction(Code(`
|
tx.DefineAction("goscript", &Code{})
|
||||||
|
|
||||||
|
var startScreenButton = tx.NewButton("🏠 To the start screen").
|
||||||
|
WithAction(NewCode(`
|
||||||
a.ChangeScreen("start")
|
a.ChangeScreen("start")
|
||||||
`))
|
`))
|
||||||
|
|
||||||
var beh = tx.NewBehaviour().
|
var (
|
||||||
|
incDecKeyboard = tx.NewKeyboard("").Row(
|
||||||
// The function will be called every time
|
tx.NewButton("+").WithAction(NewCode(`
|
||||||
// the bot is started.
|
|
||||||
WithStart(Code(`
|
|
||||||
a.V = new(UserData)
|
|
||||||
a.ChangeScreen("start")
|
|
||||||
`)).WithKeyboards(
|
|
||||||
|
|
||||||
// Increment/decrement keyboard.
|
|
||||||
tx.NewKeyboard("inc/dec").Row(
|
|
||||||
tx.NewButton("+").WithAction(Code(`
|
|
||||||
d = a.V
|
d = a.V
|
||||||
d.Counter++
|
d.Counter++
|
||||||
a.Sendf("%d", d.Counter)
|
a.Sendf("%d", d.Counter)
|
||||||
`)),
|
`)),
|
||||||
tx.NewButton("-").WithAction(Code(`
|
tx.NewButton("-").WithAction(NewCode(`
|
||||||
d = a.V
|
d = a.V
|
||||||
d.Counter--
|
d.Counter--
|
||||||
a.Sendf("%d", d.Counter)
|
a.Sendf("%d", d.Counter)
|
||||||
`)),
|
`)),
|
||||||
).Row(
|
).Row(
|
||||||
startScreenButton,
|
startScreenButton,
|
||||||
),
|
)
|
||||||
|
|
||||||
// The navigational keyboard.
|
// The navigational keyboard.
|
||||||
tx.NewKeyboard("nav").Row(
|
navKeyboard = tx.NewKeyboard("").Row(
|
||||||
tx.NewButton("Inc/Dec").WithAction(Code(`a.ChangeScreen("inc/dec")`)),
|
tx.NewButton("Inc/Dec").WithAction(NewCode(`a.ChangeScreen("inc/dec")`)),
|
||||||
).Row(
|
).Row(
|
||||||
tx.NewButton("Upper case").WithAction(Code(`a.ChangeScreen("upper-case")`)),
|
tx.NewButton("Upper case").WithAction(NewCode(`a.ChangeScreen("upper-case")`)),
|
||||||
tx.NewButton("Lower case").WithAction(Code(`a.ChangeScreen("lower-case")`)),
|
tx.NewButton("Lower case").WithAction(NewCode(`a.ChangeScreen("lower-case")`)),
|
||||||
).Row(
|
).Row(
|
||||||
tx.NewButton("Send location").
|
tx.NewButton("Send location").
|
||||||
WithSendLocation(true).
|
WithSendLocation(true).
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
err = nil
|
err = nil
|
||||||
if a.U.Message.Location != nil {
|
if a.U.Message.Location != nil {
|
||||||
l = a.U.Message.Location
|
l = a.U.Message.Location
|
||||||
|
@ -89,18 +92,25 @@ var beh = tx.NewBehaviour().
|
||||||
a.Send(err)
|
a.Send(err)
|
||||||
}
|
}
|
||||||
`)),
|
`)),
|
||||||
),
|
)
|
||||||
|
|
||||||
tx.NewKeyboard("istart").Row(
|
inlineKeyboard = tx.NewKeyboard("").Row(
|
||||||
tx.NewButton("My Telegram").
|
tx.NewButton("My Telegram").
|
||||||
WithUrl("https://t.me/surdeus"),
|
WithUrl("https://t.me/surdeus"),
|
||||||
),
|
)
|
||||||
|
|
||||||
// The keyboard to return to the start screen.
|
// The keyboard to return to the start screen.
|
||||||
tx.NewKeyboard("nav-start").Row(
|
navToStartKeyboard = tx.NewKeyboard("nav-start").Row(
|
||||||
startScreenButton,
|
startScreenButton,
|
||||||
),
|
)
|
||||||
).WithScreens(
|
)
|
||||||
|
var beh = tx.NewBehaviour().
|
||||||
|
// The function will be called every time
|
||||||
|
// the bot is started.
|
||||||
|
WithInit(NewCode(`
|
||||||
|
a.V = new(UserData)
|
||||||
|
`)).
|
||||||
|
WithScreens(
|
||||||
tx.NewScreen("start").
|
tx.NewScreen("start").
|
||||||
WithText(
|
WithText(
|
||||||
"The bot started!"+
|
"The bot started!"+
|
||||||
|
@ -108,8 +118,8 @@ var beh = tx.NewBehaviour().
|
||||||
" understand of how the API works, so just"+
|
" understand of how the API works, so just"+
|
||||||
" horse around a bit to guess everything out"+
|
" horse around a bit to guess everything out"+
|
||||||
" by yourself!",
|
" by yourself!",
|
||||||
).Keyboard("nav").
|
).WithKeyboard(navKeyboard).
|
||||||
IKeyboard("istart"),
|
WithIKeyboard(inlineKeyboard),
|
||||||
|
|
||||||
tx.NewScreen("inc/dec").
|
tx.NewScreen("inc/dec").
|
||||||
WithText(
|
WithText(
|
||||||
|
@ -118,17 +128,17 @@ var beh = tx.NewBehaviour().
|
||||||
"by saving the counter for each of users "+
|
"by saving the counter for each of users "+
|
||||||
"separately. ",
|
"separately. ",
|
||||||
).
|
).
|
||||||
Keyboard("inc/dec").
|
WithKeyboard(incDecKeyboard).
|
||||||
// The function will be called when reaching the screen.
|
// The function will be called when reaching the screen.
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
d = a.V
|
d = a.V
|
||||||
a.Sendf("Current counter value = %d", d.Counter)
|
a.Sendf("Current counter value = %d", d.Counter)
|
||||||
`)),
|
`)),
|
||||||
|
|
||||||
tx.NewScreen("upper-case").
|
tx.NewScreen("upper-case").
|
||||||
WithText("Type text and the bot will send you the upper case version to you").
|
WithText("Type text and the bot will send you the upper case version to you").
|
||||||
Keyboard("nav-start").
|
WithKeyboard(navToStartKeyboard).
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
strings = import("strings")
|
strings = import("strings")
|
||||||
for {
|
for {
|
||||||
msg, err = a.ReadTextMessage()
|
msg, err = a.ReadTextMessage()
|
||||||
|
@ -147,8 +157,8 @@ var beh = tx.NewBehaviour().
|
||||||
|
|
||||||
tx.NewScreen("lower-case").
|
tx.NewScreen("lower-case").
|
||||||
WithText("Type text and the bot will send you the lower case version").
|
WithText("Type text and the bot will send you the lower case version").
|
||||||
Keyboard("nav-start").
|
WithKeyboard(navToStartKeyboard).
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
strings = import("strings")
|
strings = import("strings")
|
||||||
for {
|
for {
|
||||||
msg, err = a.ReadTextMessage()
|
msg, err = a.ReadTextMessage()
|
||||||
|
@ -164,15 +174,20 @@ var beh = tx.NewBehaviour().
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`)),
|
`)),
|
||||||
).WithCommands(
|
).WithCommands(
|
||||||
|
tx.NewCommand("start").
|
||||||
|
Desc("start or restart the bot").
|
||||||
|
WithAction(NewCode(`
|
||||||
|
a.ChangeScreen("start")
|
||||||
|
`)),
|
||||||
tx.NewCommand("hello").
|
tx.NewCommand("hello").
|
||||||
Desc("sends the 'Hello, World!' message back").
|
Desc("sends the 'Hello, World!' message back").
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
a.Send("Hello, World!")
|
a.Send("Hello, World!")
|
||||||
`)),
|
`)),
|
||||||
tx.NewCommand("read").
|
tx.NewCommand("read").
|
||||||
Desc("reads a string and sends it back").
|
Desc("reads a string and sends it back").
|
||||||
WithAction(Code(`
|
WithAction(NewCode(`
|
||||||
a.Send("Type some text:")
|
a.Send("Type some text:")
|
||||||
msg, err = a.ReadTextMessage()
|
msg, err = a.ReadTextMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -180,26 +195,26 @@ var beh = tx.NewBehaviour().
|
||||||
}
|
}
|
||||||
a.Sendf("You typed %q", msg)
|
a.Sendf("You typed %q", msg)
|
||||||
`)),
|
`)),
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
|
||||||
bts, err := json.MarshalIndent(beh, "", "\t")
|
bts, err := json.MarshalIndent(beh, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%s", bts)
|
fmt.Printf("%s", bts)
|
||||||
|
|
||||||
/*jBeh := &tx.Behaviour{}
|
jBeh := &tx.Behaviour{}
|
||||||
err = json.Unmarshal(bts, jBeh)
|
err = json.Unmarshal(bts, jBeh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}*/
|
}
|
||||||
|
|
||||||
bot, err := tx.NewBot(os.Getenv("BOT_TOKEN"), beh, nil)
|
bot, err := tx.NewBot(os.Getenv("BOT_TOKEN"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bot = bot.WithBehaviour(jBeh)
|
||||||
|
|
||||||
err = bot.Run()
|
err = bot.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
5
cmd/json/mkfile
Normal file
5
cmd/json/mkfile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
all:
|
||||||
|
go build
|
||||||
|
|
||||||
|
run:V:
|
||||||
|
./jsoned
|
|
@ -77,11 +77,11 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
var beh = tx.NewBehaviour().
|
var beh = tx.NewBehaviour().
|
||||||
OnStartFunc(func(c *tx.A) {
|
WithInitFunc(func(c *tx.A) {
|
||||||
// The function will be called every time
|
// The session initialization.
|
||||||
// the bot is started.
|
|
||||||
c.V = &UserData{}
|
c.V = &UserData{}
|
||||||
c.ChangeScreen("start")
|
c.ChangeScreen("start")
|
||||||
|
|
||||||
}).WithScreens(
|
}).WithScreens(
|
||||||
tx.NewScreen("start").
|
tx.NewScreen("start").
|
||||||
WithText(
|
WithText(
|
||||||
|
|
|
@ -1,17 +1,43 @@
|
||||||
package tx
|
package tx
|
||||||
|
|
||||||
//apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Jsonable Action.
|
||||||
|
type action struct {
|
||||||
|
Type string
|
||||||
|
Action Action
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAction(a Action) *action {
|
||||||
|
typ, ok := actionMapByReflect[reflect.TypeOf(a)]
|
||||||
|
if !ok {
|
||||||
|
panic(ActionNotDefinedErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &action{
|
||||||
|
Type: typ,
|
||||||
|
Action: a,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *action) Act(arg *A) {
|
||||||
|
if a.Action != nil {
|
||||||
|
a.Action.Act(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customized actions for the bot.
|
||||||
type Action interface {
|
type Action interface {
|
||||||
Act(*Arg)
|
Act(*Arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Customized actions for the
|
||||||
type GroupAction interface {
|
type GroupAction interface {
|
||||||
Act(*GroupArg)
|
Act(*GroupArg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Customized actions for the bot.
|
|
||||||
|
|
||||||
type ActionFunc func(*Arg)
|
type ActionFunc func(*Arg)
|
||||||
|
|
||||||
func (af ActionFunc) Act(a *Arg) {
|
func (af ActionFunc) Act(a *Arg) {
|
||||||
|
@ -99,12 +125,3 @@ type ChannelAction struct {
|
||||||
type JsonTyper interface {
|
type JsonTyper interface {
|
||||||
JsonType() string
|
JsonType() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type JsonAction struct {
|
|
||||||
Type string
|
|
||||||
Action Action
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ja JsonAction) UnmarshalJSON(bts []byte, ptr any) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ package tx
|
||||||
|
|
||||||
// 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 {
|
||||||
Start Action
|
Init *action
|
||||||
Screens ScreenMap
|
Screens ScreenMap
|
||||||
Keyboards KeyboardMap
|
Keyboards KeyboardMap
|
||||||
Commands CommandMap
|
Commands CommandMap
|
||||||
|
@ -20,15 +20,17 @@ func NewBehaviour() *Behaviour {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Behaviour) WithStart(a Action) *Behaviour {
|
// The Action will be called on session creation,
|
||||||
b.Start = a
|
// not when starting or restarting the bot with the Start Action.
|
||||||
|
func (b *Behaviour) WithInit(a Action) *Behaviour {
|
||||||
|
b.Init = newAction(a)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Behaviour) OnStartFunc(
|
func (b *Behaviour) WithInitFunc(
|
||||||
fn ActionFunc,
|
fn ActionFunc,
|
||||||
) *Behaviour {
|
) *Behaviour {
|
||||||
return b.WithStart(fn)
|
return b.WithInit(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The function sets screens.
|
// The function sets screens.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package tx
|
package tx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
//"fmt"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
apix "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
@ -119,20 +117,21 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
||||||
chans := make(map[SessionId]chan *Update)
|
chans := make(map[SessionId]chan *Update)
|
||||||
var sid SessionId
|
var sid SessionId
|
||||||
for u := range updates {
|
for u := range updates {
|
||||||
if u.Message != nil {
|
sid = SessionId(u.FromChat().ID)
|
||||||
|
var sessionOk, chnOk bool
|
||||||
// Create new session if the one does not exist
|
// Create new session if the one does not exist
|
||||||
// for this user.
|
// for this user.
|
||||||
sid = SessionId(u.Message.Chat.ID)
|
if _, sessionOk = bot.sessions[sid]; !sessionOk {
|
||||||
if _, ok := bot.sessions[sid]; !ok {
|
|
||||||
bot.sessions.Add(sid)
|
bot.sessions.Add(sid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The "start" command resets the bot
|
_, chnOk = chans[sid]
|
||||||
// by executing the Start Action.
|
// Making the bot ignore anything except "start"
|
||||||
if u.Message.IsCommand() {
|
// before the session started
|
||||||
|
if u.Message.IsCommand() &&
|
||||||
|
(!sessionOk) {
|
||||||
cmdName := CommandName(u.Message.Command())
|
cmdName := CommandName(u.Message.Command())
|
||||||
if cmdName == "start" {
|
if cmdName == "start" {
|
||||||
// Getting current session and context.
|
|
||||||
session := bot.sessions[sid]
|
session := bot.sessions[sid]
|
||||||
ctx := &Context{
|
ctx := &Context{
|
||||||
B: bot,
|
B: bot,
|
||||||
|
@ -140,14 +139,14 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
||||||
updates: make(chan *Update),
|
updates: make(chan *Update),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Starting the new goroutine if
|
||||||
|
// there is no one.
|
||||||
|
if !chnOk {
|
||||||
chn := make(chan *Update)
|
chn := make(chan *Update)
|
||||||
chans[sid] = chn
|
chans[sid] = chn
|
||||||
// Starting the goroutine for the user.
|
|
||||||
go ctx.handleUpdateChan(chn)
|
go ctx.handleUpdateChan(chn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if u.CallbackQuery != nil {
|
|
||||||
sid = SessionId(u.CallbackQuery.Message.Chat.ID)
|
|
||||||
}
|
}
|
||||||
chn, ok := chans[sid]
|
chn, ok := chans[sid]
|
||||||
// The bot MUST get the "start" command.
|
// The bot MUST get the "start" command.
|
||||||
|
|
|
@ -10,7 +10,7 @@ type Button struct {
|
||||||
Data string
|
Data string
|
||||||
Url string
|
Url string
|
||||||
SendLocation bool
|
SendLocation bool
|
||||||
Action Action
|
Action *action
|
||||||
}
|
}
|
||||||
|
|
||||||
type ButtonMap map[string]*Button
|
type ButtonMap map[string]*Button
|
||||||
|
@ -34,7 +34,7 @@ func (btn *Button) WithUrl(url string) *Button {
|
||||||
// Set the action when pressing the button.
|
// Set the action when pressing the button.
|
||||||
// By default is nil and does nothing.
|
// By default is nil and does nothing.
|
||||||
func (btn *Button) WithAction(a Action) *Button {
|
func (btn *Button) WithAction(a Action) *Button {
|
||||||
btn.Action = a
|
btn.Action = newAction(a)
|
||||||
return btn
|
return btn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ type CommandName string
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Name CommandName
|
Name CommandName
|
||||||
Description string
|
Description string
|
||||||
Action Action
|
Action *action
|
||||||
}
|
}
|
||||||
type CommandMap map[CommandName]*Command
|
type CommandMap map[CommandName]*Command
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ func NewCommand(name CommandName) *Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Command) WithAction(a Action) *Command {
|
func (c *Command) WithAction(a Action) *Command {
|
||||||
c.Action = a
|
c.Action = newAction(a)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,10 @@ func (c *Context) handleUpdateChan(updates chan *Update) {
|
||||||
var act Action
|
var act Action
|
||||||
bot := c.B
|
bot := c.B
|
||||||
beh := bot.behaviour
|
beh := bot.behaviour
|
||||||
c.run(beh.Start, nil)
|
|
||||||
|
if beh.Init != nil {
|
||||||
|
c.run(beh.Init, nil)
|
||||||
|
}
|
||||||
for u := range updates {
|
for u := range updates {
|
||||||
screen := c.curScreen
|
screen := c.curScreen
|
||||||
// The part is added to implement custom update handling.
|
// The part is added to implement custom update handling.
|
||||||
|
|
37
src/tx/encoding.go
Normal file
37
src/tx/encoding.go
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package tx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
actionMapByReflect = make(map[reflect.Type]string)
|
||||||
|
actionMapByTypeName = make(map[string]reflect.Type)
|
||||||
|
Init func()
|
||||||
|
)
|
||||||
|
|
||||||
|
func initEncoding() {
|
||||||
|
actions := map[string]Action{
|
||||||
|
"action-func": ActionFunc(nil),
|
||||||
|
"screen-change": ScreenChange(""),
|
||||||
|
}
|
||||||
|
for k, action := range actions {
|
||||||
|
DefineAction(k, action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define interface to make it marshalable to JSON etc.
|
||||||
|
// Like in GOB. Must be done both on client and server
|
||||||
|
// if one is provided.
|
||||||
|
func DefineAction(typeName string, a Action) error {
|
||||||
|
t := reflect.TypeOf(a)
|
||||||
|
|
||||||
|
actionMapByReflect[t] = typeName
|
||||||
|
actionMapByTypeName[typeName] = t
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefineGroupAction(typ string, a GroupAction) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ var (
|
||||||
KeyboardNotExistErr = errors.New("keyboard does not exist")
|
KeyboardNotExistErr = errors.New("keyboard does not exist")
|
||||||
NotAvailableErr = errors.New("the context is not available")
|
NotAvailableErr = errors.New("the context is not available")
|
||||||
EmptyKeyboardTextErr = errors.New("got empty text for a keyboard")
|
EmptyKeyboardTextErr = errors.New("got empty text for a keyboard")
|
||||||
|
ActionNotDefinedErr = errors.New("action was not defined")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (wut WrongUpdateType) Error() string {
|
func (wut WrongUpdateType) Error() string {
|
||||||
|
|
34
src/tx/json.go
Normal file
34
src/tx/json.go
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package tx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (a *action) UnmarshalJSON(data []byte) error {
|
||||||
|
var err error
|
||||||
|
m := make(map[string]any)
|
||||||
|
err = json.Unmarshal(data, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bts, err := json.Marshal(m["Action"])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Type = m["Type"].(string)
|
||||||
|
typ := actionMapByTypeName[a.Type].(reflect.Type)
|
||||||
|
if typ.Kind() == reflect.Pointer {
|
||||||
|
typ = typ.Elem()
|
||||||
|
}
|
||||||
|
vr := reflect.New(typ).Interface().(Action)
|
||||||
|
err = json.Unmarshal(bts, vr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Action = vr
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
package tx
|
package tx
|
||||||
|
|
||||||
// The package implements behaviourial
|
func init() {
|
||||||
// definition for the Telegram bots through the API.
|
initEncoding()
|
||||||
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ type Screen struct {
|
||||||
// Keyboard to be displayed on the screen.
|
// Keyboard to be displayed on the screen.
|
||||||
Keyboard *Keyboard
|
Keyboard *Keyboard
|
||||||
// Action called on the reaching the screen.
|
// Action called on the reaching the screen.
|
||||||
Action Action
|
Action *action
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map structure for the screens.
|
// Map structure for the screens.
|
||||||
|
@ -53,7 +53,7 @@ func (s *Screen) WithKeyboard(kbd *Keyboard) *Screen {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Screen) WithAction(a Action) *Screen {
|
func (s *Screen) WithAction(a Action) *Screen {
|
||||||
s.Action = a
|
s.Action = newAction(a)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue