# How Maka Integrates with Messaging Platforms Like Slack and Discord: A Bot Bridge Architecture

> Learn how Maka integrates with Slack and Discord using its Bot Bridge architecture. Discover the unified pattern that connects platform-specific bots to a common event system.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: architecture
- Published: 2026-08-29

---

**Maka integrates with Slack and Discord through a unified *Bot Bridge* pattern where platform-specific implementations—`SlackBotBridge` and `DiscordBotBridge`—translate external protocols into a common internal event system managed by the `BotRegistry`.**

Maka's messaging platform integration is built on a clean abstraction layer that treats every chat service as a **Bot Bridge**. This architecture lets developers add new platforms without touching core runtime logic. In `apache/maka`, the bridge pattern lives in `packages/runtime/src/bots/` and provides consistent lifecycle management, event transformation, and message delivery across diverse protocols.

## The Bot Bridge Interface: Maka's Integration Foundation

Every messaging platform in Maka implements the **BotBridge** interface. This contract defines four core methods:

- `start()` – Opens the platform connection
- `stop()` – Gracefully closes the connection
- `sendMessage(chatId, text, options?)` – Delivers outbound messages
- `sendTypingIndicator?(chatId)` – Optional typing notifications

Both `SlackBotBridge` and `DiscordBotBridge` satisfy this interface, allowing the **BotRegistry** to manage them polymorphically. The registry itself, located at [`packages/runtime/src/bots/bot-registry.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bots/bot-registry.ts), handles instantiation, event wiring, and provides a uniform API for sending messages.

## Slack Integration: Socket Mode and Web API

The `SlackBotBridge` implementation in [`packages/runtime/src/bots/slack-bridge.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bots/slack-bridge.ts) connects to Slack using **dual clients**: `@slack/socket-mode` for real-time events and `@slack/web-api` for outbound messages.

### Connection Architecture

Slack integration uses `SocketModeClient` to maintain a persistent WebSocket connection. This approach avoids public URL requirements and handles reconnection automatically. The bridge authenticates with both a bot token (`xoxb-`) and an app-level token (`xapp-`).

### Event Flow: Slack to Maka

Incoming Slack events arrive as `SlackEventEnvelope` objects. The bridge transforms these through `slackMessageToEvent()` into the neutral `BotMessageEvent` shape:

| Slack Field | Maka Field |
|-------------|-----------|
| [`event.ts`](https://github.com/apache/maka/blob/main/event.ts) | `messageId` |
| `event.channel` | `chatId` |
| `event.text` | `text` |
| `event.thread_ts` | `threadId` |

### Outbound Message Handling

Outbound messages use `WebClient.chat.postMessage`. When you supply `replyToMessageId`, the bridge automatically sets `thread_ts` to preserve conversation context:

```typescript
import { SlackBotBridge } from '@maka/runtime/bots/slack-bridge';

const slackSettings = {
  enabled: true,
  token: 'xoxb-SLACK-BOT-TOKEN',
  appSecret: 'xapp-SLACK-APP-TOKEN',
};

const bridge = new SlackBotBridge(slackSettings);
await bridge.start();

// Send with thread reply
const ts = await bridge.sendMessage(
  'C01ABCD2EFG',
  'Reply in thread',
  { replyToMessageId: '1612345678.000200' }
);

await bridge.stop();

```

## Discord Integration: Gateway Bridge and REST API

The `DiscordBotBridge` in [`packages/runtime/src/bots/discord-bridge.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bots/discord-bridge.ts) extends `GatewayBridgeBase` to handle Discord's more complex WebSocket gateway protocol with its opcodes, heartbeats, and resume sequences.

### Low-Level Gateway Management

Discord requires explicit WebSocket lifecycle management. The bridge implements:

- `fetchGatewayUrl()` – Retrieves the gateway endpoint with bot authentication
- `buildIdentifyPayload()` – Constructs the identify payload with intent flags
- `buildResumePayload()` – Handles session resumption for reconnections

### Intent-Based Event Subscription

Unlike Slack's automatic event streaming, Discord uses **gateway intents** to filter which events the bot receives. The `DiscordBotBridge` configures these in `buildIdentifyPayload`, ensuring only relevant events like `MESSAGE_CREATE` are processed.

### Message Handling: Chunking and Rate Limits

Discord imposes a **2000-character limit** on message content. The bridge automatically handles this through `splitDiscordContent()`, breaking long messages into sequential chunks. Rate limiting is managed via `classifyDiscordSendResponse()` which parses Discord's `X-RateLimit-Remaining` headers:

```typescript
import { DiscordBotBridge } from '@maka/runtime/bots/discord-bridge';

const discordSettings = {
  enabled: true,
  token: 'Bot DISCORD-TOKEN',
};

const bridge = new DiscordBotBridge('discord', discordSettings);
await bridge.start();

// Automatically chunked if >2000 chars
const longText = 'A'.repeat(5000);
const messageId = await bridge.sendMessage('123456789012345678', longText);

await bridge.stop();

```

### Threading via Message References

Discord replies use `message_reference` objects rather than simple thread IDs. The `buildDiscordSendBody()` helper constructs these references when `replyToMessageId` is provided, mapping to Discord's `referenced_message.message_id` field.

## BotRegistry: The Central Hub for Messaging Platform Integration

The **BotRegistry** orchestrates all platform bridges. Located at [`packages/runtime/src/bots/bot-registry.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bots/bot-registry.ts), it provides three key capabilities:

1. **Bridge instantiation** – Creates `SlackBotBridge` or `DiscordBotBridge` based on `settings.channels` configuration
2. **Event aggregation** – Forwards `'message'` and `'statusChange'` events from all bridges to core runtime handlers
3. **Unified send API** – `registry.sendMessage(platform, chatId, text, options)` dispatches to the correct bridge

### Complete Working Example

```typescript
import { BotRegistry } from '@maka/runtime/bots/bot-registry';

const registry = new BotRegistry({
  onIncomingMessage: (msg) => console.log('From', msg.platform, ':', msg.text),
  onStatusChange: (status) => console.log(status.platform, 'is', status.state),
});

// Apply configuration for multiple platforms
await registry.applySettings({
  channels: {
    slack: { enabled: true, token: 'xoxb-…', appSecret: 'xapp-…' },
    discord: { enabled: true, token: 'Bot …' },
  },
});

// Send to either platform identically
await registry.sendMessage('slack', 'C12345678', 'Hello Slack!');
await registry.sendMessage('discord', '987654321012345678', 'Hello Discord!');

```

## Key Architectural Decisions in Maka's Messaging Integration

**Protocol abstraction strength** – The `BotMessageEvent` neutral format decouples business logic from platform specifics. Fields like `platform`, `chatId`, `messageId`, and `threadId` mean runtime code never branches on `if (platform === 'slack')`.

**Connection strategy divergence** – Slack uses **Socket Mode** (managed WebSocket library), while Discord requires **manual gateway implementation**. Both resolve to the same event emitter pattern via their bridges.

**Error handling scope** – Platform-specific concerns (Discord rate limits, Slack token rotation) stay encapsulated in bridges. The registry only sees `statusChange` events: `connecting`, `connected`, `disconnected`, `error`.

## Summary

- Maka's **Bot Bridge** pattern in `packages/runtime/src/bots/` unifies Slack, Discord, and future platforms under one interface
- **SlackBotBridge** uses `@slack/socket-mode` and `@slack/web-api` with automatic thread context via `thread_ts`
- **DiscordBotBridge** extends `GatewayBridgeBase` for manual gateway management, plus automatic message chunking and rate-limit handling
- **BotRegistry** provides the central integration point with `applySettings()` for configuration and `sendMessage()` for unified outbound delivery
- Adding new messaging platforms requires only implementing the four-method `BotBridge` interface

## Frequently Asked Questions

### How do I add a new messaging platform to Maka?

Implement the **BotBridge** interface in a new class following the `SlackBotBridge` and `DiscordBotBridge` patterns. Your bridge must handle connection lifecycle, transform incoming events to `BotMessageEvent`, and implement `sendMessage()` for outbound delivery. Register it in `BotRegistry`'s instantiation logic, and it automatically participates in the unified event system.

### Does Maka support Slack's HTTP Event Subscriptions instead of Socket Mode?

The current `SlackBotBridge` in [`packages/runtime/src/bots/slack-bridge.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bots/slack-bridge.ts) exclusively uses **Socket Mode** via `@slack/socket-mode`. HTTP Event Subscriptions would require a separate bridge implementation handling HTTP POST requests and signature verification instead of WebSocket connections.

### How does Maka handle Discord's strict rate limits?

The `DiscordBotBridge` implements rate-limit awareness in `classifyDiscordSendResponse()`, which parses Discord's `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and `Retry-After` headers. The bridge can queue or retry requests based on these values, though the exact retry strategy depends on your runtime configuration.

### Can I use multiple Slack workspaces or Discord bots simultaneously?

Yes. The **BotRegistry** supports multiple bridge instances of the same platform type through distinct configuration keys. Each workspace or bot requires its own entry in `settings.channels` with unique tokens, and the registry instantiates separate `SlackBotBridge` or `DiscordBotBridge` instances for each.