IM 渠道

Cell 内的 IM 通道集成,支持企业微信、飞书、钉钉等平台的消息收发。


渠道概念

每个 Cell 拥有独立的 IM 渠道集合。渠道是 per-cell 装配——不同部门 Cell 连接各自的企业微信 bot、飞书应用等。

支持的平台:

平台类型
企业微信wecom
飞书feishu
钉钉dingtalk
自定义 Webhookwebhook

Cell 之间的 IM 消息物理隔离——不同 credentials 不可能收到对方消息。


CellSpec.Channels 声明

CellSpec.Channels 是出生声明(INV-SEED-01):

spec := wesgine.CellSpec{
    Channels: []channel.Config{
        {
            Platform:  "wecom",
            CorpID:    "wxLegal...",
            AgentID:   1000001,
            SecretRef: config.SecretRef{Source: "env", Name: "WECOM_SECRET"},
        },
    },
}

注意:Channels 与 MCPs 没有运行时存储——spec 就是那唯一一份副本,故 spec 权威。这与 Cron/Email 不同(它们有运行时存储)。


Channel API

渠道管理

方法路径说明
GET/channels渠道列表
POST/channels注册/更新渠道
DELETE/channels/{platform}/{account}删除渠道

绑定管理

方法路径说明
GET/channels/bindings绑定列表
PUT/channels/bindings替换绑定

消息操作

方法路径说明
POST/channels/preflight预检验证
POST/channels/send发送消息
GET/channels/eventsSSE 事件流

SDK 调用

// 列出
channels, err := cell.Channels().List(ctx)

// 注册
err := cell.Channels().Register(ctx, channel.Config{
    Platform: "feishu",
    AppID:    "cli_xxx",
    // ...
})

// 发送
err := cell.Channels().Send(ctx, channel.SendRequest{
    Platform: "wecom",
    Target:   "user123",
    Content:  "你好,这是 AI 助手的消息",
})

// SSE 事件流
events := cell.Channels().Events(ctx)

Webhook 路由

IM 平台的回调消息通过 Webhook 路由到对应 Cell:

方法路径说明
POST/webhook/wecom企业微信回调
POST/webhook/feishu飞书回调
POST/webhook/dingtalk钉钉回调

多租户路由

多租户部署时,每个部门 Cell 需要独立的 callback URL:

POST /cells/dept-legal/webhook/wecom
POST /cells/dept-audit/webhook/feishu
POST /cells/dept-sales/webhook/dingtalk

Gateway 从 URL path 提取 cellID,分发到对应 Cell 处理。


渠道绑定

渠道绑定将 Agent 与 IM 平台账号关联:

cell.Channels().SetBindings(ctx, []channel.Binding{
    {
        Platform:  "wecom",
        AccountID: "bot-legal",
        AgentID:   "agent-legal",
    },
})

收到消息后,Gateway 根据绑定关系确定由哪个 Agent 处理。


配额(INV-QUOTA-05)

MaxIMChannels 遵循外设配额统一规则:

规则说明
唯一增长点Channel 注册是唯一能让集合变大的地方
整体替换幂等UpdateSpec 的 Channels = append(nil, patch...) 对 cap 幂等
收缩不需要 cap删除渠道不触发配额检查
覆盖已有名字 delta=0upsert 是编辑手势,卡在上限的 Cell 必须还能轮换凭据
// 配额检查在唯一增长点
err := quotaFn(currentCount, delta)  // delta=1 新增, delta=0 覆盖

渠道事件流

GET /channels/events 返回 SSE 事件流,包含渠道相关的实时事件:

const eventSource = new EventSource('/cells/main/channels/events');
eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Channel event:', data.type, data.payload);
};

消费方集成示例

企业微信

# 在 CellSpec 或 TenantBootstrap 中声明
channels:
  - platform: wecom
    corp_id: "wx1234567890"
    agent_id: 1000001
    secret_ref: "env:WECOM_SECRET"
    token_ref: "env:WECOM_TOKEN"
    aes_key_ref: "env:WECOM_AES_KEY"

飞书

channels:
  - platform: feishu
    app_id: "cli_xxx"
    app_secret_ref: "env:FEISHU_APP_SECRET"
    verification_token_ref: "env:FEISHU_VERIFY_TOKEN"

最佳实践

  1. 每部门独立 callback URL:包含 cellID 避免歧义
  2. 凭据使用 SecretRef:不在配置文件中明文存放
  3. 绑定明确:每个 IM 账号绑定一个 Agent
  4. 事件流监听:通过 SSE 实时感知消息收发状态