适合谁: 不会写代码、第一次接触 PowerShell、飞书开放平台和 Codex 的读者。

最终效果:

  1. 你可以在 Codex 中说“读取我今天的飞书日程”,Codex 会通过 lark-cli 获取数据;
  2. 你可以直接打开飞书,给自己的机器人发消息,由 Codex 生成回答;
  3. 后续还可以扩展读取飞书文档、知识库、表格和任务。

本文环境: Windows 10/11、PowerShell、Node.js LTS、飞书国内版、Codex CLI/SDK


目录

       一、先理解:其实有两种“接入”

模式 A:Codex 访问飞书

模式 B:飞书里直接聊天

二、准备工作

2.1 需要准备什么

2.2 安装 Node.js

三、模式 A:让 Codex 读取飞书日程和文档

3.1 安装飞书官方 CLI

3.2 配置飞书应用

3.3 用户登录授权

3.4 测试读取日历

3.5 创建一个测试日程

3.6 以后如何申请其他权限

四、让 Codex App 正常调用 lark-cli

4.1 为什么要选择一个空文件夹

4.2 在 Codex App 中选择项目

4.3 设置审批方式

4.4 使用完整路径调用 lark-cli

五、模式 B:在飞书里创建 Codex 聊天机器人

5.1 打开飞书开放平台

5.2 添加机器人能力

5.3 开通消息权限

5.4 添加消息事件

5.5 可用范围

六、先做一个回声机器人,验证飞书通道

6.1 创建项目文件夹

6.2 使用本文附带的示例项目

6.3 创建 .env

6.4 先启动程序

6.5 回到飞书后台配置长连接

6.6 发布应用

6.7 测试回声

七、把回声机器人升级为真正的 Codex 机器人

7.1 安装 Codex CLI

7.2 安装 Codex SDK

7.3 核心代码解释

7.4 为什么事件处理器不能一直等 Codex

7.5 启动机器人

7.6 在飞书测试

7.7 为什么回复比 ChatGPT 慢

八、可选增强:读取并分析飞书文档

8.1 先在 PowerShell 测试文档读取

8.2 在飞书机器人中设计 /doc

8.3 可直接交给 Codex 的升级提示词

九、电脑重启后怎么恢复

9.1 如果 Codex 登录失效

9.2 如果机器人突然不回复

9.3 电脑休眠的影响

附录:可直接复制给 Codex 的提示词

A. 让 Codex 创建回声机器人

B. 将回声机器人升级为 Codex

C. 排查“/status 正常,普通消息没反应”

官方资料

结语


一、先理解:其实有两种“接入”

很多教程把两种需求,混在一起,导致小白越配越乱。

模式 A:Codex 访问飞书

入口仍然在 Codex App 或 Codex CLI

你对 Codex 说:

读取我今天的飞书日程,只读取,不修改。

执行链路:

Codex → lark-cli → 飞书 OpenAPI → 返回日程/文档/消息

这种模式适合:

  • 读取个人日历;
  • 搜索和总结飞书文档;
  • 操作多维表格、任务和消息;
  • 让 Codex 帮你处理飞书里的工作数据。

模式 B:飞书里直接聊天

入口在 飞书客户端

你给机器人发:

你好,你是谁?

执行链路:

飞书消息 → 本地 Node.js 机器人 → Codex SDK → 回答发送回飞书

这种模式适合:

  • 在飞书私聊中直接使用 Codex;
  • 给团队做内部智能助手;
  • 后续加入 /doc/calendar/task 等命令。

本文两种都做。建议严格按顺序:先完成模式 A,再完成模式 B。

二、准备工作

2.1 需要准备什么

  • 一台 Windows 电脑;
  • 一个可正常使用的飞书账号;
  • 能进入飞书开放平台开发者后台;
  • ChatGPT/Codex 可用账号;
  • 网络可以访问飞书和 OpenAI;
  • 约 30~60 分钟。

2.2 安装 Node.js

进入 Node.js 官方下载页面,选择 LTS 长期支持版安装。

Node.js 下载: https://nodejs.org/en/download

安装完成后,打开 PowerShell:

  1. 按键盘 Win
  2. 搜索 PowerShell
  3. 打开 Windows PowerShell;
  4. 执行:
node -v
npm -v

只要两条命令都能输出版本号,就说明安装成功。

如果提示“不是内部或外部命令”,关闭 PowerShell 后重新打开;仍无效则重装 Node.js,并确认安装器勾选了加入 PATH。

三、模式 A:让 Codex 读取飞书日程和文档

3.1 安装飞书官方 CLI

在 PowerShell 中执行:

npx @larksuite/cli@latest install

第一次会看到:

Need to install the following packages:
@larksuite/cli@...
Ok to proceed? (y)

输入:

y

然后回车。

安装完成后检查:

lark-cli --version

能显示版本号即成功。

如果提示找不到 lark-cli,关闭 PowerShell,重新打开再试。
也可以运行:

& "$env:APPDATA\npm\lark-cli.cmd" --version

3.2 配置飞书应用

执行:

lark-cli config init --new

终端会出现二维码或授权链接。打开链接,用飞书账号确认创建/配置应用。

成功后会看到类似:

OK:应用配置成功!

3.3 用户登录授权

执行:

lark-cli auth login --recommend

根据终端链接完成授权,然后检查:

lark-cli auth status

用户授权的意义是:CLI 可以以“你的飞书用户身份”访问你有权限查看的日历、文档和消息。

3.4 测试读取日历

运行:

lark-cli calendar +agenda

第一次可能出现:

{
  "ok": false,
  "error": {
    "subtype": "missing_scope",
    "missing_scopes": [
      "calendar:calendar.event:read"
    ]
  }
}

这不是安装失败,而是缺少日历读取权限。按错误中给出的 scope 补授权:

lark-cli auth login --scope "calendar:calendar.event:read"

浏览器同意后,检查:

lark-cli auth check --scope "calendar:calendar.event:read"

成功结果应包含:

{
  "granted": ["calendar:calendar.event:read"],
  "missing": null,
  "ok": true
}

再次执行:

lark-cli calendar +agenda

如果结果是:

{
  "ok": true,
  "data": []
}

这代表命令成功,只是今天没有日程,并不是报错。

3.5 创建一个测试日程

打开飞书客户端:

  1. 点击左侧“日历”;
  2. 点击今天尚未过去的时间段;
  3. 标题填写 Codex 测试日程
  4. 时间设置为 30 分钟;
  5. 保存。

回到 PowerShell:

lark-cli calendar +agenda

这次应看到:

  • summary:日程标题;
  • start_time:开始时间;
  • end_time:结束时间;
  • count:日程数量。

到这里,飞书 CLI 已经可以读取你的飞书数据

3.6 以后如何申请其他权限

推荐按业务域授权:

# 日历
lark-cli auth login --domain calendar

# 文档
lark-cli auth login --domain docs

# 日历 + 文档 + 任务
lark-cli auth login --domain calendar,docs,task

查看当前状态:

lark-cli auth status

检查指定权限:

lark-cli auth check --scope "某个具体scope"

遇到 missing_scope 时,永远先看错误里的 missing_scopes,不要盲目一次开通所有权限。


四、让 Codex App 正常调用 lark-cli

4.1 为什么要选择一个空文件夹

Codex App 的“项目”本质是一个本地工作目录。即使你只是读取飞书日程,也建议新建一个空文件夹,例如:

C:\Codex-Feishu

或桌面上的:

C:\Users\你的用户名\Desktop\Codex-Feishu

空文件夹不会存放你的飞书日程,它只是让 Codex 有一个安全、隔离的运行目录。

4.2 在 Codex App 中选择项目

打开 Codex App,点击 Choose project,选择刚才的空文件夹。

4.3 设置审批方式

在输入框左下角找到“请求批准”下拉菜单。

建议:

  • 初次使用:选择 请求批准
  • 频繁执行低风险命令:可选择 替我审批
  • 不要为了省事长期给无限制系统权限。

4.4 使用完整路径调用 lark-cli

把下面内容发给 Codex:

请执行以下只读命令:

& "$env:APPDATA\npm\lark-cli.cmd" calendar +agenda

读取我今天的飞书日程,不创建、修改或删除任何内容。

使用完整路径有两个好处:

  1. 避免 Codex 找不到命令别名;
  2. 避免中文 Windows 用户名造成路径识别问题。

成功后,Codex 会整理日程并回复你。

以后可以直接说:

使用飞书 CLI 读取我明天的日程,按时间顺序整理,不要修改任何内容。

或者:

使用飞书 CLI 搜索我最近修改的飞书文档,只列标题和更新时间。

注意: “Codex 能访问飞书”不等于“飞书里已经有 Codex 机器人”。
下一部分才是把 Codex 放进飞书聊天窗口。


五、模式 B:在飞书里创建 Codex 聊天机器人

5.1 打开飞书开放平台

进入飞书开放平台开发者后台,打开刚才配置的自建应用。

5.2 添加机器人能力

左侧进入:

应用能力 → 添加应用能力 → 机器人

如果已经添加成功:

  • 左侧“机器人”会高亮;
  • 页面会显示“机器人”配置;
  • 右上角会出现“删除能力”。

5.3 开通消息权限

进入:

开发配置 → 权限管理

至少需要下面的能力。飞书后台的中文名称可能随版本微调,搜索权限代码或关键词即可。

im:message:send_as_bot

用途:机器人发送消息。

im:message.p2p_msg:readonly

用途:接收用户发给机器人的单聊消息。

如果需要群聊中 @机器人,再添加:

im:message.group_at_msg:readonly

部分后台会把权限合并为“获取与发送单聊、群组消息”等组合权限,以页面实际展示为准。

5.4 添加消息事件

进入:

开发配置 → 事件与回调

后面要添加:

im.message.receive_v1

即“接收消息”事件。

先不要急着保存长连接订阅方式。 我们先在本机把机器人程序启动起来。

以下是已添加过的事件:

5.5 可用范围

进入版本或应用发布配置,将可用范围设置为你自己。

个人测试时建议:

  • 仅包含你本人;
  • 关闭“允许机器人被添加到外部群”;
  • 关闭“允许外部用户与机器人单聊”。

六、先做一个回声机器人,验证飞书通道

为什么不直接上 Codex?

因为排错时必须把问题拆开:

  1. 飞书能否把消息推到电脑;
  2. 电脑能否回复飞书;
  3. Codex 能否生成回答。

先做回声机器人,可以证明前两项正常。

6.1 创建项目文件夹

例如在桌面创建一个空白文件夹命名为abc:

abc

推荐使用更明确的名字:

Feishu-Codex-Bot

进入该文件夹,在顶部地址栏输入:

powershell

回车后,PowerShell 会自动在当前文件夹打开。

你会看到类似:

PS C:\Users\你的用户名\Desktop\Feishu-Codex-Bot>

6.2 使用本文附带的示例项目

下载本文压缩包后,里面有:

sample-bot/
├─ package.json
├─ .env.example
├─ .gitignore
├─ start-bot.bat
└─ src/
   └─ index.js

你可以直接把 sample-bot 文件夹复制到桌面。

安装依赖:

npm install

6.3 创建 .env

执行:

Copy-Item .env.example .env
notepad .env

填写:

LARK_APP_ID=你的App ID
LARK_APP_SECRET=你的App Secret
ALLOWED_OPEN_ID=你的Open ID
CODEX_MODEL=
CODEX_TIMEOUT_MS=120000
App ID 和 App Secret 在哪

飞书开放平台:

凭证与基础信息
Open ID 在哪

在 PowerShell 中执行:

lark-cli auth status

寻找 ou_ 开头的用户 ID。

不要截图 .env
App Secret、Token 和 Codex 登录凭据都不应该出现在博客、聊天、GitHub 或工单中。

确认 .gitignore 至少包含:

.env
node_modules/

6.4 先启动程序

执行:

npm run dev

看到类似:

正在建立飞书 WebSocket 长连接。

说明程序已经开始连接。

这个窗口要保持开启。

6.5 回到飞书后台配置长连接

此时回到:

事件与回调 → 事件配置

选择:

使用长连接接收事件

保存,然后添加事件:

im.message.receive_v1

长连接模式的优点是:

  • 本地电脑即可接收事件;
  • 不需要公网 IP;
  • 不需要域名;
  • 不需要内网穿透。

6.6 发布应用

进入:

版本管理与发布 → 创建版本

更新说明可写:

新增机器人消息接收与回复能力

提交并发布,确保可用范围包含你本人。

6.7 测试回声

在飞书搜索机器人,发送:

你好

回声机器人应回复:

收到:你好

如果能收到回声,说明以下链路全部正常:

飞书消息
→ im.message.receive_v1
→ WebSocket 长连接
→ 本地 Node.js 程序
→ 飞书发送消息 API
→ 回复出现在飞书

七、把回声机器人升级为真正的 Codex 机器人

7.1 安装 Codex CLI

在项目文件夹 PowerShell 中执行:

npm install -g @openai/codex

然后运行:

codex

首次运行会提示登录。选择使用 ChatGPT 账号登录,浏览器完成授权。

出现 Codex 交互界面即表示登录成功。

按:

Ctrl + C

退出 Codex 交互界面。

登录状态通常会被本地缓存,之后重启电脑不必每次登录。

7.2 安装 Codex SDK

示例项目的 package.json 已经包含 SDK。执行:

npm install

检查 JavaScript 语法:

npm run check

7.3 核心代码解释

本文附带的 sample-bot/src/index.js 已实现:

  • 飞书 WebSocket 长连接;
  • im.message.receive_v1
  • ALLOWED_OPEN_ID 白名单;
  • 消息去重;
  • 忽略机器人自身消息;
  • 每个 chat_id 独立 Codex Thread;
  • /status
  • /clear
  • 长回答分段;
  • 同一会话串行处理;
  • Codex read-only 沙箱;
  • approvalPolicy: "never"
  • 移除 Codex 子进程中的飞书密钥;
  • 错误脱敏。

最核心的 Codex 调用只有几行:

import { Codex } from "@openai/codex-sdk";

const codex = new Codex();
const thread = codex.startThread({
  workingDirectory: process.cwd(),
  skipGitRepoCheck: true,
  sandboxMode: "read-only",
  approvalPolicy: "never",
});

const turn = await thread.run("你好,你是谁?");
console.log(turn.finalResponse);

同一个 Thread 再次调用 run(),就能延续上下文。

7.4 为什么事件处理器不能一直等 Codex

飞书长连接事件处理有时限。Codex 生成回答可能需要几十秒,如果在事件回调里一直 await thread.run(),飞书可能认为处理超时并重推事件。

因此示例代码采用:

void enqueue(chatId, () => handleUserText(chatId, text));
return {};

也就是:

  1. 收到事件后立即登记去重;
  2. 把任务放进队列;
  3. 立刻结束事件处理;
  4. 后台慢慢调用 Codex;
  5. 最后通过发送消息接口回复。

这是避免重复回复和事件超时的关键。

7.5 启动机器人

如果旧程序正在运行,先按:

Ctrl + C

然后启动:

npm start

保持窗口开启。

7.6 在飞书测试

先发:

/status

应看到类似:

飞书长连接正常;Codex SDK 已初始化。

再发:

你好,你是谁?

正常情况下,机器人会先回复:

正在处理,请稍候……

随后返回 Codex 的回答。

测试连续上下文:

给我解释什么是地震反演。

等回答后再发:

用更简单的话再解释一遍。

如果机器人理解“再解释一遍”指上一条内容,说明 Thread 连续对话正常。

清除上下文:

/clear

7.7 为什么回复比 ChatGPT 慢

你的链路比直接聊天多了几层:

飞书 → 本地机器人 → Codex CLI 子进程 → 模型推理 → 本地机器人 → 飞书

而且 Codex 是偏工程任务的 Agent,会进行更多上下文和工具准备。

提速建议:

  • 一次只发一条,等回复后再发下一条;
  • 简短问题使用更轻量的模型;
  • 不要让同一个 chat_id 同时并发多个任务;
  • 保留“正在处理”提示;
  • 设置超时;
  • 不需要文件分析时保持只读和禁用额外工具。

八、可选增强:读取并分析飞书文档

8.1 先在 PowerShell 测试文档读取

先看当前版本命令帮助:

lark-cli docs +fetch --help

常见用法类似:

lark-cli docs +fetch --doc "飞书文档链接" --as user --format pretty

由于 CLI 更新较快,以你本机 --help 的参数为准

如果缺权限,按错误中的 missing_scopes 重新授权。

8.2 在飞书机器人中设计 /doc

理想用法:

/doc https://你的租户.feishu.cn/docx/xxxxx
请总结核心结论,并指出三处逻辑问题。

安全实现必须做到:

  • 只允许飞书/Lark 合法域名;
  • 用 execFile 或 spawn 调用 CLI;
  • 禁止把用户输入拼接成任意 shell 命令;
  • 只读,不更新原文档;
  • 不把完整文档写进日志;
  • 长文档分块总结;
  • 缺权限时明确返回 scope;
  • 设置读取和分析超时。

8.3 可直接交给 Codex 的升级提示词

请在当前飞书 Codex 机器人中增加“读取飞书文档并分析”的功能。

要求:
1. 保留现有长连接、Codex Thread、白名单、去重、/status、/clear。
2. 支持 /doc <飞书文档链接> <分析要求>。
3. 普通消息包含飞书 docx/docs/wiki 链接时也自动识别。
4. 先实际运行 lark-cli docs +fetch --help,以本机版本真实参数为准。
5. Node.js 调用 lark-cli 必须使用 execFile 或 spawn,禁止 shell 拼接。
6. 仅允许合法飞书/Lark 文档域名,防止命令注入。
7. 以 user 身份只读获取文档,不创建、修改、删除、分享文档。
8. 读取成功后把标题、正文和分析要求提交给 Codex。
9. 长文档分块提取要点,再生成整体分析,不要只截取开头。
10. 缺权限时回复缺少的 scope。
11. 不输出正文到控制台,不输出 .env、Token、App Secret。
12. 完成后做语法检查,不启动程序。

九、电脑重启后怎么恢复

正常情况下不需要重新:

  • 安装 Node.js;
  • 安装 lark-cli;
  • 创建飞书应用;
  • 配权限;
  • 配事件;
  • 发布应用;
  • 填写 .env
  • 登录 Codex。

每次开机只需要:

  1. 打开机器人项目文件夹;
  2. 地址栏输入 powershell
  3. 执行:
npm start
  1. 保持 PowerShell 窗口开启;
  2. 飞书里发送:
/status

也可以双击示例项目里的:

start-bot.bat

9.1 如果 Codex 登录失效

执行:

codex

按提示重新登录,登录成功后 Ctrl + C 退出,再运行:

npm start

9.2 如果机器人突然不回复

在运行窗口按:

Ctrl + C

再执行:

npm start

9.3 电脑休眠的影响

电脑关机、睡眠、休眠、断网时,本地 WebSocket 长连接会断开,机器人离线。

要实现全天在线,需要把项目部署到长期运行的 Windows 主机或服务器。部署到公网服务器时,要重新评估登录凭据、权限、日志和密钥存储方式,不要直接照搬个人电脑配置。

附录:可直接复制给 Codex 的提示词

A. 让 Codex 创建回声机器人

请在当前空文件夹中创建一个最小可运行的飞书长连接回声机器人。

要求:
1. 使用 Node.js 和 JavaScript。
2. 使用官方 @larksuiteoapi/node-sdk。
3. 使用 WebSocket 长连接,不用 Webhook,不需要公网服务器。
4. 监听 im.message.receive_v1。
5. 只处理文本消息。
6. 收到私聊后回复“收到:用户原消息”。
7. 忽略机器人自身消息,防止循环。
8. 使用 message_id 去重。
9. 支持 ALLOWED_OPEN_ID 白名单。
10. 使用 dotenv 读取 LARK_APP_ID、LARK_APP_SECRET、ALLOWED_OPEN_ID。
11. 创建 package.json、src/index.js、.env.example、.gitignore、README.md。
12. 不在日志中输出 App Secret、Token 或完整消息。
13. 自动 npm install 和语法检查。
14. 不读取或填写真实密钥,不启动程序。

B. 将回声机器人升级为 Codex

当前飞书回声机器人已经测试成功。

请升级为 Codex 智能机器人:
1. 安装并使用官方 @openai/codex-sdk。
2. 普通私聊文本提交给 Codex,最终回答回复到原聊天。
3. 每个 chat_id 维护独立 Thread。
4. 支持 /clear 与 /status。
5. 保留白名单、自身消息过滤、message_id 去重。
6. 长回答自动分段。
7. 同一 chat_id 串行处理,禁止上下文并发错乱。
8. 收到普通消息后立即回复“正在处理,请稍候……”。
9. 单次 Codex 调用设置 120 秒超时。
10. 使用 read-only 沙箱、approvalPolicy never、skipGitRepoCheck true。
11. Codex 子进程继承系统环境,但移除 LARK_APP_ID、LARK_APP_SECRET、ALLOWED_OPEN_ID。
12. 不输出 .env、Token、App Secret。
13. 完成后语法检查,不启动程序。

C. 排查“/status 正常,普通消息没反应”

飞书能够正常回复 /status,但普通消息调用 Codex 后没有响应。

请检查并修复:
1. thread.run() 前后记录脱敏日志。
2. 立即回复“正在处理,请稍候……”。
3. 使用 turn.finalResponse 作为最终文本。
4. Codex env 从 process.env 复制,只删除飞书密钥。
5. 保留 PATH、USERPROFILE、HOME、APPDATA、LOCALAPPDATA、TEMP、TMP、SYSTEMROOT、COMSPEC。
6. 增加 120 秒超时,超时必须回复用户。
7. 保留 read-only、approvalPolicy never、白名单、消息去重。
8. 事件回调快速返回,Codex 调用放到后台队列。
9. 完成后语法检查,不启动程序。

官方资料

结语

完成本文后,你得到的不只是一个“会聊天的飞书机器人”,而是一个可以继续扩展的本地 Agent 通道:

飞书负责入口与协作
Node.js 负责连接和权限边界
Codex 负责理解、推理与任务执行
lark-cli 负责读取和操作飞书数据

先保持私聊、白名单和只读。等稳定后,再逐步增加文档读取、日历汇总、任务摘要和多维表格能力。不要一开始就开满权限,也不要把高权限机器人直接放入大群。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐