Resources
7Install
npx skillscat add stephanz1101/nanoclaw-skill-feishu Install via the SkillsCat registry.
Add Feishu Channel
This skill adds Feishu (Lark) support to NanoClaw using the skills engine for deterministic code changes, then walks through interactive setup.
Phase 1: Pre-flight
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.
Ask the user
Use AskUserQuestion to collect configuration:
AskUserQuestion: Do you have a Feishu app ID and secret, or do you need to create a bot app?
If they have credentials, collect them now. If not, we'll create the app in Phase 3.
Phase 2: Apply Code Changes
Run the skills engine to apply this skill's code package. The package files are in this directory alongside this SKILL.md.
Initialize skills system (if needed)
If .nanoclaw/ directory doesn't exist yet:
npx tsx scripts/apply-skill.ts --initApply the skill
npx tsx scripts/apply-skill.ts .claude/skills/add-feishuThis deterministically:
- Adds
src/channels/feishu.ts(FeishuChannel class with self-registration viaregisterChannel) - Adds
src/channels/feishu.test.ts(unit tests with Lark SDK mock) - Appends
import './feishu.js'to the channel barrel filesrc/channels/index.ts - Installs the
@larksuiteoapi/node-sdknpm dependency - 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
Validate code changes
npm test
npm run buildAll tests must pass (including the new Feishu tests) and build must be clean before proceeding.
Phase 3: Setup
Create Feishu Bot App (if needed)
If the user doesn't have credentials, tell them:
I need you to create a Feishu custom bot app:
- Go to Feishu Open Platform (or Lark: https://open.larksuite.com/app)
- Click Create Custom App
- Give it a name (e.g., "Andy Assistant") and description
- In the app dashboard, go to Credentials & Basic Info — copy the App ID and App Secret
- Go to Permissions & Scopes, add these permissions:
im:message(Read/Send messages)im:message.receive_v1(Receive message events)contact:user.base:readonly(Read basic user info — for sender names)im:chat:readonly(Read chat info — for chat names)- Go to Event Subscriptions > Add Event > search for
im.message.receive_v1and subscribe- Go to Bot tab and enable the bot feature
- Publish the app (submit for review, or if internal enterprise app, publish directly)
Wait for the user to provide the App ID and App Secret.
Configure environment
Add to .env:
FEISHU_APP_ID=cli_xxxxxxxxxxxx
FEISHU_APP_SECRET=your_app_secret_hereChannels auto-enable when their credentials are present — no extra configuration needed.
Sync to container environment:
mkdir -p data/env && cp .env data/env/envBuild and restart
npm run build
launchctl kickstart -k gui/$(id -u)/com.nanoclawPhase 4: Registration
Get Chat ID
Tell the user:
To get the chat ID for registration, you can:
Option A — From a group chat:
- Add the bot to the group (search for it in Feishu/Lark)
- Send any message in the group after the bot connects — the logs will show the chat ID:
Look for thetail -f logs/nanoclaw.log | grep "Feishu message"chatJidfield (format:fs:oc_xxxxxxxx)Option B — Direct/P2P chat:
- Start a direct message with the bot in Feishu/Lark
- Send a message — the logs will show the chat ID
Wait for the user to provide the chat JID (format: fs:oc_xxxxxxxx).
Register the channel
Use the IPC register flow or register directly. The chat JID, name, and folder name are needed.
For a main channel (responds to all messages):
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-only):
registerGroup("fs:<chat-id>", {
name: "<chat-name>",
folder: "feishu_<chat-name>",
trigger: `@${ASSISTANT_NAME}`,
added_at: new Date().toISOString(),
requiresTrigger: true,
});Phase 5: Verify
Test the connection
Tell the user:
Send a message in your registered Feishu/Lark chat:
- For main channel: Any message works
- For non-main: Use the trigger word (e.g.,
@Andy hello)The bot should respond within a few seconds.
Check logs if needed
tail -f logs/nanoclaw.logTroubleshooting
Bot not receiving messages
- Check
FEISHU_APP_IDandFEISHU_APP_SECRETare set in.envAND synced todata/env/env - Verify
im.message.receive_v1event is subscribed in the Feishu app dashboard - Ensure the app is published (not in draft)
- Service is running:
launchctl list | grep nanoclaw - Check logs for WebSocket connection errors
Permission errors when fetching user/chat info
Ensure these scopes are added in Permissions & Scopes:
contact:user.base:readonlyim:chat:readonly
If scopes were added after publishing, re-publish the app.
Chat ID not appearing in logs
The bot only logs chat IDs from unregistered chats at debug level. Check debug logs:
tail -f logs/nanoclaw.log | grep -i feishuBot only responds to trigger word
This is the default behavior for non-main channels (requiresTrigger: true). To change:
- Update the registered group's
requiresTriggertofalse - Or register the chat as the main channel
After Setup
The Feishu bot supports:
- Text messages in registered chats (groups and direct messages)
- Media message placeholders (images, files, audio, video shown as
[图片],[文件], etc.) - Sender name resolution (via Feishu Contacts API)
- Chat name resolution (via Feishu Chat API)
- WebSocket long connection (no webhook/public URL required)
- Typing indicators are not supported by the Feishu API