l10n and bot command auto generation; v0.6.0
This commit is contained in:
16
bot.go
16
bot.go
@@ -41,7 +41,7 @@ func LoadSettingsFromEnv() *BotSettings {
|
||||
func LoadPrefixesFromEnv() []string {
|
||||
prefixesS, exists := os.LookupEnv("PREFIXES")
|
||||
if !exists {
|
||||
return []string{"!"}
|
||||
return []string{"/"}
|
||||
}
|
||||
return strings.Split(prefixesS, ";")
|
||||
}
|
||||
@@ -61,6 +61,7 @@ type Bot struct {
|
||||
|
||||
dbContext *DatabaseContext
|
||||
api *tgapi.API
|
||||
l10n L10n
|
||||
|
||||
dbWriterRequested extypes.Slice[*slog.Logger]
|
||||
|
||||
@@ -76,7 +77,7 @@ func NewBot(settings *BotSettings) *Bot {
|
||||
updateOffset: 0, plugins: make([]Plugin, 0), debug: settings.Debug, errorTemplate: "%s",
|
||||
prefixes: settings.Prefixes, updateTypes: make([]tgapi.UpdateType, 0), runners: make([]Runner, 0),
|
||||
updateQueue: updateQueue, api: api, dbWriterRequested: make([]*slog.Logger, 0),
|
||||
token: settings.Token,
|
||||
token: settings.Token, l10n: L10n{},
|
||||
}
|
||||
bot.dbWriterRequested = bot.dbWriterRequested.Push(api.Logger)
|
||||
|
||||
@@ -182,9 +183,9 @@ func (b *Bot) Debug(debug bool) *Bot {
|
||||
b.debug = debug
|
||||
return b
|
||||
}
|
||||
func (b *Bot) AddPlugins(plugin ...Plugin) *Bot {
|
||||
b.plugins = append(b.plugins, plugin...)
|
||||
func (b *Bot) AddPlugins(plugin ...*Plugin) *Bot {
|
||||
for _, p := range plugin {
|
||||
b.plugins = append(b.plugins, *p)
|
||||
b.logger.Debugln(fmt.Sprintf("plugins with name \"%s\" registered", p.Name))
|
||||
}
|
||||
return b
|
||||
@@ -211,6 +212,13 @@ func (b *Bot) AddRunner(runner Runner) *Bot {
|
||||
b.logger.Debugln(fmt.Sprintf("runner with name \"%s\" registered", runner.Name))
|
||||
return b
|
||||
}
|
||||
func (b *Bot) AddL10n(l L10n) *Bot {
|
||||
b.l10n = l
|
||||
return b
|
||||
}
|
||||
func (b *Bot) L10n(lang, key string) string {
|
||||
return b.l10n.Translate(lang, key)
|
||||
}
|
||||
func (b *Bot) Logger() *slog.Logger {
|
||||
return b.logger
|
||||
}
|
||||
|
||||
@@ -1,26 +1,59 @@
|
||||
package laniakea
|
||||
|
||||
import "git.nix13.pw/scuroneko/laniakea/tgapi"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.nix13.pw/scuroneko/laniakea/tgapi"
|
||||
)
|
||||
|
||||
func generateBotCommand(cmd Command) tgapi.BotCommand {
|
||||
return tgapi.BotCommand{
|
||||
Command: cmd.command, Description: cmd.command,
|
||||
desc := cmd.command
|
||||
if len(cmd.description) > 0 {
|
||||
desc = cmd.description
|
||||
}
|
||||
var descArgs []string
|
||||
for _, a := range cmd.args {
|
||||
if a.required {
|
||||
descArgs = append(descArgs, fmt.Sprintf("%s", a.text))
|
||||
} else {
|
||||
descArgs = append(descArgs, fmt.Sprintf("[%s]", a.text))
|
||||
}
|
||||
}
|
||||
desc = fmt.Sprintf("%s. Usage: /%s %s", desc, cmd.command, strings.Join(descArgs, " "))
|
||||
return tgapi.BotCommand{Command: cmd.command, Description: desc}
|
||||
}
|
||||
|
||||
func generateBotCommandForPlugin(pl Plugin) []tgapi.BotCommand {
|
||||
cmds := make([]tgapi.BotCommand, 0)
|
||||
commands := make([]tgapi.BotCommand, 0)
|
||||
for _, cmd := range pl.Commands {
|
||||
cmds = append(cmds, generateBotCommand(cmd))
|
||||
commands = append(commands, generateBotCommand(cmd))
|
||||
}
|
||||
return cmds
|
||||
return commands
|
||||
}
|
||||
|
||||
func (b *Bot) AutoGenerateCommands() error {
|
||||
_, err := b.api.DeleteMyCommands(tgapi.DeleteMyCommandsP{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commands := make([]tgapi.BotCommand, 0)
|
||||
for _, pl := range b.plugins {
|
||||
commands = append(commands, generateBotCommandForPlugin(pl)...)
|
||||
}
|
||||
_, err := b.api.SetMyCommands(tgapi.SetMyCommandsP{Commands: commands})
|
||||
|
||||
privateChatsScope := &tgapi.BotCommandScope{Type: tgapi.BotCommandScopePrivateType}
|
||||
groupChatsScope := &tgapi.BotCommandScope{Type: tgapi.BotCommandScopeGroupType}
|
||||
chatAdminsScope := &tgapi.BotCommandScope{Type: tgapi.BotCommandScopeAllChatAdministratorsType}
|
||||
_, err = b.api.SetMyCommands(tgapi.SetMyCommandsP{Commands: commands, Scope: privateChatsScope})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.api.SetMyCommands(tgapi.SetMyCommandsP{Commands: commands, Scope: groupChatsScope})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = b.api.SetMyCommands(tgapi.SetMyCommandsP{Commands: commands, Scope: chatAdminsScope})
|
||||
return err
|
||||
}
|
||||
|
||||
5
go.mod
5
go.mod
@@ -1,11 +1,11 @@
|
||||
module git.nix13.pw/scuroneko/laniakea
|
||||
|
||||
go 1.25
|
||||
go 1.26
|
||||
|
||||
require (
|
||||
git.nix13.pw/scuroneko/extypes v1.2.0
|
||||
git.nix13.pw/scuroneko/slog v1.0.2
|
||||
github.com/redis/go-redis/v9 v9.17.3
|
||||
github.com/redis/go-redis/v9 v9.18.0
|
||||
github.com/vinovest/sqlx v1.7.1
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0
|
||||
)
|
||||
@@ -23,6 +23,7 @@ require (
|
||||
github.com/xdg-go/scram v1.2.0 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
|
||||
10
go.sum
10
go.sum
@@ -22,6 +22,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
@@ -36,8 +38,8 @@ github.com/muir/sqltoken v0.3.0 h1:3xbcqr80f3IA4OlwkOpdIHC4DTu6gsi1TwMqgYL4Dpg=
|
||||
github.com/muir/sqltoken v0.3.0/go.mod h1:+OSmbGI22QcVZ6DCzlHT8EAzEq/mqtqedtPP91Le+3A=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/redis/go-redis/v9 v9.17.3 h1:fN29NdNrE17KttK5Ndf20buqfDZwGNgoUr9qjl1DQx4=
|
||||
github.com/redis/go-redis/v9 v9.17.3/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370=
|
||||
github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs=
|
||||
github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/vinovest/sqlx v1.7.1 h1:kdq4v0N9kRLpytWGSWOw4aulOGdQPmIoMR6Y+cTBxow=
|
||||
@@ -51,8 +53,12 @@ github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gi
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
|
||||
12
handler.go
12
handler.go
@@ -46,7 +46,6 @@ func (b *Bot) handleMessage(update *tgapi.Update, ctx *MsgContext) {
|
||||
text = strings.TrimSpace(text[len(prefix):])
|
||||
|
||||
for _, plugin := range b.plugins {
|
||||
// Check every command
|
||||
for cmd := range plugin.Commands {
|
||||
if !strings.HasPrefix(text, cmd) {
|
||||
continue
|
||||
@@ -60,17 +59,22 @@ func (b *Bot) handleMessage(update *tgapi.Update, ctx *MsgContext) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isValid {
|
||||
continue
|
||||
}
|
||||
|
||||
ctx.Text = strings.TrimSpace(text[len(cmd):])
|
||||
ctx.Args = strings.Split(ctx.Text, " ")
|
||||
if ctx.Text == "" {
|
||||
ctx.Args = []string{}
|
||||
} else {
|
||||
ctx.Args = strings.Split(ctx.Text, " ")
|
||||
}
|
||||
|
||||
if !plugin.executeMiddlewares(ctx, b.dbContext) {
|
||||
return
|
||||
}
|
||||
go plugin.Execute(cmd, ctx, b.dbContext)
|
||||
go plugin.executeCmd(cmd, ctx, b.dbContext)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -100,7 +104,7 @@ func (b *Bot) handleCallback(update *tgapi.Update, ctx *MsgContext) {
|
||||
if !plugin.executeMiddlewares(ctx, b.dbContext) {
|
||||
return
|
||||
}
|
||||
go plugin.ExecutePayload(data.Command, ctx, b.dbContext)
|
||||
go plugin.executePayload(data.Command, ctx, b.dbContext)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
27
l10n.go
Normal file
27
l10n.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package laniakea
|
||||
|
||||
// DictEntry {key:{ru:123,en:123}}
|
||||
type DictEntry map[string]string
|
||||
type L10n struct {
|
||||
entries map[string]DictEntry
|
||||
fallbackLang string
|
||||
}
|
||||
|
||||
func NewL10n(fallbackLanguage string) *L10n {
|
||||
return &L10n{make(map[string]DictEntry), fallbackLanguage}
|
||||
}
|
||||
func (l *L10n) AddDictEntry(key string, value DictEntry) *L10n {
|
||||
l.entries[key] = value
|
||||
return l
|
||||
}
|
||||
func (l *L10n) GetFallbackLanguage() string {
|
||||
return l.fallbackLang
|
||||
}
|
||||
|
||||
func (l *L10n) Translate(lang, key string) string {
|
||||
s, ok := l.entries[key]
|
||||
if !ok {
|
||||
return key
|
||||
}
|
||||
return s[lang]
|
||||
}
|
||||
@@ -212,3 +212,11 @@ func (ctx *MsgContext) error(err error) {
|
||||
func (ctx *MsgContext) Error(err error) {
|
||||
ctx.error(err)
|
||||
}
|
||||
|
||||
func (ctx *MsgContext) Translate(key string) string {
|
||||
if ctx.From == nil {
|
||||
return key
|
||||
}
|
||||
lang := Val(ctx.From.LanguageCode, ctx.Bot.l10n.GetFallbackLanguage())
|
||||
return ctx.Bot.L10n(lang, key)
|
||||
}
|
||||
|
||||
147
plugins.go
147
plugins.go
@@ -1,13 +1,12 @@
|
||||
package laniakea
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
|
||||
"git.nix13.pw/scuroneko/extypes"
|
||||
)
|
||||
|
||||
type CommandExecutor func(ctx *MsgContext, dbContext *DatabaseContext)
|
||||
|
||||
const (
|
||||
CommandValueStringType CommandValueType = "string"
|
||||
CommandValueIntType CommandValueType = "int"
|
||||
@@ -17,7 +16,12 @@ const (
|
||||
|
||||
var (
|
||||
CommandRegexInt = regexp.MustCompile("\\d+")
|
||||
CommandRegexString = regexp.MustCompile("\\.+")
|
||||
CommandRegexString = regexp.MustCompile(".+")
|
||||
)
|
||||
|
||||
var (
|
||||
ErrCmdArgCountMismatch = errors.New("command arg count mismatch")
|
||||
ErrCmdArgRegexpMismatch = errors.New("command arg regexp mismatch")
|
||||
)
|
||||
|
||||
type CommandValueType string
|
||||
@@ -25,69 +29,102 @@ type CommandArg struct {
|
||||
valueType CommandValueType
|
||||
text string
|
||||
regex *regexp.Regexp
|
||||
required bool
|
||||
}
|
||||
|
||||
func NewCommandArg(text string, valueType CommandValueType) CommandArg {
|
||||
func NewCommandArg(text string, valueType CommandValueType) *CommandArg {
|
||||
regex := CommandRegexString
|
||||
switch valueType {
|
||||
case CommandValueIntType:
|
||||
regex = CommandRegexInt
|
||||
}
|
||||
return CommandArg{valueType, text, regex}
|
||||
return &CommandArg{valueType, text, regex, false}
|
||||
}
|
||||
func (c *CommandArg) SetRequired() *CommandArg {
|
||||
c.required = true
|
||||
return c
|
||||
}
|
||||
|
||||
type CommandExecutor func(ctx *MsgContext, dbContext *DatabaseContext)
|
||||
type Command struct {
|
||||
command string
|
||||
description string
|
||||
exec CommandExecutor
|
||||
args []CommandArg
|
||||
middlewares []Middleware
|
||||
args extypes.Slice[CommandArg]
|
||||
middlewares extypes.Slice[Middleware]
|
||||
}
|
||||
|
||||
func NewCommand(exec CommandExecutor, command string, args ...CommandArg) *Command {
|
||||
return &Command{command, exec, args, make([]Middleware, 0)}
|
||||
return &Command{command, "", exec, args, make(extypes.Slice[Middleware], 0)}
|
||||
}
|
||||
func (c *Command) Use(m Middleware) *Command {
|
||||
c.middlewares = c.middlewares.Push(m)
|
||||
return c
|
||||
}
|
||||
func (c *Command) SetDescription(desc string) *Command {
|
||||
c.description = desc
|
||||
return c
|
||||
}
|
||||
func (c *Command) validateArgs(args []string) error {
|
||||
cmdArgs := c.args.Filter(func(e CommandArg) bool { return !e.required })
|
||||
if len(args) < cmdArgs.Len() {
|
||||
return ErrCmdArgCountMismatch
|
||||
}
|
||||
|
||||
for i, arg := range args {
|
||||
if i >= c.args.Len() {
|
||||
break
|
||||
}
|
||||
cmdArg := c.args.Get(i)
|
||||
if cmdArg.regex == nil {
|
||||
continue
|
||||
}
|
||||
if !cmdArg.regex.MatchString(arg) {
|
||||
return ErrCmdArgRegexpMismatch
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Plugin struct {
|
||||
Name string
|
||||
Commands map[string]Command
|
||||
Payloads map[string]Command
|
||||
Middlewares extypes.Slice[PluginMiddleware]
|
||||
Middlewares extypes.Slice[Middleware]
|
||||
}
|
||||
|
||||
func NewPlugin(name string) *Plugin {
|
||||
return &Plugin{
|
||||
Name: name,
|
||||
Commands: map[string]Command{},
|
||||
Payloads: map[string]Command{},
|
||||
Middlewares: extypes.Slice[PluginMiddleware]{},
|
||||
name, map[string]Command{},
|
||||
map[string]Command{}, extypes.Slice[Middleware]{},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plugin) AddCommand(command Command) *Plugin {
|
||||
p.Commands[command.command] = command
|
||||
func (p *Plugin) AddCommand(command *Command) *Plugin {
|
||||
p.Commands[command.command] = *command
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Plugin) AddPayload(command Command) *Plugin {
|
||||
p.Payloads[command.command] = command
|
||||
func (p *Plugin) AddPayload(command *Command) *Plugin {
|
||||
p.Payloads[command.command] = *command
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Plugin) AddMiddleware(middleware PluginMiddleware) *Plugin {
|
||||
func (p *Plugin) AddMiddleware(middleware Middleware) *Plugin {
|
||||
p.Middlewares = p.Middlewares.Push(middleware)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Plugin) Execute(cmd string, ctx *MsgContext, dbContext *DatabaseContext) {
|
||||
func (p *Plugin) executeCmd(cmd string, ctx *MsgContext, dbContext *DatabaseContext) {
|
||||
command := p.Commands[cmd]
|
||||
if !command.validateArgs(ctx.Args) {
|
||||
if err := command.validateArgs(ctx.Args); err != nil {
|
||||
ctx.error(err)
|
||||
return
|
||||
}
|
||||
command.exec(ctx, dbContext)
|
||||
}
|
||||
func (p *Plugin) ExecutePayload(payload string, ctx *MsgContext, dbContext *DatabaseContext) {
|
||||
func (p *Plugin) executePayload(payload string, ctx *MsgContext, dbContext *DatabaseContext) {
|
||||
pl := p.Payloads[payload]
|
||||
if !pl.validateArgs(ctx.Args) {
|
||||
if err := pl.validateArgs(ctx.Args); err != nil {
|
||||
ctx.error(err)
|
||||
return
|
||||
}
|
||||
pl.exec(ctx, dbContext)
|
||||
@@ -100,30 +137,19 @@ func (p *Plugin) executeMiddlewares(ctx *MsgContext, db *DatabaseContext) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (c *Command) validateArgs(args []string) bool {
|
||||
if len(args) != len(c.args) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, arg := range c.args {
|
||||
if arg.regex == nil {
|
||||
continue
|
||||
}
|
||||
if !arg.regex.MatchString(args[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
type MiddlewareExecutor func(ctx *MsgContext, db *DatabaseContext) bool
|
||||
|
||||
// Middleware
|
||||
// When async, returned value ignored
|
||||
type Middleware struct {
|
||||
name string
|
||||
exec CommandExecutor
|
||||
order int
|
||||
async bool
|
||||
name string
|
||||
executor MiddlewareExecutor
|
||||
order int
|
||||
async bool
|
||||
}
|
||||
|
||||
func NewMiddleware(name string, executor CommandExecutor) *Middleware {
|
||||
func NewMiddleware(name string, executor MiddlewareExecutor) *Middleware {
|
||||
return &Middleware{name, executor, 0, false}
|
||||
}
|
||||
func (m *Middleware) SetOrder(order int) *Middleware {
|
||||
@@ -134,40 +160,7 @@ func (m *Middleware) SetAsync(async bool) *Middleware {
|
||||
m.async = async
|
||||
return m
|
||||
}
|
||||
func (m *Middleware) Execute(ctx *MsgContext, db *DatabaseContext) {
|
||||
if m.async {
|
||||
go m.exec(ctx, db)
|
||||
} else {
|
||||
m.Execute(ctx, db)
|
||||
}
|
||||
}
|
||||
|
||||
type PluginMiddlewareExecutor func(ctx *MsgContext, db *DatabaseContext) bool
|
||||
|
||||
// PluginMiddleware
|
||||
// When async, returned value ignored
|
||||
type PluginMiddleware struct {
|
||||
executor PluginMiddlewareExecutor
|
||||
order int
|
||||
async bool
|
||||
}
|
||||
|
||||
func NewPluginMiddleware(executor PluginMiddlewareExecutor) *PluginMiddleware {
|
||||
return &PluginMiddleware{
|
||||
executor: executor,
|
||||
order: 0,
|
||||
async: false,
|
||||
}
|
||||
}
|
||||
func (m *PluginMiddleware) SetOrder(order int) *PluginMiddleware {
|
||||
m.order = order
|
||||
return m
|
||||
}
|
||||
func (m *PluginMiddleware) SetAsync(async bool) *PluginMiddleware {
|
||||
m.async = async
|
||||
return m
|
||||
}
|
||||
func (m *PluginMiddleware) Execute(ctx *MsgContext, db *DatabaseContext) bool {
|
||||
func (m *Middleware) Execute(ctx *MsgContext, db *DatabaseContext) bool {
|
||||
if m.async {
|
||||
go m.executor(ctx, db)
|
||||
return true
|
||||
|
||||
@@ -67,9 +67,6 @@ func (r TelegramRequest[R, P]) DoWithContext(ctx context.Context, api *API) (R,
|
||||
return zero, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return zero, fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
reader := io.LimitReader(res.Body, 10<<20)
|
||||
data, err = io.ReadAll(reader)
|
||||
@@ -77,6 +74,9 @@ func (r TelegramRequest[R, P]) DoWithContext(ctx context.Context, api *API) (R,
|
||||
return zero, err
|
||||
}
|
||||
api.Logger.Debugln("RES", r.method, string(data))
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return zero, fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
var resp ApiResponse[R]
|
||||
err = json.Unmarshal(data, &resp)
|
||||
|
||||
@@ -9,7 +9,7 @@ type BotCommandScopeType string
|
||||
const (
|
||||
BotCommandScopeDefaultType BotCommandScopeType = "default"
|
||||
BotCommandScopePrivateType BotCommandScopeType = "all_private_chats"
|
||||
BotCommandScopeGroupType BotCommandScopeType = "all_groups_chats"
|
||||
BotCommandScopeGroupType BotCommandScopeType = "all_group_chats"
|
||||
BotCommandScopeAllChatAdministratorsType BotCommandScopeType = "all_chat_administrators"
|
||||
BotCommandScopeChatType BotCommandScopeType = "chat"
|
||||
BotCommandScopeChatAdministratorsType BotCommandScopeType = "chat_administrators"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package utils
|
||||
|
||||
const (
|
||||
VersionString = "0.5.0"
|
||||
VersionString = "0.6.0"
|
||||
VersionMajor = 0
|
||||
VersionMinor = 5
|
||||
VersionMinor = 6
|
||||
VersionPatch = 0
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user