From 7a6f135487388566a48b9723e763eea3b7e797bf Mon Sep 17 00:00:00 2001 From: ScuroNeko Date: Wed, 4 Feb 2026 17:27:36 +0300 Subject: [PATCH] plugin middlewares; v0.3.10 --- bot.go | 4 +--- handler.go | 7 +++++++ plugins.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/bot.go b/bot.go index 0ba6f62..9295a9c 100644 --- a/bot.go +++ b/bot.go @@ -251,9 +251,7 @@ func (b *Bot) Run() { continue } - ctx := &MsgContext{ - Bot: b, Update: u, - } + ctx := &MsgContext{Bot: b, Update: u} for _, middleware := range b.middlewares { middleware.Execute(ctx, b.dbContext) } diff --git a/handler.go b/handler.go index e1ba871..c2f8877 100644 --- a/handler.go +++ b/handler.go @@ -39,6 +39,9 @@ func (b *Bot) handleMessage(update *Update, ctx *MsgContext) { ctx.Text = strings.TrimSpace(text[len(cmd):]) ctx.Args = strings.Split(ctx.Text, " ") + if !plugin.executeMiddlewares(ctx, b.dbContext) { + return + } go plugin.Execute(cmd, ctx, b.dbContext) return } @@ -65,6 +68,10 @@ func (b *Bot) handleCallback(update *Update, ctx *MsgContext) { if !ok { continue } + + if !plugin.executeMiddlewares(ctx, b.dbContext) { + return + } go plugin.ExecutePayload(data.Command, ctx, b.dbContext) return } diff --git a/plugins.go b/plugins.go index 414c098..86b5e96 100644 --- a/plugins.go +++ b/plugins.go @@ -1,6 +1,10 @@ package laniakea -import "log" +import ( + "log" + + "git.nix13.pw/scuroneko/extypes" +) type CommandExecutor func(ctx *MsgContext, dbContext *DatabaseContext) @@ -9,6 +13,7 @@ type PluginBuilder struct { commands map[string]*CommandExecutor payloads map[string]*CommandExecutor updateListener *CommandExecutor + middlewares extypes.Slice[*PluginMiddleware] } type Plugin struct { @@ -16,6 +21,7 @@ type Plugin struct { Commands map[string]*CommandExecutor Payloads map[string]*CommandExecutor UpdateListener *CommandExecutor + Middlewares extypes.Slice[*PluginMiddleware] } func NewPlugin(name string) *PluginBuilder { @@ -45,6 +51,11 @@ func (p *PluginBuilder) UpdateListener(listener CommandExecutor) *PluginBuilder return p } +func (p *PluginBuilder) Middleware(middleware *PluginMiddleware) *PluginBuilder { + p.middlewares = p.middlewares.Push(middleware) + return p +} + func (p *PluginBuilder) Build() Plugin { if len(p.commands) == 0 && len(p.payloads) == 0 { log.Println("no command or payloads") @@ -54,6 +65,7 @@ func (p *PluginBuilder) Build() Plugin { Commands: p.commands, Payloads: p.payloads, UpdateListener: p.updateListener, + Middlewares: p.middlewares, } } @@ -65,6 +77,15 @@ func (p *Plugin) ExecutePayload(payload string, ctx *MsgContext, dbContext *Data (*p.Payloads[payload])(ctx, dbContext) } +func (p *Plugin) executeMiddlewares(ctx *MsgContext, db *DatabaseContext) bool { + for _, m := range p.Middlewares { + if !m.Execute(ctx, db) { + return false + } + } + return true +} + type Middleware struct { Name string Executor CommandExecutor @@ -78,8 +99,8 @@ type MiddlewareBuilder struct { async bool } -func NewMiddleware(name string) *MiddlewareBuilder { - return &MiddlewareBuilder{name: name, async: false} +func NewMiddleware(name string, executor CommandExecutor) *MiddlewareBuilder { + return &MiddlewareBuilder{name: name, executor: executor, order: 0, async: false} } func (m *MiddlewareBuilder) SetName(name string) *MiddlewareBuilder { m.name = name @@ -112,3 +133,36 @@ func (m Middleware) Execute(ctx *MsgContext, db *DatabaseContext) { 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 { + if m.async { + go m.executor(ctx, db) + return true + } + return m.executor(ctx, db) +}