Skip to main content
xbot
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

The plugin event bus provides publish/subscribe communication between plugins.

Overview

PluginEventBus is an in-process pub/sub system. Plugins can subscribe to topics and publish events. Each handler invocation is wrapped in panic recovery.

API

type PluginEventBus struct { ... }

func NewPluginEventBus() *PluginEventBus

func (b *PluginEventBus) Subscribe(topic string, handler PluginEventHandler) error
func (b *PluginEventBus) Publish(ctx context.Context, topic string, data any) []error
func (b *PluginEventBus) Unsubscribe(topic string, handler PluginEventHandler) error

Handler signature:

type PluginEventHandler func(ctx context.Context, topic string, data any) error

Permissions

ActionRequired Permission
Subscribebus.read
Publishbus.write
Both (plugin-to-plugin)bus.plugin (implies bus.read + bus.write)

Usage

Subscribing

func (p *MyPlugin) Activate(ctx plugin.PluginContext) error {
    return ctx.Subscribe("xbot.my-plugin:events", func(ctx context.Context, topic string, data any) error {
        logger := ctx.Logger()
        logger.Info("Received event", plugin.Field{Key: "topic", Value: topic})
        return nil
    })
}

Publishing

func (p *MyPlugin) DoSomething(ctx plugin.PluginContext) error {
    return ctx.Publish("xbot.my-plugin:events", map[string]any{
        "action": "completed",
        "timestamp": time.Now().Unix(),
    })
}

Unsubscribing

// Unsubscribe uses function pointer comparison
handler := func(ctx context.Context, topic string, data any) error { return nil }
ctx.Subscribe("topic", handler)
// Later:
ctx.Unsubscribe("topic", handler)  // Must be the same function reference

Topic Naming Convention

Use reverse-DNS style with plugin ID prefix:

xbot.<plugin-id>:<event-name>

Examples:

  • xbot.git-fancy:commit — Git Fancy plugin commit event
  • xbot.my-plugin:ready — My plugin ready event

Implementation Details

  • Thread-safe: Protected by sync.RWMutex
  • Copy-on-read: Handlers are copied before iteration, so subscribe/unsubscribe during publish is safe
  • Panic recovery: Each handler is wrapped in recover(). Panics are returned as errors, not propagated
  • Unsubscribe: Uses function pointer comparison (reflect.ValueOf().Pointer())

See Also