Small fixes and a bit of refactoring.
This commit is contained in:
parent
b39e63cbaa
commit
37cd1d37fd
8 changed files with 56 additions and 227 deletions
|
@ -112,6 +112,14 @@ WithInitFunc(func(c *tg.Context) {
|
|||
tg.NewButton("Send location").Go("/send-location"),
|
||||
).Reply(),
|
||||
),
|
||||
|
||||
tg.Func(func(c *tg.Context){
|
||||
for u := range c.Input() {
|
||||
if u.EditedMessage != nil {
|
||||
c.Sendf2("The new message is `%s`", u.EditedMessage.Text)
|
||||
}
|
||||
}
|
||||
}),
|
||||
}
|
||||
}),
|
||||
|
||||
|
@ -208,7 +216,7 @@ WithInitFunc(func(c *tg.Context) {
|
|||
|
||||
return tg.UI{
|
||||
kbd,
|
||||
tg.NewMessage("").Reply(
|
||||
tg.NewMessage("Use the reply keyboard to get back").Reply(
|
||||
backKeyboard.Reply(),
|
||||
),
|
||||
}
|
||||
|
@ -242,7 +250,9 @@ WithInitFunc(func(c *tg.Context) {
|
|||
}),
|
||||
),
|
||||
)).WithRoot(tg.NewCommandCompo().
|
||||
WithPreStart(tg.Func(func(c *tg.Context){
|
||||
WithUsage(tg.Func(func(c *tg.Context){
|
||||
c.Sendf("There is no such command %q", c.Message.Command())
|
||||
})).WithPreStart(tg.Func(func(c *tg.Context){
|
||||
c.Sendf("Please, use /start ")
|
||||
})).WithCommands(
|
||||
tg.NewCommand("info").
|
||||
|
|
47
tg/beh.go
47
tg/beh.go
|
@ -77,50 +77,3 @@ func (beh *Behaviour) GetScreen(pth Path) *Screen {
|
|||
return screen
|
||||
}
|
||||
|
||||
// The type describes behaviour for the bot in group chats.
|
||||
type GroupBehaviour struct {
|
||||
Init GroupAction
|
||||
// List of commands
|
||||
Commands GroupCommandMap
|
||||
}
|
||||
|
||||
// Returns new empty group behaviour object.
|
||||
func NewGroupBehaviour() *GroupBehaviour {
|
||||
return &GroupBehaviour{
|
||||
Commands: make(GroupCommandMap),
|
||||
}
|
||||
}
|
||||
|
||||
// Sets an Action for initialization on each group connected to the
|
||||
// group bot.
|
||||
func (b *GroupBehaviour) WithInitAction(a GroupAction) *GroupBehaviour {
|
||||
b.Init = a
|
||||
return b
|
||||
}
|
||||
|
||||
// The method reciveies a function to be called on initialization of the
|
||||
// bot group bot.
|
||||
func (b *GroupBehaviour) InitFunc(fn GroupActionFunc) *GroupBehaviour {
|
||||
return b.WithInitAction(fn)
|
||||
}
|
||||
|
||||
// The method sets group commands.
|
||||
func (b *GroupBehaviour) WithCommands(
|
||||
cmds ...*GroupCommand,
|
||||
) *GroupBehaviour {
|
||||
for _, cmd := range cmds {
|
||||
if cmd.Name == "" {
|
||||
panic("empty command name")
|
||||
}
|
||||
_, ok := b.Commands[cmd.Name]
|
||||
if ok {
|
||||
panic("duplicate command definition")
|
||||
}
|
||||
b.Commands[cmd.Name] = cmd
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// The type describes behaviour for the bot in channels.
|
||||
type ChannelBehaviour struct {
|
||||
}
|
||||
|
|
61
tg/bot.go
61
tg/bot.go
|
@ -22,12 +22,12 @@ type Bot struct {
|
|||
// Private bot behaviour.
|
||||
behaviour *Behaviour
|
||||
// Group bot behaviour.
|
||||
groupBehaviour *GroupBehaviour
|
||||
//groupBehaviour *GroupBehaviour
|
||||
// Bot behaviour in channels.
|
||||
channelBehaviour *ChannelBehaviour
|
||||
//channelBehaviour *ChannelBehaviour
|
||||
contexts map[SessionId] *context
|
||||
sessions SessionMap
|
||||
groupSessions GroupSessionMap
|
||||
//groupSessions GroupSessionMap
|
||||
}
|
||||
|
||||
// Return the new bot with empty sessions and behaviour.
|
||||
|
@ -65,28 +65,8 @@ func (bot *Bot) Send(
|
|||
return c.Bot.Send(c.Session.Id, v)
|
||||
}
|
||||
|
||||
/*func (bot *Bot) Render(
|
||||
sid SessionId, r Renderable,
|
||||
) (MessageMap, error) {
|
||||
configs := r.Render(sid, bot)
|
||||
if configs == nil {
|
||||
return nil, MapCollisionErr
|
||||
}
|
||||
messages := make(MessageMap)
|
||||
for _, config := range configs {
|
||||
_, collision := messages[config.Name]
|
||||
if collision {
|
||||
return messages, MapCollisionErr
|
||||
}
|
||||
msg, err := bot.Api.Send(config.ToApi())
|
||||
if err != nil {
|
||||
return messages, err
|
||||
}
|
||||
messages[config.Name] = &msg
|
||||
}
|
||||
return messages, nil
|
||||
}*/
|
||||
|
||||
// Get session by its ID. Can be used for any scope
|
||||
// including private, group and channel.
|
||||
func (bot *Bot) GetSession(
|
||||
sid SessionId,
|
||||
) (*Session, bool) {
|
||||
|
@ -94,13 +74,6 @@ func (bot *Bot) GetSession(
|
|||
return session, ok
|
||||
}
|
||||
|
||||
func (bot *Bot) GetGroupSession(
|
||||
sid SessionId,
|
||||
) (*GroupSession, bool) {
|
||||
session, ok := bot.groupSessions[sid]
|
||||
return session, ok
|
||||
}
|
||||
|
||||
func (b *Bot) WithBehaviour(beh *Behaviour) *Bot {
|
||||
b.behaviour = beh
|
||||
b.sessions = make(SessionMap)
|
||||
|
@ -112,7 +85,7 @@ func (b *Bot) WithSessions(sessions SessionMap) *Bot {
|
|||
return b
|
||||
}
|
||||
|
||||
func (b *Bot) WithGroupBehaviour(beh *GroupBehaviour) *Bot {
|
||||
/*func (b *Bot) WithGroupBehaviour(beh *GroupBehaviour) *Bot {
|
||||
b.groupBehaviour = beh
|
||||
b.groupSessions = make(GroupSessionMap)
|
||||
return b
|
||||
|
@ -121,12 +94,18 @@ func (b *Bot) WithGroupBehaviour(beh *GroupBehaviour) *Bot {
|
|||
func (b *Bot) WithGroupSessions(sessions GroupSessionMap) *Bot {
|
||||
b.groupSessions = sessions
|
||||
return b
|
||||
}*/
|
||||
|
||||
func (bot *Bot) DeleteCommands() {
|
||||
//tgbotapi.NewBotCommandScopeAllPrivateChats(),
|
||||
cfg := tgbotapi.NewDeleteMyCommands()
|
||||
bot.Api.Request(cfg)
|
||||
}
|
||||
|
||||
// Setting the command on the user side.
|
||||
func (bot *Bot) SetCommands(
|
||||
scope tgbotapi.BotCommandScope,
|
||||
cmdMap map[CommandName] BotCommander,
|
||||
cmdMap CommandMap,
|
||||
) {
|
||||
// First the private commands.
|
||||
names := []string{}
|
||||
|
@ -135,7 +114,7 @@ func (bot *Bot) SetCommands(
|
|||
}
|
||||
sort.Strings([]string(names))
|
||||
|
||||
cmds := []BotCommander{}
|
||||
cmds := []*Command{}
|
||||
for _, name := range names {
|
||||
cmds = append(
|
||||
cmds,
|
||||
|
@ -159,8 +138,7 @@ func (bot *Bot) SetCommands(
|
|||
|
||||
// Run the bot with the Behaviour.
|
||||
func (bot *Bot) Run() error {
|
||||
if bot.behaviour == nil &&
|
||||
bot.groupBehaviour == nil {
|
||||
if bot.behaviour == nil {
|
||||
return errors.New("no behaviour defined")
|
||||
}
|
||||
|
||||
|
@ -169,7 +147,7 @@ func (bot *Bot) Run() error {
|
|||
}
|
||||
|
||||
uc := tgbotapi.NewUpdate(0)
|
||||
uc.Timeout = 60
|
||||
uc.Timeout = 10
|
||||
updates := bot.Api.GetUpdatesChan(uc)
|
||||
handles := make(map[string] chan *Update)
|
||||
|
||||
|
@ -179,7 +157,7 @@ func (bot *Bot) Run() error {
|
|||
go bot.handlePrivate(chn)
|
||||
}
|
||||
|
||||
if bot.groupBehaviour != nil {
|
||||
/*if bot.groupBehaviour != nil {
|
||||
commanders := make(map[CommandName] BotCommander)
|
||||
for k, v := range bot.groupBehaviour.Commands {
|
||||
commanders[k] = v
|
||||
|
@ -192,7 +170,7 @@ func (bot *Bot) Run() error {
|
|||
handles["group"] = chn
|
||||
handles["supergroup"] = chn
|
||||
go bot.handleGroup(chn)
|
||||
}
|
||||
}*/
|
||||
|
||||
me, _ := bot.Api.GetMe()
|
||||
bot.Me = &me
|
||||
|
@ -249,7 +227,7 @@ func (bot *Bot) handlePrivate(updates chan *Update) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func (bot *Bot) handleGroup(updates chan *Update) {
|
||||
var sid SessionId
|
||||
chans := make(map[SessionId]chan *Update)
|
||||
|
@ -273,3 +251,4 @@ func (bot *Bot) handleGroup(updates chan *Update) {
|
|||
chn <- u
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -6,14 +6,18 @@ import (
|
|||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
type BotCommander interface {
|
||||
ToApi() tgbotapi.BotCommand
|
||||
}
|
||||
type Message = tgbotapi.Message
|
||||
type CommandType uint8
|
||||
const (
|
||||
PrivateCommandType CommandType = iota
|
||||
GroupCommandType
|
||||
ChannelCommandType
|
||||
)
|
||||
|
||||
type CommandName string
|
||||
|
||||
type Command struct {
|
||||
Name CommandName
|
||||
Type CommandType
|
||||
Description string
|
||||
Action Action
|
||||
Widget Widget
|
||||
|
@ -63,41 +67,6 @@ func (c *Command) Go(pth Path, args ...any) *Command {
|
|||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
func (cmd *GroupCommand) Desc(desc string) *GroupCommand {
|
||||
cmd.Description = desc
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (c *GroupCommand) ToApi() tgbotapi.BotCommand {
|
||||
ret := tgbotapi.BotCommand{}
|
||||
ret.Command = string(c.Name)
|
||||
ret.Description = c.Description
|
||||
return ret
|
||||
}
|
||||
|
||||
// The type is used to recognize commands and execute
|
||||
// its actions and widgets .
|
||||
type CommandCompo struct {
|
||||
|
@ -165,13 +134,14 @@ func (widget *CommandCompo) Filter(
|
|||
|
||||
// Implementing server.
|
||||
func (compo *CommandCompo) Serve(c *Context) {
|
||||
commanders := make(map[CommandName] BotCommander)
|
||||
/*commanders := make(map[CommandName] BotCommander)
|
||||
for k, v := range compo.Commands {
|
||||
commanders[k] = v
|
||||
}
|
||||
}*/
|
||||
c.Bot.DeleteCommands()
|
||||
c.Bot.SetCommands(
|
||||
tgbotapi.NewBotCommandScopeAllPrivateChats(),
|
||||
commanders,
|
||||
compo.Commands,
|
||||
)
|
||||
|
||||
var cmdUpdates *UpdateChan
|
||||
|
|
|
@ -32,6 +32,6 @@ func DefineAction(typeName string, a Action) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func DefineGroupAction(typ string, a GroupAction) error {
|
||||
/*func DefineGroupAction(typ string, a GroupAction) error {
|
||||
return nil
|
||||
}
|
||||
}*/
|
||||
|
|
92
tg/group.go
92
tg/group.go
|
@ -1,94 +1,2 @@
|
|||
package tg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
//tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
// Customized actions for the group behaviour.
|
||||
type GroupAction interface {
|
||||
Act(*GroupContext)
|
||||
}
|
||||
|
||||
// The handler function type.
|
||||
type GroupActionFunc func(*GroupContext)
|
||||
|
||||
func (af GroupActionFunc) Act(a *GroupContext) {
|
||||
af(a)
|
||||
}
|
||||
|
||||
type GC = GroupContext
|
||||
|
||||
func (c *GroupContext) Session() *GroupSession {
|
||||
session, _ := c.Bot.GetGroupSession(
|
||||
SessionId(c.SentFrom().ID),
|
||||
)
|
||||
return session
|
||||
}
|
||||
|
||||
type GroupContext struct {
|
||||
*groupContext
|
||||
*Update
|
||||
}
|
||||
|
||||
// Context for interaction inside groups.
|
||||
type groupContext struct {
|
||||
Session *GroupSession
|
||||
Bot *Bot
|
||||
updates chan *Update
|
||||
}
|
||||
|
||||
func (c *groupContext) run(a GroupAction, u *Update) {
|
||||
go a.Act(&GroupContext{
|
||||
groupContext: c,
|
||||
Update: u,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *groupContext) handleUpdateChan(updates chan *Update) {
|
||||
var act GroupAction
|
||||
beh := c.Bot.groupBehaviour
|
||||
for u := range updates {
|
||||
if u.Message != nil {
|
||||
msg := u.Message
|
||||
if msg.IsCommand() {
|
||||
cmdName := CommandName(msg.Command())
|
||||
|
||||
// Skipping the commands sent not to us.
|
||||
withAt := msg.CommandWithAt()
|
||||
if len(cmdName) == len(withAt) {
|
||||
continue
|
||||
}
|
||||
|
||||
atName := withAt[len(cmdName)+1:]
|
||||
if c.Bot.Me.UserName != atName {
|
||||
continue
|
||||
}
|
||||
cmd, ok := beh.Commands[cmdName]
|
||||
if !ok {
|
||||
// Some lack of command handling
|
||||
continue
|
||||
}
|
||||
act = cmd.Action
|
||||
}
|
||||
}
|
||||
if act != nil {
|
||||
c.run(act, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *groupContext) Sendf(
|
||||
format string,
|
||||
v ...any,
|
||||
) (*Message, error) {
|
||||
return c.Send(NewMessage(
|
||||
fmt.Sprintf(format, v...),
|
||||
))
|
||||
}
|
||||
|
||||
// Sends into the chat specified values converted to strings.
|
||||
func (c *groupContext) Send(v Sendable) (*Message, error) {
|
||||
return c.Bot.Send(c.Session.Id, v)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package tg
|
|||
import (
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
type Message = tgbotapi.Message
|
||||
|
||||
// Simple text message type.
|
||||
type MessageCompo struct {
|
||||
|
|
8
tg/poll.go
Normal file
8
tg/poll.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package tg
|
||||
|
||||
type Poll struct {
|
||||
}
|
||||
|
||||
type PollCompo struct {
|
||||
}
|
||||
|
Loading…
Reference in a new issue