@lixiongwei/n8n-nodes-feishu 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,72 +1,66 @@
1
- # n8n-nodes-feishu
1
+ # @lixiongwei/n8n-nodes-feishu
2
2
 
3
- > 飞书/Lark 集成节点,免费功能 + Pro License。附带 5 个即用工作流模板。
3
+ > Feishu / Lark integration nodes for n8n. Free tier + Pro License. Includes 5 workflow templates.
4
4
 
5
5
  ---
6
6
 
7
- ## 安装
7
+ ## Install
8
8
 
9
9
  ```bash
10
10
  npm install @lixiongwei/n8n-nodes-feishu
11
11
  ```
12
12
 
13
- n8n 自托管版直接在 n8n 所在目录执行。云版不支持社区节点。
14
-
15
13
  ---
16
14
 
17
- ## 免费功能 🆓
15
+ ## Free Features 🆓
18
16
 
19
- | 功能 | 说明 |
20
- |------|------|
21
- | **发送文本消息** | 给用户/群发文本消息 |
22
- | **消息触发器** | 接收飞书事件回调 |
17
+ | Feature | Description |
18
+ |---------|-------------|
19
+ | Send Text Message | Send plain text to users or groups |
20
+ | Webhook Trigger | Receive Feishu event callbacks |
23
21
 
24
22
  ---
25
23
 
26
- ## Pro 功能(需 License Key
24
+ ## Pro Features(License Key required)
27
25
 
28
- | 功能 | 说明 |
29
- |------|------|
30
- | **发送卡片消息** | 富文本卡片模板 + Markdown |
31
- | **读取多维表格** | 按字段读取 Bitable 数据 |
32
- | **写入多维表格** | 写入新行到 Bitable |
33
- | **获取待审批列表** | 查询审批实例 |
26
+ | Feature | Description |
27
+ |---------|-------------|
28
+ | Send Card Message | Rich interactive cards with Markdown |
29
+ | Read Bitable | Query records from a Bitable |
30
+ | Write to Bitable | Insert new records into a Bitable |
31
+ | Get Pending Approvals | List pending approval instances |
34
32
 
35
33
  ---
36
34
 
37
- ## 获取 License Key
38
-
39
- 👉 **[在 Gumroad 购买](https://gumroad.com/l/feishu-pro)** — $49 一次性,永久使用。
35
+ ## Get a License Key
40
36
 
41
- 购买后在凭证管理里填入 Key,Pro 功能即刻解锁。
37
+ 👉 **[Buy on Gumroad](https://1717465779306.gumroad.com/l/feishu-pro)** — $49 one-time, lifetime license.
42
38
 
43
39
  ---
44
40
 
45
- ## 附带工作流模板
41
+ ## Included Workflow Templates
46
42
 
47
- `workflows/` 目录下,导入即用:
43
+ Import from `workflows/`:
48
44
 
49
- | 模板 | 场景 |
50
- |------|------|
51
- | `template-01-send-message.json` | Webhook → 飞书消息 |
52
- | `template-02-cron-reminder.json` | 定时飞书提醒 |
53
- | `template-03-website-monitor.json` | 网站监控飞书告警 |
54
- | `template-04-form-notify.json` | 表单提交卡片通知 |
55
- | `template-05-api-to-feishu.json` | API 数据飞书推送 |
45
+ | Template | Scenario |
46
+ |----------|----------|
47
+ | `template-01-send-message.json` | Webhook → Feishu message |
48
+ | `template-02-cron-reminder.json` | ScheduledFeishu reminder |
49
+ | `template-03-website-monitor.json` | Website monitor Feishu alert |
50
+ | `template-04-form-notify.json` | Form submission Card notification |
51
+ | `template-05-api-to-feishu.json` | API dataFeishu push |
56
52
 
57
53
  ---
58
54
 
59
- ## 飞书应用配置
55
+ ## Feishu App Setup
60
56
 
61
- 1. 飞书开发者后台创建 **企业自建应用**
62
- 2. 开启 **机器人** 能力
63
- 3. 权限管理开通:`im:message:send_as_bot`
64
- 4. 发布应用
65
- 5. n8n 凭证中填入 App ID + App Secret + License Key
57
+ 1. Create an **Enterprise Internal App** at [Feishu Developer Console](https://open.feishu.cn/)
58
+ 2. Enable **Bot** capability
59
+ 3. Add permissions: `im:message:send_as_bot`
60
+ 4. Publish the app
61
+ 5. In n8n credentials, fill in App ID + App Secret + License Key
66
62
 
67
63
  ---
68
64
 
69
- ## 版本
70
-
71
- - n8n 版本要求:1.x+
72
- - 飞书 API 版本:v3
65
+ - n8n version: 1.x+
66
+ - Feishu API version: v3
@@ -4,7 +4,7 @@ exports.FeishuApi = void 0;
4
4
  class FeishuApi {
5
5
  constructor() {
6
6
  this.name = 'feishuApi';
7
- this.displayName = '飞书 Feishu API';
7
+ this.displayName = 'Feishu (Lark) API';
8
8
  this.documentationUrl = 'https://open.feishu.cn/document/home/getting-started';
9
9
  this.properties = [
10
10
  {
@@ -12,7 +12,7 @@ class FeishuApi {
12
12
  name: 'appId',
13
13
  type: 'string',
14
14
  default: '',
15
- description: '飞书应用的 App ID(从开发者后台-凭证与基础信息获取)',
15
+ description: 'Feishu App ID (from Developer Console → Credentials)',
16
16
  required: true,
17
17
  },
18
18
  {
@@ -21,15 +21,15 @@ class FeishuApi {
21
21
  type: 'string',
22
22
  typeOptions: { password: true },
23
23
  default: '',
24
- description: '飞书应用的 App Secret',
24
+ description: 'Feishu App Secret',
25
25
  required: true,
26
26
  },
27
27
  {
28
- displayName: 'License Key',
28
+ displayName: 'License Key (optional)',
29
29
  name: 'licenseKey',
30
30
  type: 'string',
31
31
  default: '',
32
- description: 'Pro License Key Gumroad 购买获取。留空则仅使用免费功能',
32
+ description: 'Pro License Key from Gumroad. Leave empty for free features only. Get one at: https://1717465779306.gumroad.com/l/feishu-pro',
33
33
  required: false,
34
34
  },
35
35
  ];
@@ -6,7 +6,7 @@ const license_1 = require("./license");
6
6
  // --- Operation definitions ---
7
7
  const FREE_OPERATIONS = ['sendTextMessage'];
8
8
  const PRO_OPERATIONS = ['sendCardMessage', 'readBitable', 'writeBitable', 'getApprovals'];
9
- // --- Token cache (in-memory, per-node lifetime) ---
9
+ // --- Token cache ---
10
10
  let cachedToken = null;
11
11
  let tokenExpiry = 0;
12
12
  async function getFeishuToken(appId, appSecret) {
@@ -21,7 +21,7 @@ async function getFeishuToken(appId, appSecret) {
21
21
  json: true,
22
22
  });
23
23
  if (response.code !== 0) {
24
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `飞书 Token 获取失败:${response.msg} (code: ${response.code})`);
24
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Feishu token failed: ${response.msg} (code: ${response.code})`);
25
25
  }
26
26
  cachedToken = response.tenant_access_token;
27
27
  tokenExpiry = Date.now() + (response.expire - 300) * 1000;
@@ -31,98 +31,98 @@ async function getFeishuToken(appId, appSecret) {
31
31
  class Feishu {
32
32
  constructor() {
33
33
  this.description = {
34
- displayName: '飞书 Feishu',
34
+ displayName: 'Feishu / Lark',
35
35
  name: 'feishu',
36
36
  icon: 'file:feishu.svg',
37
37
  group: ['transform'],
38
38
  version: 1,
39
39
  subtitle: '={{ $parameter["operation"] }}',
40
- description: '飞书集成:发消息、读多维表格、处理审批',
41
- defaults: { name: '飞书 Feishu' },
40
+ description: 'Feishu/Lark integration: send messages, manage Bitable, process approvals',
41
+ defaults: { name: 'Feishu / Lark' },
42
42
  inputs: ["main"],
43
43
  outputs: ["main"],
44
44
  credentials: [{ name: 'feishuApi', required: true }],
45
45
  properties: [
46
46
  // --- Operation selector ---
47
47
  {
48
- displayName: '操作 Operation',
48
+ displayName: 'Operation',
49
49
  name: 'operation',
50
50
  type: 'options',
51
51
  noDataExpression: true,
52
52
  options: [
53
- { name: '🆓 发送文本消息 (免费)', value: 'sendTextMessage' },
54
- { name: '⭐ 发送卡片消息 (Pro)', value: 'sendCardMessage' },
55
- { name: '⭐ 读取多维表格 (Pro)', value: 'readBitable' },
56
- { name: '⭐ 写入多维表格 (Pro)', value: 'writeBitable' },
57
- { name: '⭐ 获取待审批列表 (Pro)', value: 'getApprovals' },
53
+ { name: '🆓 Send Text Message (Free)', value: 'sendTextMessage' },
54
+ { name: '⭐ Send Card Message (Pro)', value: 'sendCardMessage' },
55
+ { name: '⭐ Read Bitable (Pro)', value: 'readBitable' },
56
+ { name: '⭐ Write to Bitable (Pro)', value: 'writeBitable' },
57
+ { name: '⭐ Get Pending Approvals (Pro)', value: 'getApprovals' },
58
58
  ],
59
59
  default: 'sendTextMessage',
60
- description: 'Pro 功能需要 License Key',
60
+ description: 'Pro features require a License Key',
61
61
  },
62
62
  // --- Send Text Message (Free) ---
63
63
  {
64
- displayName: '接收人 ID 类型',
64
+ displayName: 'Recipient ID Type',
65
65
  name: 'receiveIdType',
66
66
  type: 'options',
67
67
  options: [
68
- { name: '用户 Open ID', value: 'open_id' },
69
- { name: '用户 User ID', value: 'user_id' },
70
- { name: '邮箱', value: 'email' },
71
- { name: 'Chat ID', value: 'chat_id' },
68
+ { name: 'Open ID', value: 'open_id' },
69
+ { name: 'User ID', value: 'user_id' },
70
+ { name: 'Email', value: 'email' },
71
+ { name: 'Chat ID', value: 'chat_id' },
72
72
  ],
73
73
  default: 'open_id',
74
74
  displayOptions: { show: { operation: ['sendTextMessage', 'sendCardMessage'] } },
75
75
  },
76
76
  {
77
- displayName: '接收人',
77
+ displayName: 'Recipient',
78
78
  name: 'receiveId',
79
79
  type: 'string',
80
80
  default: '',
81
81
  required: true,
82
82
  displayOptions: { show: { operation: ['sendTextMessage', 'sendCardMessage'] } },
83
- placeholder: 'ou_xxx chat_xxx email',
84
- description: '接收人的 open_iduser_id、邮箱或群的 chat_id',
83
+ placeholder: 'ou_xxx or chat_xxx or email@example.com',
84
+ description: 'Recipient open_id, user_id, email, or chat_id',
85
85
  },
86
86
  {
87
- displayName: '消息内容',
87
+ displayName: 'Message Content',
88
88
  name: 'textContent',
89
89
  type: 'string',
90
90
  typeOptions: { rows: 4 },
91
91
  default: '',
92
92
  required: true,
93
93
  displayOptions: { show: { operation: ['sendTextMessage'] } },
94
- placeholder: '输入要发送的消息...',
94
+ placeholder: 'Type your message...',
95
95
  },
96
96
  // --- Send Card Message (Pro) ---
97
97
  {
98
- displayName: '卡片标题',
98
+ displayName: 'Card Title',
99
99
  name: 'cardTitle',
100
100
  type: 'string',
101
- default: '📢 通知',
101
+ default: '📢 Notification',
102
102
  displayOptions: { show: { operation: ['sendCardMessage'] } },
103
103
  },
104
104
  {
105
- displayName: '卡片内容 (支持 Markdown)',
105
+ displayName: 'Card Body (Markdown supported)',
106
106
  name: 'cardContent',
107
107
  type: 'string',
108
108
  typeOptions: { rows: 6 },
109
109
  default: '',
110
110
  required: true,
111
111
  displayOptions: { show: { operation: ['sendCardMessage'] } },
112
- placeholder: '**标题**\n内容...',
112
+ placeholder: '**Title**\nContent...',
113
113
  },
114
114
  // --- Read Bitable (Pro) ---
115
115
  {
116
- displayName: '多维表格 App Token',
116
+ displayName: 'Bitable App Token',
117
117
  name: 'bitableAppToken',
118
118
  type: 'string',
119
119
  default: '',
120
120
  required: true,
121
121
  displayOptions: { show: { operation: ['readBitable', 'writeBitable'] } },
122
- description: '多维表格 URL 中的 app token,如 /base/XXX 的 XXX 部分',
122
+ description: 'The app token from your Bitable URL (the XXX in /base/XXX)',
123
123
  },
124
124
  {
125
- displayName: ' ID',
125
+ displayName: 'Table ID',
126
126
  name: 'tableId',
127
127
  type: 'string',
128
128
  default: '',
@@ -132,13 +132,13 @@ class Feishu {
132
132
  },
133
133
  // --- Write Bitable (Pro) ---
134
134
  {
135
- displayName: '写入数据 (JSON)',
135
+ displayName: 'Fields (JSON)',
136
136
  name: 'bitableFields',
137
137
  type: 'json',
138
- default: '{"字段名": ""}',
138
+ default: '{"Field Name": "Value"}',
139
139
  required: true,
140
140
  displayOptions: { show: { operation: ['writeBitable'] } },
141
- description: '要写入的字段和值,JSON 格式',
141
+ description: 'Fields and values to write, in JSON format',
142
142
  },
143
143
  ],
144
144
  };
@@ -147,7 +147,6 @@ class Feishu {
147
147
  async execute() {
148
148
  const items = this.getInputData();
149
149
  const returnData = [];
150
- // Get credentials
151
150
  const credentials = await this.getCredentials('feishuApi');
152
151
  const appId = credentials.appId;
153
152
  const appSecret = credentials.appSecret;
@@ -155,21 +154,18 @@ class Feishu {
155
154
  for (let i = 0; i < items.length; i++) {
156
155
  try {
157
156
  const operation = this.getNodeParameter('operation', i);
158
- // --- License check for Pro operations ---
157
+ // License check for Pro operations
159
158
  if (PRO_OPERATIONS.includes(operation)) {
160
159
  if (!licenseKey) {
161
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), '⭐ 这是 Pro 功能。请在凭证中填写 License Key。\n' +
162
- '👉 购买 License Keyhttps://gumroad.com/l/feishu-pro\n' +
163
- '👉 获取免费 Key 试用 7 天:https://gumroad.com/l/feishu-pro');
160
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), '⭐ This is a Pro feature. Please add a License Key in your credentials.\n' +
161
+ '👉 Get a License Key: https://1717465779306.gumroad.com/l/feishu-pro');
164
162
  }
165
163
  const validation = await license_1.validateLicense.call(this, licenseKey, appId);
166
164
  if (!validation.valid) {
167
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `License Key 无效或已过期:${validation.reason}`);
165
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `License Key invalid or expired: ${validation.reason}`);
168
166
  }
169
167
  }
170
- // Get token
171
168
  const token = await getFeishuToken.call(this, appId, appSecret);
172
- // Execute operation
173
169
  switch (operation) {
174
170
  case 'sendTextMessage': {
175
171
  const receiveIdType = this.getNodeParameter('receiveIdType', i);
@@ -278,9 +274,7 @@ class Feishu {
278
274
  returnData.push({ json: { error: error.message }, error });
279
275
  }
280
276
  else {
281
- returnData.push({
282
- json: { error: error.message || 'Unknown error' },
283
- });
277
+ returnData.push({ json: { error: error.message || 'Unknown error' } });
284
278
  }
285
279
  }
286
280
  }
@@ -4,14 +4,14 @@ exports.FeishuTrigger = void 0;
4
4
  class FeishuTrigger {
5
5
  constructor() {
6
6
  this.description = {
7
- displayName: '飞书触发器 Feishu Trigger',
7
+ displayName: 'Feishu / Lark Trigger',
8
8
  name: 'feishuTrigger',
9
9
  icon: 'file:feishu.svg',
10
10
  group: ['trigger'],
11
11
  version: 1,
12
12
  subtitle: '={{ $parameter["event"] }}',
13
- description: '监听飞书事件:消息接收、审批状态变化',
14
- defaults: { name: '飞书 Trigger' },
13
+ description: 'Listen for Feishu events: message received, approval status changed',
14
+ defaults: { name: 'Feishu / Lark Trigger' },
15
15
  inputs: [],
16
16
  outputs: ["main"],
17
17
  credentials: [{ name: 'feishuApi', required: true }],
@@ -25,22 +25,22 @@ class FeishuTrigger {
25
25
  ],
26
26
  properties: [
27
27
  {
28
- displayName: '事件类型',
28
+ displayName: 'Event Type',
29
29
  name: 'event',
30
30
  type: 'options',
31
31
  options: [
32
- { name: '🆓 消息接收 (免费)', value: 'message_receive' },
33
- { name: '⭐ 审批状态变化 (Pro)', value: 'approval_change' },
32
+ { name: '🆓 Message Received (Free)', value: 'message_receive' },
33
+ { name: '⭐ Approval Status Changed (Pro)', value: 'approval_change' },
34
34
  ],
35
35
  default: 'message_receive',
36
- description: 'Pro 功能需要 License Key',
36
+ description: 'Pro events require a License Key',
37
37
  },
38
38
  {
39
- displayName: '验证 Token',
39
+ displayName: 'Verification Token',
40
40
  name: 'verificationToken',
41
41
  type: 'string',
42
42
  default: '',
43
- description: '飞书事件订阅的 Verification Token,用于验证回调来源',
43
+ description: 'Feishu Event Subscription Verification Token',
44
44
  },
45
45
  ],
46
46
  };
@@ -48,14 +48,13 @@ class FeishuTrigger {
48
48
  async webhook() {
49
49
  const req = this.getRequestObject();
50
50
  const body = req.body;
51
- // Handle Feishu URL verification challenge
51
+ // Feishu URL verification challenge
52
52
  if (body?.type === 'url_verification') {
53
53
  return {
54
54
  webhookResponse: { challenge: body.challenge },
55
55
  workflowData: [],
56
56
  };
57
57
  }
58
- // Handle event
59
58
  const event = body?.event || {};
60
59
  const header = body?.header || {};
61
60
  return {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lixiongwei/n8n-nodes-feishu",
3
- "version": "1.0.1",
4
- "description": "飞书/Lark nodes for n8n — send messages, manage bitables, process approvals. Free tier + Pro license.",
3
+ "version": "1.0.2",
4
+ "description": "Feishu/Lark nodes for n8n — send messages, manage Bitables, process approvals. Free tier + Pro license.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "build": "tsc",