lark-node-sdk
Lark/Feishu Node SDK
Development guide for @larksuiteoapi/node-sdk.
References
| Resource | Link |
|---|---|
| Official Node SDK | larksuite/node-sdk |
| Official MCP Reference | larksuite/lark-openapi-mcp |
| Open Platform Docs | open.feishu.cn |
| Message Card Builder | Card Builder |
Client Setup
import * as lark from '@larksuiteoapi/node-sdk';
const client = new lark.Client({
appId: 'app id',
appSecret: 'app secret',
// domain: lark.Domain.Feishu, // Default. Use lark.Domain.Lark for international
});
// ISV (store app)
const client = new lark.Client({
appId: 'app id',
appSecret: 'app secret',
appType: lark.AppType.ISV,
});
| Param | Description | Required | Default |
|---|---|---|---|
| appId | App ID | Yes | - |
| appSecret | App Secret | Yes | - |
| domain | Feishu / Lark / custom URL | No | Domain.Feishu |
| appType | SelfBuild / ISV | No | SelfBuild |
| disableTokenCache | Disable token caching | No | false |
API Calls
Semantic chaining: client.<domain>.<resource>.<method>
Send Messages
// Text message
const res = await client.im.message.create({
params: { receive_id_type: 'chat_id' }, // chat_id | open_id | user_id | union_id | email
data: {
receive_id: 'oc_xxx',
content: JSON.stringify({ text: 'hello world' }),
msg_type: 'text',
},
});
// Interactive card
const res = await client.im.message.create({
params: { receive_id_type: 'chat_id' },
data: {
receive_id: 'oc_xxx',
content: JSON.stringify({
config: { wide_screen_mode: true },
header: {
template: 'blue',
title: { content: '标题', tag: 'plain_text' },
},
elements: [{ tag: 'markdown', content: '**内容**' }],
}),
msg_type: 'interactive',
},
});
// Built-in card helper
const res = await client.im.message.create({
params: { receive_id_type: 'chat_id' },
data: {
receive_id: 'oc_xxx',
content: lark.messageCard.defaultCard({ title: '标题', content: '内容' }),
msg_type: 'interactive',
},
});
// Card template ID
const res = await client.im.message.createByCard({
params: { receive_id_type: 'chat_id' },
data: {
receive_id: 'oc_xxx',
template_id: 'AAqCxxxxxx',
template_variable: { title: '标题', content: '内容' },
},
});
Pagination (Async Iterator)
for await (const items of await client.contact.user.listWithIterator({
params: { department_id: '0', page_size: 20 },
})) {
console.log(items);
}
File Upload / Download
// Upload
const res = await client.im.file.create({
data: {
file_type: 'mp4',
file_name: 'test.mp4',
file: fs.readFileSync('path/to/file.mp4'),
},
});
// Download
const resp = await client.im.file.get({ path: { file_key: 'file_key' } });
await resp.writeFile('download.mp4');
// Or: resp.getReadableStream().pipe(fs.createWriteStream('download.mp4'));
Event Handling
WebSocket (Recommended)
No public IP or tunnel needed — works in local dev.
const wsClient = new lark.WSClient({
appId: 'xxx',
appSecret: 'xxx',
loggerLevel: lark.LoggerLevel.info,
});
wsClient.start({
eventDispatcher: new lark.EventDispatcher({}).register({
'im.message.receive_v1': async (data) => {
const { message: { chat_id, content } } = data;
await client.im.message.create({
params: { receive_id_type: 'chat_id' },
data: {
receive_id: chat_id,
content: JSON.stringify({ text: `Reply: ${JSON.parse(content).text}` }),
msg_type: 'text',
},
});
},
}),
});
Webhook
const eventDispatcher = new lark.EventDispatcher({
encryptKey: 'encrypt key',
}).register({
'im.message.receive_v1': async (data) => {
// Handle message
},
});
// Express
app.use('/webhook/event', lark.adaptExpress(eventDispatcher, { autoChallenge: true }));
// Koa
app.use(lark.adaptKoa('/webhook/event', eventDispatcher, { autoChallenge: true }));
Card Action Handler
const cardDispatcher = new lark.CardActionHandler(
{ encryptKey: 'encrypt key', verificationToken: 'verification token' },
async (data) => {
// Return new card to update the original
return {
header: { title: { tag: 'plain_text', content: 'Done' } },
elements: [{ tag: 'markdown', content: 'Operation complete' }],
};
},
);
app.use('/webhook/card', lark.adaptExpress(cardDispatcher));
Common API Domains
| Domain | Description | Example |
|---|---|---|
im |
Messages & Groups | client.im.message.create() |
contact |
Contacts | client.contact.user.list() |
calendar |
Calendar | client.calendar.event.create() |
drive |
Docs | client.drive.file.list() |
sheets |
Spreadsheets | client.sheets.spreadsheet.create() |
bitable |
Base (Multitable) | client.bitable.app.create() |
approval |
Approval | client.approval.instance.create() |
attendance |
Attendance | client.attendance.record.list() |
Request Options
// ISV: pass tenant_key
await client.im.message.create({ ... }, lark.withTenantKey('tenant key'));
// Custom headers
await client.im.message.create({ ... }, { headers: { 'X-Custom': 'value' } });
// Combine options
await client.im.message.create({ ... }, lark.withAll([
lark.withTenantToken('tenant token'),
lark.withTenantKey('tenant key'),
]));
More from wenerme/ai
glab-cli
Use when interacting with GitLab via the glab CLI: creating/reviewing merge requests, managing issues, monitoring CI/CD pipelines, making API calls, or performing any GitLab operation from the terminal. Triggers on glab, gitlab cli, merge request, MR create, pipeline status, ci lint.
32mikro-orm-v6-to-v7
Use when upgrading @mikro-orm packages from v6 to v7, fixing v7 runtime/type errors (decorator SyntaxError, persistAndFlush removed, nativeInsert not found), adapting knex to kysely or better-sqlite to new SQLite drivers, running MikroORM in Edge/Bun/node:sqlite environments, or choosing between defineEntity vs decorator entity definitions. Triggers on "mikro-orm v7", "persistAndFlush", "@mikro-orm/decorators", "@mikro-orm/sql", "defineEntity", "bun:sqlite mikro-orm".
31orpc-implementation-sops
Use when building, updating, or refactoring oRPC contracts, server handlers, clients, or React Query integration
30zustand-mutative-pattern
Use when implementing React state management with Zustand, including context-scoped stores, mutative updates, or actions namespace patterns
25tmux-session-manager
Use when executing commands, running builds, starting services, or monitoring logs in a visible tmux pane
25chrome-devtools
Uses Chrome DevTools via MCP for efficient debugging, troubleshooting and browser automation. Use when debugging web pages, automating browser interactions, analyzing performance, or inspecting network requests. This skill does not apply to `--slim` mode (MCP configuration).
24