ruindong-feishu-bitable
v2.1.0
Published
飞书多维表格(Bitable)操作封装类,支持批量操作、文件上传、自动重试等功能
Maintainers
Readme
飞书多维表格 SDK
一个功能强大的飞书多维表格(Bitable)操作封装,支持流式遍历、批量增删改查、文件上传、智能重试等。
安装
npm install ruindong-feishu-bitable从 v1 升级? 请阅读 MIGRATION.md — v2.0.0 含破坏性改动。
快速开始
const Bitable = require('ruindong-feishu-bitable');
require('dotenv').config();
const bitable = new Bitable({
appId: process.env.FEISHU_APP_ID,
appSecret: process.env.FEISHU_APP_SECRET,
appToken: process.env.FEISHU_APP_TOKEN, // 可选,默认 app_token
// logger: console, // 可选,需要看进度日志再打开
// domain: 'feishu', // 可选,'feishu' 或 'lark'
});v1 旧式位置参数
new Bitable(appToken, appId, appSecret)仍然兼容,会触发一次 deprecation 提示。计划在 v3 移除。
功能特性
- 🔐 必填的应用凭证 — appId / appSecret 在构造时即刻校验
- 📦 批量操作 — 自动分片(每批最多 500 条)
- ⚡ 并发控制 — 通过
concurrency配置 - 🔄 智能重试 — 仅对网络错误 / 5xx / 429 / 限流类业务码重试,采用指数退避 + 抖动
- 🌊 流式遍历 —
iterRecords用 async iterator,大数据量不爆内存 - 📁 文件上传/下载 — 都带重试
- 🔇 默认静默 — SDK 不主动 console.log,需要时主动注入 logger
- 🎯 结构化错误 — 业务错误抛
FeishuApiError,含feishuCode/feishuMsg
用法
流式遍历(推荐用于大数据量)
for await (const page of bitable.iterRecords(tableId, {
fieldNames: ['name', 'value'],
pageSize: 500,
})) {
await processPage(page); // 边读边处理,内存占用 ~ 一页
}一次性获取全部记录
const records = await bitable.fetchAllRecords(tableId, {
viewId: 'view_id', // 可选
fieldNames: ['field1', 'field2'],
pageSize: 500,
});字段值扁平化规则
返回的每条记录已经被扁平化(去掉了飞书 API 的类型包装),便于直接使用:
- 文本/链接数组(
[{ text: "..." }]) → 字符串(取首段 text) - 数字/单选(
{ type: 1, value: [...] }) → 拼接字符串 - 多选/复选(
{ type: 2 | 3 | 1005, value: [...] }) → 逗号拼接 - 附件、关联记录、人员引用 → 保留原数组结构,业务方可以读
file_token/record_ids/id等元数据
// 例如附件字段:
record.货盘表 // → [{ file_token, name, size, url, type }, ...]
const fileToken = record.货盘表[0].file_token; // 可以直接拿来 client.drive.v1.media.download批量新增
const created = await bitable.insertList(tableId, [
{ fields: { name: 'A', value: 1 } },
{ fields: { name: 'B', value: 2 } },
], {
concurrency: 2, // 默认 1
chunkSize: 500, // 默认 500,飞书上限
});
// created: [{ record_id, fields: { ... } }, ...]批量更新
const updated = await bitable.updateList(tableId, [
{ record_id: 'rec1', fields: { value: 100 } },
{ record_id: 'rec2', fields: { value: 200 } },
]);
// updated: [{ record_id, fields: { ... } }, ...]批量删除
const deleted = await bitable.deleteList(tableId, ['rec1', 'rec2', 'rec3']);
// deleted: [{ record_id, deleted: true }, ...]上传文件
// 直接传 Buffer
const buffer = require('fs').readFileSync('./pic.jpg');
const result = await bitable.uploadFile({
file: buffer,
parentType: 'bitable_file',
parent_node: tableId,
fileName: 'pic.jpg', // 可选,未提供时自动生成
});
// 也支持 base64 / data URL
await bitable.uploadFile({
file: 'data:image/jpeg;base64,/9j/4AAQ...',
parentType: 'bitable_file',
parent_node: tableId,
});下载文件
const buffer = await bitable.downLoadFile('file_token', extra);错误处理
const { Bitable, FeishuApiError } = require('ruindong-feishu-bitable');
try {
await bitable.insertList(tableId, records);
} catch (e) {
if (e instanceof FeishuApiError) {
console.error('飞书业务错误', e.feishuCode, e.feishuMsg);
} else {
console.error('其他错误', e);
}
}重试策略
仅以下情况会自动重试(最多 5 次,指数退避 + 抖动):
- 网络错误:
ECONNRESET、ETIMEDOUT、ECONNREFUSED、ENETUNREACH等 - HTTP 5xx 与 429
- 飞书业务码:
1254290、1254607、99991663、99991668、99991400
其他错误(参数错、token 错、字段不存在等)立即抛出,避免无效等待。
多 appToken 场景
构造时不传 appToken,每次调用现传:
const bitable = new Bitable({ appId, appSecret });
await bitable.insertList(tableId, records, { appToken: 'token_for_app_A' });
await bitable.fetchAllRecords(otherTableId, opts, 'token_for_app_B');安全建议
- 用环境变量管理
appId/appSecret/appToken,不要硬编码 - 定期轮换应用密钥
- 生产环境不要把
logger设成 console(避免敏感数据进日志)
许可证
MIT
