Honor IGNORED_BOTS env var: global sender ignore at dispatch

IGNORED_BOTS was set in .env but never read by any code; only the
URL-preview plugin filtered, and via a different unset var
(URL_PREVIEW_IGNORE_USERS). Parse IGNORED_BOTS in NewRegistry and
short-circuit DispatchMessage/DispatchReaction so ignored senders
(e.g. @pete:parodia.dev) are dropped before any plugin runs.
This commit is contained in:
prosolis
2026-06-05 19:26:49 -07:00
parent 667f87f9d0
commit 6a47be34bc

View File

@@ -2,6 +2,8 @@ package bot
import ( import (
"log/slog" "log/slog"
"os"
"strings"
"sync" "sync"
"gogobee/internal/plugin" "gogobee/internal/plugin"
@@ -9,13 +11,24 @@ import (
// Registry manages plugin registration and event dispatch. // Registry manages plugin registration and event dispatch.
type Registry struct { type Registry struct {
mu sync.RWMutex mu sync.RWMutex
plugins []plugin.Plugin plugins []plugin.Plugin
ignoredBots map[string]struct{}
} }
// NewRegistry creates an empty plugin registry. // NewRegistry creates an empty plugin registry. Senders listed in the
// IGNORED_BOTS env var (comma-separated full Matrix user IDs, e.g.
// "@pete:parodia.dev") are dropped before any plugin sees them.
func NewRegistry() *Registry { func NewRegistry() *Registry {
return &Registry{} ignored := make(map[string]struct{})
if raw := os.Getenv("IGNORED_BOTS"); raw != "" {
for _, u := range strings.Split(raw, ",") {
if u = strings.TrimSpace(u); u != "" {
ignored[u] = struct{}{}
}
}
}
return &Registry{ignoredBots: ignored}
} }
// Register adds a plugin to the registry. // Register adds a plugin to the registry.
@@ -42,6 +55,9 @@ func (r *Registry) Init() error {
// DispatchMessage sends a message context to all plugins in order. // DispatchMessage sends a message context to all plugins in order.
func (r *Registry) DispatchMessage(ctx plugin.MessageContext) { func (r *Registry) DispatchMessage(ctx plugin.MessageContext) {
if _, ok := r.ignoredBots[string(ctx.Sender)]; ok {
return
}
r.mu.RLock() r.mu.RLock()
defer r.mu.RUnlock() defer r.mu.RUnlock()
for _, p := range r.plugins { for _, p := range r.plugins {
@@ -71,6 +87,9 @@ func (r *Registry) safeOnMessage(p plugin.Plugin, ctx plugin.MessageContext) {
// DispatchReaction sends a reaction context to all plugins in order. // DispatchReaction sends a reaction context to all plugins in order.
func (r *Registry) DispatchReaction(ctx plugin.ReactionContext) { func (r *Registry) DispatchReaction(ctx plugin.ReactionContext) {
if _, ok := r.ignoredBots[string(ctx.Sender)]; ok {
return
}
r.mu.RLock() r.mu.RLock()
defer r.mu.RUnlock() defer r.mu.RUnlock()
for _, p := range r.plugins { for _, p := range r.plugins {