add-feishu

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Add Feishu Channel

添加飞书渠道

This skill adds Feishu (飞书/Lark) support to NanoClaw using the skills engine for deterministic code changes, then walks through interactive setup.
本技能通过技能引擎将飞书(Feishu/Lark)支持添加到NanoClaw中,实现确定性代码变更,并引导完成交互式配置流程。

Phase 1: Pre-flight

阶段1:准备工作

Check if already applied

检查是否已应用

Read
.nanoclaw/state.yaml
. If
feishu
is in
applied_skills
, skip to Phase 3 (Setup). The code changes are already in place.
读取
.nanoclaw/state.yaml
文件。如果
feishu
已在
applied_skills
列表中,则直接跳至阶段3(配置),说明代码变更已完成。

Ask the user

询问用户

Use
AskUserQuestion
to collect configuration:
AskUserQuestion: Do you have a Feishu (Lark) app already created, or do you need to create one?
If they have one, ask for the App ID and App Secret. If not, walk them through creation in Phase 3.
使用
AskUserQuestion
收集配置信息:
AskUserQuestion: 您是否已经创建了飞书(Lark)应用,还是需要创建新的应用?
如果用户已有应用,询问其App ID和App Secret。如果没有,则在阶段3引导用户创建。

Phase 2: Apply Code Changes

阶段2:应用代码变更

Run the skills engine to apply this skill's code package. The package files are in this directory alongside this SKILL.md.
运行技能引擎以应用本技能的代码包。代码包文件位于本SKILL.md所在的目录中。

Initialize skills system (if needed)

初始化技能系统(如需要)

If
.nanoclaw/
directory doesn't exist yet:
bash
npx tsx scripts/apply-skill.ts --init
如果
.nanoclaw/
目录尚未存在:
bash
npx tsx scripts/apply-skill.ts --init

Apply the skill

应用技能

bash
npx tsx scripts/apply-skill.ts .claude/skills/add-feishu
This deterministically:
  • Adds
    src/channels/feishu.ts
    (FeishuChannel class with self-registration via
    registerChannel
    )
  • Adds
    src/channels/feishu.test.ts
    (unit tests)
  • Appends
    import './feishu.js'
    to the channel barrel file
    src/channels/index.ts
  • Installs the
    @larksuiteoapi/node-sdk
    npm dependency
  • Updates
    .env.example
    with
    FEISHU_APP_ID
    and
    FEISHU_APP_SECRET
  • Records the application in
    .nanoclaw/state.yaml
If the apply reports merge conflicts, read the intent file:
  • modify/src/channels/index.ts.intent.md
    — what changed and invariants
bash
npx tsx scripts/apply-skill.ts .claude/skills/add-feishu
该命令会确定性地执行以下操作:
  • 添加
    src/channels/feishu.ts
    (通过
    registerChannel
    实现自注册的FeishuChannel类)
  • 添加
    src/channels/feishu.test.ts
    (单元测试文件)
  • 在渠道入口文件
    src/channels/index.ts
    中追加
    import './feishu.js'
  • 安装
    @larksuiteoapi/node-sdk
    npm依赖包
  • .env.example
    中更新
    FEISHU_APP_ID
    FEISHU_APP_SECRET
    配置项
  • .nanoclaw/state.yaml
    中记录技能应用状态
如果应用过程中报告合并冲突,请查看意图文件:
  • modify/src/channels/index.ts.intent.md
    — 变更内容和不变项说明

Validate code changes

验证代码变更

bash
npm test
npm run build
All tests must pass (including the new feishu tests) and build must be clean before proceeding.
bash
npm test
npm run build
在继续操作前,所有测试(包括新增的飞书相关测试)必须通过,且构建过程无报错。

Phase 3: Setup

阶段3:配置

Create Feishu App (if needed)

创建飞书应用(如需要)

If the user doesn't have an app, tell them:
I need you to create a Feishu app:
  1. Go to Feishu Open Platform (or Lark Open Platform for international)
  2. Click Create AppCustom App
  3. Fill in app name and description (e.g., "NanoClaw Assistant")
  4. Go to Credentials & Basic Info — copy the App ID and App Secret
  5. Go to Event SubscriptionsAdd Events → search and add:
    • im.message.receive_v1
      (Receive messages — v2.0)
  6. Go to Permissions & Scopes → add the following permissions:
    • im:message
      (Send & receive messages)
    • im:message:send_as_bot
      (Send messages as bot)
    • im:chat
      (Read chat info)
    • im:chat.members:read
      (Read chat members)
  7. Go to Bot tab → enable the bot feature
  8. Click Publish / Apply for Release
Note: For enterprise use, your IT admin may need to approve the app.
Wait for the user to provide the App ID (format:
cli_xxxxxxxxxxxxxxxxxx
) and App Secret.
如果用户尚未创建应用,请告知:
我需要您创建一个飞书应用:
  1. 访问 飞书开放平台(国际版请访问 Lark开放平台
  2. 点击创建应用自定义应用
  3. 填写应用名称和描述(例如:"NanoClaw助手")
  4. 进入凭证与基础信息页面 — 复制App IDApp Secret
  5. 进入事件订阅添加事件 → 搜索并添加:
    • im.message.receive_v1
      (接收消息 — v2.0版本)
  6. 进入权限与范围 → 添加以下权限:
    • im:message
      (发送与接收消息)
    • im:message:send_as_bot
      (以机器人身份发送消息)
    • im:chat
      (读取聊天信息)
    • im:chat.members:read
      (读取聊天成员)
  7. 进入机器人标签页 → 启用机器人功能
  8. 点击发布 / 申请发布
注意: 企业环境下,应用可能需要IT管理员审批。
等待用户提供App ID(格式:
cli_xxxxxxxxxxxxxxxxxx
)和App Secret。

Configure environment

配置环境变量

Add to
.env
:
bash
FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxxxx
FEISHU_APP_SECRET=your_app_secret_here
Channels auto-enable when their credentials are present — no extra configuration needed.
Sync to container environment:
bash
mkdir -p data/env && cp .env data/env/env
The container reads environment from
data/env/env
, not
.env
directly.
.env
文件中添加:
bash
FEISHU_APP_ID=cli_xxxxxxxxxxxxxxxxxx
FEISHU_APP_SECRET=your_app_secret_here
当凭证存在时,渠道会自动启用 — 无需额外配置。
同步到容器环境:
bash
mkdir -p data/env && cp .env data/env/env
容器会从
data/env/env
读取环境变量,而非直接读取
.env
文件。

Build and restart

构建并重启服务

bash
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS
bash
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclaw  # macOS系统

Linux: systemctl --user restart nanoclaw

Linux系统:systemctl --user restart nanoclaw

undefined
undefined

Phase 4: Registration

阶段4:注册聊天

Get Chat ID

获取聊天ID

Tell the user:
To register a Feishu chat with NanoClaw, I need the chat's ID:
For a direct (p2p) chat:
  1. Add the bot to your Feishu contacts
  2. Open a direct message to the bot
  3. Send any message — NanoClaw will log the JID as
    fs:p2p:<your_open_id>
  4. Check
    logs/nanoclaw.log
    for:
    Message from unregistered Feishu chat
For a group chat:
  1. Add the bot to the group: Group Settings → Members → Add Bot
  2. Send any message in the group (or @mention the bot)
  3. NanoClaw will log the JID as
    fs:oc_<chat_id>
  4. Check
    logs/nanoclaw.log
    for:
    Message from unregistered Feishu chat
Tell user to check the log:
bash
tail -f logs/nanoclaw.log | grep "unregistered Feishu"
Wait for the user to provide the JID (format:
fs:oc_xxxxx
or
fs:p2p:ou_xxxxx
).
告知用户:
要将飞书聊天注册到NanoClaw,我需要该聊天的JID:
一对一聊天:
  1. 将机器人添加到您的飞书联系人
  2. 打开与机器人的一对一对话
  3. 发送任意消息 — NanoClaw会在日志中记录JID,格式为
    fs:p2p:<your_open_id>
  4. 查看
    logs/nanoclaw.log
    中的日志:
    Message from unregistered Feishu chat
群组聊天:
  1. 将机器人添加到群组:群组设置 → 成员 → 添加机器人
  2. 在群组中发送任意消息(或@提及机器人)
  3. NanoClaw会在日志中记录JID,格式为
    fs:oc_<chat_id>
  4. 查看
    logs/nanoclaw.log
    中的日志:
    Message from unregistered Feishu chat
告知用户可通过以下命令查看日志:
bash
tail -f logs/nanoclaw.log | grep "unregistered Feishu"
等待用户提供JID(格式:
fs:oc_xxxxx
fs:p2p:ou_xxxxx
)。

Register the chat

注册聊天

For a main chat (responds to all messages):
typescript
registerGroup("fs:<chat-id>", {
  name: "<chat-name>",
  folder: "feishu_main",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: false,
  isMain: true,
});
For additional chats (trigger-based, responds only when @mentioned or triggered):
typescript
registerGroup("fs:<chat-id>", {
  name: "<chat-name>",
  folder: "feishu_<group-name>",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: true,
});
主聊天(响应所有消息)的注册代码:
typescript
registerGroup("fs:<chat-id>", {
  name: "<chat-name>",
  folder: "feishu_main",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: false,
  isMain: true,
});
其他聊天(仅在触发时响应,如@提及或触发词)的注册代码:
typescript
registerGroup("fs:<chat-id>", {
  name: "<chat-name>",
  folder: "feishu_<group-name>",
  trigger: `@${ASSISTANT_NAME}`,
  added_at: new Date().toISOString(),
  requiresTrigger: true,
});

Phase 5: Verify

阶段5:验证

Test the connection

测试连接

Tell the user:
Send a message to your registered Feishu chat:
  • For main chat: Any message works
  • For non-main: @mention the bot or include a question/request keyword
The bot should respond within a few seconds.
告知用户:
向已注册的飞书聊天发送消息:
  • 主聊天:发送任意消息即可
  • 非主聊天:@提及机器人或包含请求关键词(如帮、请、分析等)
机器人应在几秒内做出响应。

Check logs if needed

必要时查看日志

bash
tail -f logs/nanoclaw.log
bash
tail -f logs/nanoclaw.log

Troubleshooting

故障排查

Bot not receiving messages

机器人未收到消息

Check:
  1. im.message.receive_v1
    event is added in the app's Event Subscriptions
  2. App is published / enabled (enterprise apps need admin approval)
  3. For groups: the bot is added as a member of the group
  4. FEISHU_APP_ID
    and
    FEISHU_APP_SECRET
    are set in
    .env
    AND synced to
    data/env/env
  5. Service is running:
    launchctl list | grep nanoclaw
    (macOS) or
    systemctl --user status nanoclaw
    (Linux)
检查以下项:
  1. 应用的事件订阅中已添加
    im.message.receive_v1
    事件
  2. 应用已发布/启用(企业应用需要管理员审批)
  3. 群组场景:机器人已添加为群成员
  4. FEISHU_APP_ID
    FEISHU_APP_SECRET
    已在
    .env
    data/env/env
    中正确配置
  5. 服务正在运行:
    launchctl list | grep nanoclaw
    (macOS)或
    systemctl --user status nanoclaw
    (Linux)

Bot not responding in groups

机器人在群组中无响应

By default, NanoClaw only responds in groups when:
  • The bot is @mentioned
  • The message contains a request keyword (帮, 请, 分析, etc.)
  • The message ends with ? or ?
To make the bot respond to all messages in a group, register it with
requiresTrigger: false
.
默认情况下,NanoClaw仅在以下情况时响应群组消息:
  • 机器人被@提及
  • 消息包含请求关键词(帮、请、分析等)
  • 消息以?或?结尾
若要让机器人响应群组中所有消息,注册时需设置
requiresTrigger: false

"Message from unregistered Feishu chat" in logs

日志中出现"Message from unregistered Feishu chat"

This is normal — it means the bot is receiving messages, but the chat isn't registered yet. Follow Phase 4 to register.
这是正常现象 — 表示机器人正在接收消息,但该聊天尚未注册。请按照阶段4的步骤完成注册。

Finding the JID

查找JID

If the log message is hard to find:
bash
sqlite3 store/messages.db "SELECT DISTINCT chat_jid FROM chats WHERE channel = 'feishu'"
如果难以找到日志中的JID,可执行以下命令:
bash
sqlite3 store/messages.db "SELECT DISTINCT chat_jid FROM chats WHERE channel = 'feishu'"

App Secret security

App Secret安全

The App Secret is sensitive. Store it only in
.env
and
data/env/env
. Do NOT commit these files to version control.
App Secret是敏感信息。仅可存储在
.env
data/env/env
中,请勿将这些文件提交到版本控制系统。

JID Format Reference

JID格式参考

Chat typeJID formatExample
Group chat
fs:oc_<id>
fs:oc_4e359893776d45f7cd05d40e3ee10f55
Direct (p2p)
fs:p2p:<open_id>
fs:p2p:ou_7a66d6bd1baa3e6e3d7b3df9a8c90000
聊天类型JID格式示例
群组聊天
fs:oc_<id>
fs:oc_4e359893776d45f7cd05d40e3ee10f55
一对一聊天
fs:p2p:<open_id>
fs:p2p:ou_7a66d6bd1baa3e6e3d7b3df9a8c90000

After Setup

配置完成后

If running
npm run dev
while the service is active:
bash
undefined
如果在服务运行状态下执行
npm run dev
bash
undefined

macOS:

macOS系统:

launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist npm run dev
launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist npm run dev

When done testing:

测试完成后:

launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist
launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist

Linux:

Linux系统:

systemctl --user stop nanoclaw

systemctl --user stop nanoclaw

npm run dev

npm run dev

systemctl --user start nanoclaw

systemctl --user start nanoclaw

undefined
undefined

Removal

移除飞书集成

To remove Feishu integration:
  1. Delete
    src/channels/feishu.ts
    and
    src/channels/feishu.test.ts
  2. Remove
    import './feishu.js'
    from
    src/channels/index.ts
  3. Remove
    FEISHU_APP_ID
    and
    FEISHU_APP_SECRET
    from
    .env
  4. Remove Feishu registrations from SQLite:
    sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'fs:%'"
  5. Uninstall:
    npm uninstall @larksuiteoapi/node-sdk
  6. Rebuild:
    npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw
    (macOS) or
    npm run build && systemctl --user restart nanoclaw
    (Linux)
如需移除飞书集成:
  1. 删除
    src/channels/feishu.ts
    src/channels/feishu.test.ts
    文件
  2. src/channels/index.ts
    中移除
    import './feishu.js'
    语句
  3. .env
    中删除
    FEISHU_APP_ID
    FEISHU_APP_SECRET
    配置
  4. 从SQLite中删除飞书注册信息:
    sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'fs:%'"
  5. 卸载依赖:
    npm uninstall @larksuiteoapi/node-sdk
  6. 重新构建并重启服务:
    npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw
    (macOS)或
    npm run build && systemctl --user restart nanoclaw
    (Linux)