Skip to content

chat-platform

Writing a bot that reads a Discord channel should not put a Discord SDK in your dependency graph, and supporting Slack later should not mean a second code path.

This module is the contract. Providers live in their own modules and register themselves, so your code depends on an interface and never on a gateway client.

factory, _ := chatplatform.Lookup("discord")
p, _ := factory(chatplatform.Config{Token: tok, Space: guild, AllowedChannels: chans})

for msg := range p.Reader.Messages() {
    p.Actor.ReplyInThread(ctx, msg.Ref(), "help", answer)
}

Where to start

Design in four points

  • Reading and acting are separate. Ask for read-only and there is no Actor at all, so shadow mode is enforced by the type system rather than by remembering to check a flag.
  • Capabilities are opt-in. Moderation, member lookup, interactive components and slash commands are optional interfaces found by type assertion. A read-only bridge with none of them is a legitimate provider.
  • Reconnect losses are surfaced. A reconnect that restarted the session rather than resuming dropped every message during the gap — with no error and nothing to notice. ConnState says so.
  • No vendor SDK in the core. This module has no third-party dependencies at all, and a guard test keeps it that way.