一文看懂OpenClaw是如何处理飞书消息任务的

一、飞书消息任务流程分析

把整个系统想象成一个「餐厅」

scss 复制代码
用户 ──────► 飞书服务器 ──► OpenClaw Gateway ──► AI Agent ──► 飞书服务器 ──► 用户
            (外卖平台)       (餐厅前台)          (后厨)         (外卖平台)

1. 消息接收:「接单」

场景: 顾客在外卖平台下单

scss 复制代码
用户发送消息
        │
        ▼
   飞书服务器 ──收到订单──► OpenClaw Gateway
   (外卖平台)                (餐厅前台)

做了什么:

  • 飞书服务器收到用户消息
  • 通过 WebSocketWebhook 推送给 OpenClaw
  • 就像外卖平台把订单推送给餐厅

关键文件: extensions/feishu/src/monitor.transport.ts


2. 消息验证:「验单」

场景: 前台收到订单,检查订单是否有效

scss 复制代码
inboundDebouncer.enqueue()  ── 消息去重/防抖
        │
        ▼
handleFeishuMessage()      ── 解析消息 + 权限检查
        │
        ├── 是群聊?需要 @ 机器人吗?
        ├── 用户在白名单吗?
        └── 机器人有没有回复权限?

关键文件: extensions/feishu/src/bot.ts


3. 路由到 Agent:「分单到后厨」

场景: 前台确认订单有效,交给后厨

scss 复制代码
dispatchReplyFromConfig()  ── 消息分发给 AI
        │
        ▼
getReplyFromConfig()      ── 准备做饭(加载会话、解析指令)
        │
        ▼
runPreparedReply()        ── 把食材准备好

关键文件: src/auto-reply/reply/dispatch-from-config.ts


4. AI 处理:「炒菜」

场景: 后厨开始做菜

scss 复制代码
runReplyAgent()            ── 启动做菜流程
        │
        ▼
runEmbeddedPiAgent()      ── 调用 AI 模型
        │
        ▼
        ┌─────────────────────────────┐
        │        AI 模型              │
        │   "分析消息,生成回复"       │
        └─────────────────────────────┘

AI 做了什么:

  • 理解用户说的话
  • 查看对话历史(记忆)
  • 生成合适的回复

关键文件: src/agents/pi-embedded.ts


5. 回复发送:「出餐」

场景: 菜做好了,交给外卖小哥

scss 复制代码
ReplyPayload 生成         ── 装盘
        │
        ▼
sendMessageFeishu()       ── 发送文本消息
        或
sendCardFeishu()          ── 发送卡片消息(带格式)
        或
FeishuStreamingSession    ── 流式发送(边做边上菜)
        │
        ▼
飞书 API                  ── 外卖小哥取餐
        │
        ▼
   用户收到回复

关键文件: extensions/feishu/src/send.ts


完整流程图

bash 复制代码
用户: "帮我翻译 Hello"
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ 第一步:接单(消息接收)                                      │
│                                                             │
│   飞书服务器 ─── WebSocket/Webhook ───► OpenClaw Gateway    │
│                                                             │
│   📁 extensions/feishu/src/monitor.transport.ts              │
└─────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ 第二步:验单(权限检查)                                      │
│                                                             │
│   - 是群聊吗?需要 @ 我吗?                                   │
│   - 用户有没有权限?                                          │
│   - 机器人能不能回复?                                        │
│                                                             │
│   📁 extensions/feishu/src/bot.ts                           │
└─────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ 第三步:分单(路由到 Agent)                                  │
│                                                             │
│   dispatchReplyFromConfig()                                 │
│                                                             │
│   📁 src/auto-reply/reply/dispatch-from-config.ts           │
└─────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ 第四步:炒菜(AI 处理)                                       │
│                                                             │
│   ┌─────────────────────────────────────────┐              │
│   │  AI 模型: "Hello" → "你好"              │              │
│   └─────────────────────────────────────────┘              │
│                                                             │
│   📁 src/agents/pi-embedded.ts                             │
└─────────────────────────────────────────────────────────────┘
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ 第五步:出餐(发送回复)                                      │
│                                                             │
│   sendMessageFeishu() ───► 飞书 API ───► 用户               │
│                                                             │
│   📁 extensions/feishu/src/send.ts                         │
└─────────────────────────────────────────────────────────────┘
       │
       ▼
用户: "你好"

二、飞书消息任务源码分析

1. 飞书 Extension 入口和消息接收点

关键文件:

  • extensions/feishu/src/channel.ts - 飞书 channel 插件主入口
  • extensions/feishu/src/monitor.ts - 消息监控入口
  • extensions/feishu/src/monitor.transport.ts - WebSocket/Webhook 传输层
  • extensions/feishu/src/monitor.account.ts - 单账号消息处理

消息接收流程:

scss 复制代码
Gateway 启动
    │
    ▼
monitorFeishuProvider() [monitor.ts:31]
    │
    ├── monitorSingleAccount() [monitor.account.ts:634]
    │       │
    │       ├── fetchBotIdentityForMonitor() - 获取机器人身份
    │       ├── warmupDedupFromDisk() - 加载去重缓存
    │       ├── createEventDispatcher() - 创建 Lark SDK 事件分发器
    │       ├── registerEventHandlers() - 注册事件处理器
    │       │
    │       └── 根据 connectionMode 选择传输方式:
    │               │
    │               ├── WebSocket: monitorWebSocket() [monitor.transport.ts:84]
    │               │               └── wsClient.start({ eventDispatcher })
    │               │
    │               └── Webhook: monitorWebhook() [monitor.transport.ts:129]
    │                               └── HTTP Server 处理 webhook 请求

事件注册点 [monitor.account.ts:410-619]:

typescript 复制代码
eventDispatcher.register({
  "im.message.receive_v1": ...     // 接收消息
  "im.message.reaction.created_v1": ...  // 表情反应
  "im.message.reaction.deleted_v1": ...  // 删除反应
  "application.bot.menu_v6": ...         // Bot 菜单
  "card.action.trigger": ...             // 卡片交互
})

2. 消息如何路由到 Agents

关键文件:

  • extensions/feishu/src/bot.ts - 消息处理和路由核心逻辑
  • extensions/feishu/src/policy.ts - 权限策略检查
  • extensions/feishu/src/session-route.ts - Session 路由解析

路由流程:

scss 复制代码
im.message.receive_v1 事件
    │
    ▼
inboundDebouncer.enqueue() [monitor.account.ts:419] - 消息去重/防抖
    │
    ▼
handleFeishuMessage() [bot.ts:221]
    │
    ├── finalizeFeishuMessageProcessing() - 去重确认
    ├── parseFeishuMessageEvent() - 解析消息内容
    │
    ├── 权限检查:
    │   ├── 群组检查: isFeishuGroupAllowed() - 检查 groupAllowFrom
    │   ├── DM 检查: resolveFeishuAllowlistMatch() - 检查 dmPolicy
    │   └── 配对检查: createChannelPairingController() - 处理未配对用户
    │
    ├── 消息路由:
    │   ├── resolveAgentRoute() - 解析 agent 路由
    │   ├── resolveConfiguredBindingRoute() - ACP 会话绑定
    │   └── buildFeishuAgentBody() - 构建发送给 agent 的消息体
    │
    └── dispatchReplyFromConfig() [dispatch-from-config.ts:149]
            │
            └── getReplyFromConfig() [get-reply.ts:106]
                    │
                    └── 传递给 Agent 执行

消息解析 [bot.ts:130-174]:

typescript 复制代码
parseFeishuMessageEvent(event, botOpenId, botName)
├── parseMessageContent() - 解析消息内容
├── checkBotMentioned() - 检查是否 @机器人
├── normalizeMentions() - 规范化提及
└── 返回 FeishuMessageContext

权限策略 [policy.ts]:

  • groupPolicy: "open" | "allowlist" - 群组策略
  • dmPolicy: "open" | "pairing" | "allowlist" - DM 策略
  • requireMention: 群组是否需要 @机器人才响应

3. Agent 如何处理并生成回复

关键文件:

  • src/auto-reply/reply/get-reply.ts - 回复生成入口
  • src/auto-reply/reply/get-reply-run.ts - 回复运行逻辑
  • src/auto-reply/reply/agent-runner.ts - Agent 执行器
  • src/auto-reply/reply/agent-runner-execution.ts - 实际 LLM 调用
  • src/agents/pi-embedded.ts - Embedded PI Agent

Agent 处理流程:

scss 复制代码
dispatchReplyFromConfig()
    │
    ├── 快速中止检查: tryFastAbortFromMessage()
    ├── 发送策略检查: resolveSendPolicy()
    ├── ACP 分发: tryDispatchAcpReply() - ACP 会话处理
    │
    └── getReplyFromConfig() [get-reply.ts:106]
            │
            ├── finalizeInboundContext() - 规范化上下文
            ├── applyMediaUnderstandingIfNeeded() - 媒体理解
            ├── applyLinkUnderstandingIfNeeded() - 链接理解
            ├── initSessionState() - 初始化会话状态
            ├── resolveReplyDirectives() - 解析指令
            │       ├── /think - 思考级别
            │       ├── /verbose - 详细模式
            │       └── /reset - 重置会话
            │
            └── runPreparedReply() [get-reply-run.ts:204]
                    │
                    ├── 构建 prompt
                    ├── 解析队列设置
                    └── runReplyAgent() [agent-runner.ts:110]
                            │
                            └── runAgentTurnWithFallback() [agent-runner-execution.ts:84]
                                    │
                                    └── runEmbeddedPiAgent() [pi-embedded.ts]
                                            │
                                            └── 调用 LLM API 生成回复

消息格式化 [bot.ts:176-219]:

typescript 复制代码
buildFeishuAgentBody()
├── 添加引用内容 [Replying to: "..."]
├── 添加发送者标识 "sender: message"
├── 添加提及提示 [System: ...]
└── 添加消息 ID [message_id: xxx]

4. 回复如何传回飞书

关键文件:

  • extensions/feishu/src/reply-dispatcher.ts - 回复分发器
  • extensions/feishu/src/send.ts - 消息发送
  • extensions/feishu/src/outbound.ts - 出站适配器
  • extensions/feishu/src/streaming-card.ts - 流式卡片

回复发送流程:

scss 复制代码
Agent 生成 ReplyPayload
    │
    ▼
createFeishuReplyDispatcher() [reply-dispatcher.ts:95]
    │
    ├── 创建 typing controller (打字指示器)
    └── 创建 ReplyDispatcher
            │
            ├── dispatcher.sendToolResult() - 工具结果
            ├── dispatcher.sendBlockReply() - 块回复(流式)
            └── dispatcher.sendFinalReply() - 最终回复
                    │
                    ▼
            reply-dispatcher.ts deliver()
                    │
                    ├── 流式卡片: streaming.start() / streaming.update() / streaming.close()
                    │           或
                    ├── 文本卡片: sendStructuredCardFeishu()
                    │           或
                    └── 纯文本: sendMessageFeishu()
                            │
                            ▼
                    sendReplyOrFallbackDirect() [send.ts:121]
                            │
                            ├── 尝试回复: client.im.message.reply()
                            └── 失败时直接发送: client.im.message.create()

发送函数链 [send.ts]:

typescript 复制代码
sendMessageFeishu() 
    → sendReplyOrFallbackDirect()
        → client.im.message.reply() (回复)
        → client.im.message.create() (直接发送)
        
sendStructuredCardFeishu()
    → sendCardFeishu()
        → sendReplyOrFallbackDirect()

sendMediaFeishu() [media.ts]
    → 上传媒体到飞书
    → 发送消息

流式卡片 [streaming-card.ts]:

typescript 复制代码
FeishuStreamingSession
├── start() - 创建卡片消息
├── update() - 更新卡片内容(partial)
└── close() - 关闭并发送最终内容

完整消息流时序图

css 复制代码
┌─────────────────────────────────────────────────────────────────────────┐
│                           飞书服务器                                     │
│  im.message.receive_v1 event ──────────────────────────────────────┐   │
└─────────────────────────────────────────────────────────────────────┼───┘
                                                                      │
                    WebSocket / Webhook                                ▼
┌───────────────────────────────────────────────────────────────────────────┐
│                          OpenClaw Gateway                                │
│                                                                           │
│  monitor.ts: monitorFeishuProvider()                                      │
│       │                                                                  │
│       ▼                                                                  │
│  monitor.account.ts: monitorSingleAccount()                               │
│       │                                                                  │
│       ▼                                                                  │
│  monitor.account.ts: registerEventHandlers()                              │
│       │  注册 im.message.receive_v1                                       │
│       ▼                                                                  │
│  monitor.account.ts: inboundDebouncer.enqueue()                            │
│       │  消息防抖/去重                                                    │
│       ▼                                                                  │
│  bot.ts: handleFeishuMessage()                                           │
│       │  - 解析消息                                                       │
│       │  - 权限检查                                                       │
│       │  - 路由解析                                                       │
│       ▼                                                                  │
│  dispatch-from-config.ts: dispatchReplyFromConfig()                       │
│       │  - 插件钩子                                                       │
│       │  - 快速中止检查                                                   │
│       │  - ACP 分发                                                       │
│       ▼                                                                  │
│  get-reply.ts: getReplyFromConfig()                                      │
│       │  - 会话初始化                                                     │
│       │  - 指令解析                                                       │
│       ▼                                                                  │
│  get-reply-run.ts: runPreparedReply()                                     │
│       │  - 构建 prompt                                                   │
│       ▼                                                                  │
│  agent-runner.ts: runReplyAgent()                                        │
│       │                                                                  │
│       ▼                                                                  │
│  agent-runner-execution.ts: runAgentTurnWithFallback()                    │
│       │  - 模型选择                                                       │
│       │  - 错误重试                                                       │
│       ▼                                                                  │
│  pi-embedded.ts: runEmbeddedPiAgent()                                    │
│       │  LLM API 调用                                                     │
│       ▼                                                                  │
│  ┌───────────────────────────────────────────────────────────────────┐    │
│  │                        AI Model                                    │    │
│  └───────────────────────────────────────────────────────────────────┘    │
│       │                                                                  │
│       ▼                                                                  │
│  ReplyPayload 生成                                                       │
│       │                                                                  │
│       ▼                                                                  │
│  reply-dispatcher.ts: createFeishuReplyDispatcher()                       │
│       │  - 创建 typing controller                                        │
│       │  - 处理流式/块/最终回复                                           │
│       ▼                                                                  │
│  send.ts: sendMessageFeishu() / sendStructuredCardFeishu()               │
│       │                                                                  │
│       ▼                                                                  │
│  client.im.message.reply() / client.im.message.create()                   │
│       │  调用飞书 API                                                     │
└───────────────────────────────────────────────────────────────────────────┘
                                                                      │
                    飞书 API                                               ▼
┌───────────────────────────────────────────────────────────────────────────┐
│                           飞书服务器                                     │
│                        消息发送到用户                                    │
└───────────────────────────────────────────────────────────────────────────┘

关键文件路径汇总

阶段 文件路径 核心函数
Channel 入口 extensions/feishu/src/channel.ts feishuPlugin - 插件定义
监控启动 extensions/feishu/src/monitor.ts monitorFeishuProvider()
单账号监控 extensions/feishu/src/monitor.account.ts monitorSingleAccount(), registerEventHandlers()
传输层 extensions/feishu/src/monitor.transport.ts monitorWebSocket(), monitorWebhook()
消息处理 extensions/feishu/src/bot.ts handleFeishuMessage(), parseFeishuMessageEvent()
权限策略 extensions/feishu/src/policy.ts resolveFeishuReplyPolicy(), isFeishuGroupAllowed()
回复分发 extensions/feishu/src/reply-dispatcher.ts createFeishuReplyDispatcher()
消息发送 extensions/feishu/src/send.ts sendMessageFeishu(), sendCardFeishu()
出站适配 extensions/feishu/src/outbound.ts feishuOutbound
流式卡片 extensions/feishu/src/streaming-card.ts FeishuStreamingSession
核心分发 src/auto-reply/reply/dispatch-from-config.ts dispatchReplyFromConfig()
回复生成 src/auto-reply/reply/get-reply.ts getReplyFromConfig()
Agent 运行 src/auto-reply/reply/agent-runner.ts runReplyAgent()
LLM 执行 src/auto-reply/reply/agent-runner-execution.ts runAgentTurnWithFallback()
相关推荐
岛雨QA2 小时前
Skill学习指南🧑‍💻
人工智能·agent·ai编程
小仓桑3 小时前
【Agent智能体项目实战五】LangChain访问阿里云嵌入模型
langchain·agent
熊猫钓鱼>_>4 小时前
WorkBuddy使用心得:腾讯版“免部署小龙虾“的办公新体验
人工智能·ai·腾讯云·agent·wechat·openclaw·workbuddy
蔚天灿雨4 小时前
Kage:在 Codex、Claude 和 QoderCLI 等 CodingAgentCLI 之间 Fork 与迁移 Session
人工智能·ai·agent·ai编程
小仓桑6 小时前
【Agent智能体项目实战三】LangChain调用通义千问保姆级教程
数据库·阿里云·langchain·agent
zabr7 小时前
花了 100+ 篇笔记,我整理出 了一套 AI Agent 工程完全指南
前端·后端·agent
MIka8 小时前
CopilotKit 入门:用 Runtime 和 React Core 搭建真正可用的 AI Copilot
人工智能·typescript·agent
16Miku8 小时前
Mapping-Skill:把 AI/ML 人才搜索、作者挖掘与个性化触达整合成一条工作流
爬虫·ai·飞书·agent·skill·openclaw·龙虾
墨渊君9 小时前
OpenClaw 上手实践: 使用 Docker 从构建到可用全流程指南
前端·agent