Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
426 changes: 419 additions & 7 deletions content/docs/api-reference.mdx

Large diffs are not rendered by default.

342 changes: 336 additions & 6 deletions content/docs/architecture.mdx

Large diffs are not rendered by default.

260 changes: 254 additions & 6 deletions content/docs/channels.mdx
Original file line number Diff line number Diff line change
@@ -1,11 +1,259 @@
---
title: Channels
description: Stub page — content coming soon.
description: Connect workspaces to Telegram, Slack, and Lark/Feishu for social integrations.
---

> 🚧 **Coming soon.** The Documentation Specialist agent will populate this
> page on its next maintenance cycle.
## Overview

If you need this content urgently, open an issue on the
[docs repo](https://github.com/Molecule-AI/docs/issues/new) and the agent
will prioritise it on its next cron tick.
Channels let workspaces send and receive messages on social platforms. Each
workspace can have multiple channel integrations — a Telegram bot, a Slack
webhook, a Lark/Feishu Custom Bot — configured independently with per-channel
allowlists and JSONB config.

Outbound messages flow from the workspace through the platform adapter to the
social platform. Inbound messages arrive via webhooks (`POST /webhooks/:type`),
are parsed by the adapter, and forwarded to the workspace as A2A
`message/send` requests.

```
User (Telegram/Slack/Lark) ──webhook──> Platform ──A2A──> Workspace Agent
<──adapter── (response)
User <──bot message──────────────────────────────────────/
```

---

## Adapters

Three adapters are registered out of the box. Use `GET /channels/adapters` to
list them at runtime.

### Telegram

Uses the Telegram Bot API. Supports both long-polling (for inbound) and direct
API calls (for outbound). The adapter caches `BotAPI` instances to avoid
repeated `getMe` calls.

**Required config fields:**

| Field | Type | Description |
|-------|------|-------------|
| `bot_token` | string | Telegram bot token (`123456789:ABCdef...`). Validated against a strict regex. |
| `chat_id` | string | Comma-separated chat IDs to listen on and send to. |

**Features:**

- Long-polling with 30s timeout and 2s retry interval
- Auto-reply to `/start` with the chat ID (useful for setup)
- Bot commands: `/start`, `/help`, `/reset` (clear history), `/cancel` (best-effort)
- Long messages automatically split at paragraph/line/word boundaries (4096 char limit)
- Typing indicator sent while the agent processes
- Rate-limit handling with `retry_after` backoff
- Auto-discovers chats via `getUpdates` (including `my_chat_member` events for group adds)
- Auto-disables the channel when the bot is kicked from a chat

### Slack

Uses Slack Incoming Webhooks for outbound and the Slack Events API for inbound.

**Required config fields:**

| Field | Type | Description |
|-------|------|-------------|
| `webhook_url` | string | Slack Incoming Webhook URL (must start with `https://hooks.slack.com/`). |

**Features:**

- Outbound via Incoming Webhook (no OAuth required)
- Inbound via Events API JSON payload or slash command (URL-encoded form)
- `url_verification` challenge handshake supported
- Slash commands prepend the command name so the agent sees the full invocation

### Lark / Feishu

Outbound via Custom Bot webhooks, inbound via Event Subscriptions.

**Required config fields:**

| Field | Type | Description |
|-------|------|-------------|
| `webhook_url` | string | Custom Bot webhook URL. Must start with `https://open.feishu.cn/open-apis/bot/v2/hook/` or `https://open.larksuite.com/open-apis/bot/v2/hook/`. |

**Optional config fields:**

| Field | Type | Description |
|-------|------|-------------|
| `verify_token` | string | Verification Token from the app's Event Subscriptions page. When set, inbound events with a mismatching token are rejected. |

**Features:**

- Both China (`open.feishu.cn`) and international (`open.larksuite.com`) endpoints supported
- `url_verification` handshake with constant-time `verify_token` comparison
- v2 event payload parsing (`im.message.receive_v1`)
- Token verification on both `url_verification` and `event_callback` payloads
- Application-level error codes checked (Lark returns HTTP 200 even for app errors)

---

## Setup Flow

### 1. Create a Channel

```bash
curl -X POST http://localhost:8080/workspaces/{id}/channels \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {token}" \
-d '{
"type": "telegram",
"config": {
"bot_token": "123456789:ABCdefGHIjklmnopQRSTuvwxyz",
"chat_id": "-1001234567890"
}
}'
```

### 2. Test the Connection

```bash
curl -X POST http://localhost:8080/workspaces/{id}/channels/{channelId}/test \
-H "Authorization: Bearer {token}"
```

### 3. Send a Message

```bash
curl -X POST http://localhost:8080/workspaces/{id}/channels/{channelId}/send \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {token}" \
-d '{"text": "Hello from the agent!"}'
```

---

## Inbound Webhooks

Register your platform's public URL as the webhook endpoint for each social
platform. Inbound messages arrive at:

```
POST /webhooks/:type
```

where `:type` is `telegram`, `slack`, or `lark`. The platform:

1. Looks up all channels of that type
2. Calls the adapter's `ParseWebhook` to extract a standardized `InboundMessage`
3. Checks the allowlist (if configured)
4. Forwards the message to the workspace via A2A `message/send`

For Telegram, the platform can also use long-polling instead of webhooks,
started automatically when a Telegram channel is created.

---

## Discover Chats

Auto-detect available chats for a bot token before creating a channel:

```bash
curl -X POST http://localhost:8080/channels/discover \
-H "Content-Type: application/json" \
-d '{"type": "telegram", "bot_token": "123456789:ABCdef..."}'
```

Returns the bot username, discovered chats (with IDs, names, and types), and
whether the bot can read all group messages (Telegram privacy mode).

---

## Allowlists

Each channel row has an `allowed_users` JSONB array. When non-empty, only
messages from users whose IDs appear in the list are forwarded to the workspace.
All others are silently dropped.

---

## Config Encryption

Sensitive config fields (like `bot_token`) are encrypted at rest. The `List`
endpoint decrypts them server-side and masks tokens in the response
(showing only the first 4 and last 4 characters).

---

## API Reference

| Method | Path | Description |
|--------|------|-------------|
| GET | `/channels/adapters` | List available adapter types |
| POST | `/channels/discover` | Auto-detect chats for a bot token |
| GET | `/workspaces/:id/channels` | List channels for a workspace |
| POST | `/workspaces/:id/channels` | Add a channel |
| PATCH | `/workspaces/:id/channels/:channelId` | Update a channel |
| DELETE | `/workspaces/:id/channels/:channelId` | Remove a channel |
| POST | `/workspaces/:id/channels/:channelId/test` | Test connection |
| POST | `/workspaces/:id/channels/:channelId/send` | Send outbound message |
| POST | `/webhooks/:type` | Incoming social webhook |

---

## Example Configs

### Telegram

```json
{
"type": "telegram",
"config": {
"bot_token": "123456789:ABCdefGHIjklmnopQRSTuvwxyz_1234",
"chat_id": "-1001234567890"
}
}
```

Multiple chats (comma-separated):

```json
{
"type": "telegram",
"config": {
"bot_token": "123456789:ABCdefGHIjklmnopQRSTuvwxyz_1234",
"chat_id": "-1001234567890, -1009876543210"
}
}
```

### Slack

```json
{
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
}
}
```

### Lark / Feishu

```json
{
"type": "lark",
"config": {
"webhook_url": "https://open.larksuite.com/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"verify_token": "your-verification-token"
}
}
```

China endpoint:

```json
{
"type": "lark",
"config": {
"webhook_url": "https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
```
Loading