2023-08-19 09:12:26 +03:00
|
|
|
package tg
|
2023-08-12 14:35:33 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
//"flag"
|
|
|
|
|
2023-09-11 13:00:38 +03:00
|
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
2023-08-12 14:35:33 +03:00
|
|
|
)
|
|
|
|
|
2023-09-11 13:00:38 +03:00
|
|
|
type BotCommander interface {
|
|
|
|
ToApi() tgbotapi.BotCommand
|
|
|
|
}
|
|
|
|
type Message = tgbotapi.Message
|
2023-08-12 14:35:33 +03:00
|
|
|
type CommandName string
|
|
|
|
|
|
|
|
type Command struct {
|
|
|
|
Name CommandName
|
|
|
|
Description string
|
2023-09-21 20:32:24 +03:00
|
|
|
Action Action
|
2023-09-11 13:37:04 +03:00
|
|
|
Widget Widget
|
2023-08-12 14:35:33 +03:00
|
|
|
}
|
2023-08-13 15:37:36 +03:00
|
|
|
type CommandMap map[CommandName]*Command
|
2023-08-12 14:35:33 +03:00
|
|
|
|
|
|
|
func NewCommand(name CommandName) *Command {
|
|
|
|
return &Command{
|
|
|
|
Name: name,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) WithAction(a Action) *Command {
|
2023-09-21 20:32:24 +03:00
|
|
|
c.Action = a
|
2023-08-12 14:35:33 +03:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Command) ActionFunc(af ActionFunc) *Command {
|
|
|
|
return c.WithAction(af)
|
|
|
|
}
|
|
|
|
|
2023-09-11 13:37:04 +03:00
|
|
|
func (c *Command) WithWidget(w Widget) *Command {
|
|
|
|
c.Widget = w
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-09-26 17:13:31 +03:00
|
|
|
func (c *Command) WidgetFunc(fn Func) *Command {
|
2023-09-11 13:37:04 +03:00
|
|
|
return c.WithWidget(fn)
|
|
|
|
}
|
|
|
|
|
2023-09-11 13:00:38 +03:00
|
|
|
func (c *Command) ToApi() tgbotapi.BotCommand {
|
|
|
|
ret := tgbotapi.BotCommand{}
|
|
|
|
ret.Command = string(c.Name)
|
|
|
|
ret.Description = c.Description
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
2023-08-12 14:35:33 +03:00
|
|
|
func (c *Command) Desc(desc string) *Command {
|
|
|
|
c.Description = desc
|
|
|
|
return c
|
|
|
|
}
|
2023-08-13 15:37:36 +03:00
|
|
|
|
2023-09-21 15:28:06 +03:00
|
|
|
func (c *Command) Go(pth Path, args ...any) *Command {
|
|
|
|
return c.WithAction(ScreenGo{
|
|
|
|
Path: pth,
|
|
|
|
Args: args,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-08-13 15:37:36 +03:00
|
|
|
type GroupCommand struct {
|
|
|
|
Name CommandName
|
|
|
|
Description string
|
|
|
|
Action GroupAction
|
|
|
|
}
|
|
|
|
type GroupCommandMap map[CommandName]*GroupCommand
|
|
|
|
|
|
|
|
func NewGroupCommand(name CommandName) *GroupCommand {
|
|
|
|
return &GroupCommand{
|
|
|
|
Name: name,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *GroupCommand) WithAction(a GroupAction) *GroupCommand {
|
|
|
|
cmd.Action = a
|
|
|
|
return cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func (cmd *GroupCommand) ActionFunc(fn GroupActionFunc) *GroupCommand {
|
|
|
|
return cmd.WithAction(fn)
|
|
|
|
}
|
|
|
|
|
2023-09-21 15:28:06 +03:00
|
|
|
|
2023-08-13 15:37:36 +03:00
|
|
|
func (cmd *GroupCommand) Desc(desc string) *GroupCommand {
|
|
|
|
cmd.Description = desc
|
|
|
|
return cmd
|
|
|
|
}
|
2023-09-11 13:00:38 +03:00
|
|
|
|
|
|
|
func (c *GroupCommand) ToApi() tgbotapi.BotCommand {
|
|
|
|
ret := tgbotapi.BotCommand{}
|
|
|
|
ret.Command = string(c.Name)
|
|
|
|
ret.Description = c.Description
|
|
|
|
return ret
|
|
|
|
}
|
2023-09-11 15:58:45 +03:00
|
|
|
|
|
|
|
// The type is used to recognize commands and execute
|
|
|
|
// its actions and widgets .
|
|
|
|
type CommandWidget struct {
|
|
|
|
PreStart Action
|
|
|
|
Commands CommandMap
|
|
|
|
Usage Action
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns new empty CommandWidget.
|
|
|
|
func NewCommandWidget() *CommandWidget {
|
|
|
|
ret := &CommandWidget{}
|
|
|
|
ret.Commands = make(CommandMap)
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the commands to handle.
|
|
|
|
func (w *CommandWidget) WithCommands(cmds ...*Command) *CommandWidget {
|
|
|
|
for _, cmd := range cmds {
|
|
|
|
if cmd.Name == "" {
|
|
|
|
panic("empty command name")
|
|
|
|
}
|
|
|
|
_, ok := w.Commands[cmd.Name]
|
|
|
|
if ok {
|
|
|
|
panic("duplicate command definition")
|
|
|
|
}
|
|
|
|
w.Commands[cmd.Name] = cmd
|
|
|
|
}
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the prestart action.
|
|
|
|
func (w *CommandWidget) WithPreStart(a Action) *CommandWidget {
|
|
|
|
w.PreStart = a
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the prestart action with function.
|
|
|
|
func (w *CommandWidget) WithPreStartFunc(fn ActionFunc) *CommandWidget {
|
|
|
|
return w.WithPreStart(fn)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the usage action.
|
|
|
|
func (w *CommandWidget) WithUsage(a Action) *CommandWidget {
|
|
|
|
w.Usage = a
|
|
|
|
return w
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the usage action with function.
|
|
|
|
func (w *CommandWidget) WithUsageFunc(fn ActionFunc) *CommandWidget {
|
|
|
|
return w.WithUsage(fn)
|
|
|
|
}
|
|
|
|
|
2023-09-21 15:28:06 +03:00
|
|
|
func (widget *CommandWidget) Filter(
|
2023-09-16 14:34:17 +03:00
|
|
|
u *Update,
|
|
|
|
msgs ...*Message,
|
|
|
|
) bool {
|
|
|
|
/*if u.Message == nil || !u.Message.IsCommand() {
|
|
|
|
return false
|
|
|
|
}*/
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2023-09-20 22:48:35 +03:00
|
|
|
func (widget *CommandWidget) Serve(c *Context) {
|
2023-09-11 15:58:45 +03:00
|
|
|
commanders := make(map[CommandName] BotCommander)
|
|
|
|
for k, v := range widget.Commands {
|
|
|
|
commanders[k] = v
|
|
|
|
}
|
|
|
|
c.Bot.SetCommands(
|
|
|
|
tgbotapi.NewBotCommandScopeAllPrivateChats(),
|
|
|
|
commanders,
|
|
|
|
)
|
|
|
|
|
2023-09-16 15:40:30 +03:00
|
|
|
var cmdUpdates *UpdateChan
|
2023-09-20 22:48:35 +03:00
|
|
|
for u := range c.Input() {
|
2023-09-21 12:03:54 +03:00
|
|
|
if c.Path() == "" && u.Message != nil {
|
2023-09-11 15:58:45 +03:00
|
|
|
// Skipping and executing the preinit action
|
|
|
|
// while we have the empty screen.
|
|
|
|
// E. g. the session did not start.
|
|
|
|
if !(u.Message.IsCommand() && u.Message.Command() == "start") {
|
|
|
|
c.Run(widget.PreStart, u)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if u.Message != nil && u.Message.IsCommand() {
|
|
|
|
// Command handling.
|
|
|
|
cmdName := CommandName(u.Message.Command())
|
|
|
|
cmd, ok := widget.Commands[cmdName]
|
|
|
|
if !ok {
|
|
|
|
c.Run(widget.Usage, u)
|
|
|
|
continue
|
2023-09-12 11:41:50 +03:00
|
|
|
}
|
|
|
|
|
2023-09-11 15:58:45 +03:00
|
|
|
c.Run(cmd.Action, u)
|
|
|
|
if cmd.Widget != nil {
|
2023-09-16 15:40:30 +03:00
|
|
|
cmdUpdates.Close()
|
2023-09-26 17:13:31 +03:00
|
|
|
cmdUpdates = c.runWidget(cmd.Widget)
|
2023-09-11 15:58:45 +03:00
|
|
|
}
|
2023-09-12 11:41:50 +03:00
|
|
|
continue
|
2023-09-11 15:58:45 +03:00
|
|
|
}
|
|
|
|
|
2023-09-20 22:48:35 +03:00
|
|
|
if !cmdUpdates.Closed() {
|
2023-09-11 15:58:45 +03:00
|
|
|
// Send to the commands channel if we are
|
|
|
|
// executing one.
|
2023-09-16 15:40:30 +03:00
|
|
|
cmdUpdates.Send(u)
|
2023-09-11 15:58:45 +03:00
|
|
|
} else {
|
|
|
|
c.Skip(u)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|