@larksuiteoapi/node-sdk 1.2.2 → 1.3.0

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
@@ -403,6 +403,32 @@ const resule = await dispatcher.invoke(data);
403
403
  server.sendResult(result);
404
404
  ````
405
405
 
406
+ #### challenge校验
407
+ When configuring the event request address, The Open Platform will push a POST request in `application/json` format to the request address. The POST request is used to verify the validity of the configured request address, and the request body will carry a `challenge` field , **The application needs to return the received challenge value to the Open Platform within 1 second**. See: [ Document](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case)
408
+
409
+ The adapter provided by the sdk above encapsulates the verification logic. Set the `autoChallenge` field in the options parameter to true to enable:
410
+ ```typescript
411
+ // adaptDefault
412
+ lark.adaptDefault('/webhook/event', eventDispatcher, {
413
+ autoChallenge: true,
414
+ });
415
+ // express
416
+ lark.adaptExpress(eventDispatcher, {
417
+ autoChallenge: true,
418
+ });
419
+ // koa
420
+ lark.adaptKoa('/webhook/event', eventDispatcher, {
421
+ autoChallenge: true,
422
+ });
423
+ // koa-router
424
+ router.post(
425
+ '/webhook/event',
426
+ lark.adaptKoaRouter(eventDispatcher, {
427
+ autoChallenge: true,
428
+ })
429
+ );
430
+ ```
431
+
406
432
  ### [Message Card](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN)
407
433
  The processing of the Message Card is also a kind of Event processing. The only difference between the two is that the processor of the Message Card is used to respond to the events generated by the interaction between the user and the Message Card. If the processor has a return value (*the value structure should be in line with the structure defined by [Message Card Structure](https://open.feishu.cn/document/ukTMukTMukTM/uEjNwUjLxYDM14SM2ATN)*), then the return value is used to update the responded message card:
408
434
 
@@ -443,6 +469,10 @@ import * as lark from '@larksuiteoapi/node-sdk';
443
469
 
444
470
  new lark.AESCipher('encrypt key').decrypt('content');
445
471
  ````
472
+
473
+ ## Blog
474
+ [ISV Application Development Guide](https://bytedance.feishu.cn/docx/RUZKdGwdyoH4KexMJgDcITQnn0b)
475
+
446
476
  ## LICENSE
447
477
  MIT
448
478
 
package/README.zh.md CHANGED
@@ -402,6 +402,32 @@ const resule = await dispatcher.invoke(data);
402
402
  server.sendResult(result);
403
403
  ```
404
404
 
405
+ #### challenge校验
406
+ 在配置事件请求地址时,开放平台会向请求地址推送一个`application/json`格式的 POST请求,该POST请求用于验证所配置的请求地址的合法性,请求体中会携带一个`challenge`字段,**应用需要在 1 秒内,将接收到的challenge值原样返回给飞书开放平台**。详见:[文档](https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case)
407
+
408
+ 上面sdk提供出的适配器内部封装了这部分验证的逻辑,将options参数中的`autoChallenge`字段设为true即可启用:
409
+ ```typescript
410
+ // adaptDefault
411
+ lark.adaptDefault('/webhook/event', eventDispatcher, {
412
+ autoChallenge: true,
413
+ });
414
+ // express
415
+ lark.adaptExpress(eventDispatcher, {
416
+ autoChallenge: true,
417
+ });
418
+ // koa
419
+ lark.adaptKoa('/webhook/event', eventDispatcher, {
420
+ autoChallenge: true,
421
+ });
422
+ // koa-router
423
+ router.post(
424
+ '/webhook/event',
425
+ lark.adaptKoaRouter(eventDispatcher, {
426
+ autoChallenge: true,
427
+ })
428
+ );
429
+ ```
430
+
405
431
  ### [消息卡片](https://open.feishu.cn/document/ukTMukTMukTM/uczM3QjL3MzN04yNzcDN)
406
432
  对消息卡片的处理亦是对事件处理的一种,两者的不同点仅在于消息卡片的处理器用于响应用户与消息卡片交互所产生的事件,若处理器有返回值(*返回值的数据结构理应为符合[消息卡片结构](https://open.feishu.cn/document/ukTMukTMukTM/uEjNwUjLxYDM14SM2ATN)所定义的结构*),则返回值被用来更新被响应的消息卡片:
407
433
 
@@ -442,6 +468,10 @@ import * as lark from '@larksuiteoapi/node-sdk';
442
468
 
443
469
  new lark.AESCipher('encrypt key').decrypt('content');
444
470
  ```
471
+
472
+ ## Blog
473
+ [ISV(商店应用)开发指南](https://bytedance.feishu.cn/docx/RUZKdGwdyoH4KexMJgDcITQnn0b)
474
+
445
475
  ## 许可协议
446
476
  MIT
447
477
 
package/es/index.js CHANGED
@@ -241,7 +241,16 @@ class Client$1 {
241
241
  });
242
242
  return {
243
243
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
244
- yield res.pipe(fs.createWriteStream(filePath));
244
+ return new Promise((resolve, reject) => {
245
+ const writableStream = fs.createWriteStream(filePath);
246
+ writableStream.on("finish", () => {
247
+ resolve(filePath);
248
+ });
249
+ writableStream.on("error", (e) => {
250
+ reject(e);
251
+ });
252
+ res.pipe(writableStream);
253
+ });
245
254
  }),
246
255
  };
247
256
  }),
@@ -382,7 +391,16 @@ class Client$1 {
382
391
  });
383
392
  return {
384
393
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
385
- yield res.pipe(fs.createWriteStream(filePath));
394
+ return new Promise((resolve, reject) => {
395
+ const writableStream = fs.createWriteStream(filePath);
396
+ writableStream.on("finish", () => {
397
+ resolve(filePath);
398
+ });
399
+ writableStream.on("error", (e) => {
400
+ reject(e);
401
+ });
402
+ res.pipe(writableStream);
403
+ });
386
404
  }),
387
405
  };
388
406
  }),
@@ -2408,7 +2426,16 @@ class Client$1 {
2408
2426
  });
2409
2427
  return {
2410
2428
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
2411
- yield res.pipe(fs.createWriteStream(filePath));
2429
+ return new Promise((resolve, reject) => {
2430
+ const writableStream = fs.createWriteStream(filePath);
2431
+ writableStream.on("finish", () => {
2432
+ resolve(filePath);
2433
+ });
2434
+ writableStream.on("error", (e) => {
2435
+ reject(e);
2436
+ });
2437
+ res.pipe(writableStream);
2438
+ });
2412
2439
  }),
2413
2440
  };
2414
2441
  }),
@@ -3693,7 +3720,16 @@ class Client$1 {
3693
3720
  });
3694
3721
  return {
3695
3722
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
3696
- yield res.pipe(fs.createWriteStream(filePath));
3723
+ return new Promise((resolve, reject) => {
3724
+ const writableStream = fs.createWriteStream(filePath);
3725
+ writableStream.on("finish", () => {
3726
+ resolve(filePath);
3727
+ });
3728
+ writableStream.on("error", (e) => {
3729
+ reject(e);
3730
+ });
3731
+ res.pipe(writableStream);
3732
+ });
3697
3733
  }),
3698
3734
  };
3699
3735
  }),
@@ -8397,7 +8433,16 @@ class Client$1 {
8397
8433
  });
8398
8434
  return {
8399
8435
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
8400
- yield res.pipe(fs.createWriteStream(filePath));
8436
+ return new Promise((resolve, reject) => {
8437
+ const writableStream = fs.createWriteStream(filePath);
8438
+ writableStream.on("finish", () => {
8439
+ resolve(filePath);
8440
+ });
8441
+ writableStream.on("error", (e) => {
8442
+ reject(e);
8443
+ });
8444
+ res.pipe(writableStream);
8445
+ });
8401
8446
  }),
8402
8447
  };
8403
8448
  }),
@@ -8742,7 +8787,16 @@ class Client$1 {
8742
8787
  });
8743
8788
  return {
8744
8789
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
8745
- yield res.pipe(fs.createWriteStream(filePath));
8790
+ return new Promise((resolve, reject) => {
8791
+ const writableStream = fs.createWriteStream(filePath);
8792
+ writableStream.on("finish", () => {
8793
+ resolve(filePath);
8794
+ });
8795
+ writableStream.on("error", (e) => {
8796
+ reject(e);
8797
+ });
8798
+ res.pipe(writableStream);
8799
+ });
8746
8800
  }),
8747
8801
  };
8748
8802
  }),
@@ -9218,7 +9272,16 @@ class Client$1 {
9218
9272
  });
9219
9273
  return {
9220
9274
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
9221
- yield res.pipe(fs.createWriteStream(filePath));
9275
+ return new Promise((resolve, reject) => {
9276
+ const writableStream = fs.createWriteStream(filePath);
9277
+ writableStream.on("finish", () => {
9278
+ resolve(filePath);
9279
+ });
9280
+ writableStream.on("error", (e) => {
9281
+ reject(e);
9282
+ });
9283
+ res.pipe(writableStream);
9284
+ });
9222
9285
  }),
9223
9286
  };
9224
9287
  }),
@@ -9535,7 +9598,16 @@ class Client$1 {
9535
9598
  });
9536
9599
  return {
9537
9600
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
9538
- yield res.pipe(fs.createWriteStream(filePath));
9601
+ return new Promise((resolve, reject) => {
9602
+ const writableStream = fs.createWriteStream(filePath);
9603
+ writableStream.on("finish", () => {
9604
+ resolve(filePath);
9605
+ });
9606
+ writableStream.on("error", (e) => {
9607
+ reject(e);
9608
+ });
9609
+ res.pipe(writableStream);
9610
+ });
9539
9611
  }),
9540
9612
  };
9541
9613
  }),
@@ -10494,7 +10566,16 @@ class Client$1 {
10494
10566
  });
10495
10567
  return {
10496
10568
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
10497
- yield res.pipe(fs.createWriteStream(filePath));
10569
+ return new Promise((resolve, reject) => {
10570
+ const writableStream = fs.createWriteStream(filePath);
10571
+ writableStream.on("finish", () => {
10572
+ resolve(filePath);
10573
+ });
10574
+ writableStream.on("error", (e) => {
10575
+ reject(e);
10576
+ });
10577
+ res.pipe(writableStream);
10578
+ });
10498
10579
  }),
10499
10580
  };
10500
10581
  }),
@@ -11038,7 +11119,16 @@ class Client$1 {
11038
11119
  });
11039
11120
  return {
11040
11121
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
11041
- yield res.pipe(fs.createWriteStream(filePath));
11122
+ return new Promise((resolve, reject) => {
11123
+ const writableStream = fs.createWriteStream(filePath);
11124
+ writableStream.on("finish", () => {
11125
+ resolve(filePath);
11126
+ });
11127
+ writableStream.on("error", (e) => {
11128
+ reject(e);
11129
+ });
11130
+ res.pipe(writableStream);
11131
+ });
11042
11132
  }),
11043
11133
  };
11044
11134
  }),
@@ -13008,7 +13098,16 @@ class Client$1 {
13008
13098
  });
13009
13099
  return {
13010
13100
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13011
- yield res.pipe(fs.createWriteStream(filePath));
13101
+ return new Promise((resolve, reject) => {
13102
+ const writableStream = fs.createWriteStream(filePath);
13103
+ writableStream.on("finish", () => {
13104
+ resolve(filePath);
13105
+ });
13106
+ writableStream.on("error", (e) => {
13107
+ reject(e);
13108
+ });
13109
+ res.pipe(writableStream);
13110
+ });
13012
13111
  }),
13013
13112
  };
13014
13113
  }),
@@ -13072,7 +13171,16 @@ class Client$1 {
13072
13171
  });
13073
13172
  return {
13074
13173
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13075
- yield res.pipe(fs.createWriteStream(filePath));
13174
+ return new Promise((resolve, reject) => {
13175
+ const writableStream = fs.createWriteStream(filePath);
13176
+ writableStream.on("finish", () => {
13177
+ resolve(filePath);
13178
+ });
13179
+ writableStream.on("error", (e) => {
13180
+ reject(e);
13181
+ });
13182
+ res.pipe(writableStream);
13183
+ });
13076
13184
  }),
13077
13185
  };
13078
13186
  }),
@@ -13559,7 +13667,16 @@ class Client$1 {
13559
13667
  });
13560
13668
  return {
13561
13669
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13562
- yield res.pipe(fs.createWriteStream(filePath));
13670
+ return new Promise((resolve, reject) => {
13671
+ const writableStream = fs.createWriteStream(filePath);
13672
+ writableStream.on("finish", () => {
13673
+ resolve(filePath);
13674
+ });
13675
+ writableStream.on("error", (e) => {
13676
+ reject(e);
13677
+ });
13678
+ res.pipe(writableStream);
13679
+ });
13563
13680
  }),
13564
13681
  };
13565
13682
  }),
@@ -17392,7 +17509,16 @@ class Client$1 {
17392
17509
  });
17393
17510
  return {
17394
17511
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
17395
- yield res.pipe(fs.createWriteStream(filePath));
17512
+ return new Promise((resolve, reject) => {
17513
+ const writableStream = fs.createWriteStream(filePath);
17514
+ writableStream.on("finish", () => {
17515
+ resolve(filePath);
17516
+ });
17517
+ writableStream.on("error", (e) => {
17518
+ reject(e);
17519
+ });
17520
+ res.pipe(writableStream);
17521
+ });
17396
17522
  }),
17397
17523
  };
17398
17524
  }),
@@ -19088,13 +19214,40 @@ const pickRequestData = (req) => new Promise((resolve) => {
19088
19214
  });
19089
19215
  });
19090
19216
 
19091
- const adaptDefault = (path, dispatcher) => (req, res) => __awaiter(void 0, void 0, void 0, function* () {
19217
+ const generateChallenge = (data, options) => {
19218
+ if ('encrypt' in data && !options.encryptKey) {
19219
+ throw new Error('auto-challenge need encryptKey, please check for missing in dispatcher');
19220
+ }
19221
+ const targetData = 'encrypt' in data
19222
+ ? JSON.parse(new AESCipher(options.encryptKey).decrypt(data.encrypt))
19223
+ : data;
19224
+ return {
19225
+ isChallenge: targetData.type === 'url_verification',
19226
+ challenge: {
19227
+ challenge: targetData.challenge,
19228
+ },
19229
+ };
19230
+ };
19231
+
19232
+ const adaptDefault = (path, dispatcher, options) => (req, res) => __awaiter(void 0, void 0, void 0, function* () {
19092
19233
  if (req.url !== path) {
19093
19234
  return;
19094
19235
  }
19095
19236
  const data = Object.assign(Object.create({
19096
19237
  headers: req.headers,
19097
19238
  }), yield pickRequestData(req));
19239
+ // 是否自动响应challange事件:
19240
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19241
+ const autoChallenge = get(options, 'autoChallenge', false);
19242
+ if (autoChallenge) {
19243
+ const { isChallenge, challenge } = generateChallenge(data, {
19244
+ encryptKey: dispatcher.encryptKey,
19245
+ });
19246
+ if (isChallenge) {
19247
+ res.end(JSON.stringify(challenge));
19248
+ return;
19249
+ }
19250
+ }
19098
19251
  const value = yield dispatcher.invoke(data);
19099
19252
  // event don't need response
19100
19253
  if (dispatcher instanceof CardActionHandler) {
@@ -19118,6 +19271,18 @@ const adaptExpress = (dispatcher, options) => (req, res) => __awaiter(void 0, vo
19118
19271
  const data = Object.assign(Object.create({
19119
19272
  headers: req.headers,
19120
19273
  }), reqData);
19274
+ // 是否自动响应challange事件:
19275
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19276
+ const autoChallenge = get(options, 'autoChallenge', false);
19277
+ if (autoChallenge) {
19278
+ const { isChallenge, challenge } = generateChallenge(data, {
19279
+ encryptKey: dispatcher.encryptKey,
19280
+ });
19281
+ if (isChallenge) {
19282
+ res.json(challenge);
19283
+ return;
19284
+ }
19285
+ }
19121
19286
  const value = yield dispatcher.invoke(data);
19122
19287
  // event don't need response
19123
19288
  if (dispatcher instanceof CardActionHandler) {
@@ -19143,6 +19308,19 @@ const adaptKoa = (path, dispatcher, options) => (ctx, next) => __awaiter(void 0,
19143
19308
  const data = Object.assign(Object.create({
19144
19309
  headers: req.headers,
19145
19310
  }), reqData);
19311
+ // 是否自动响应challange事件:
19312
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19313
+ const autoChallenge = get(options, 'autoChallenge', false);
19314
+ if (autoChallenge) {
19315
+ const { isChallenge, challenge } = generateChallenge(data, {
19316
+ encryptKey: dispatcher.encryptKey,
19317
+ });
19318
+ if (isChallenge) {
19319
+ ctx.body = challenge;
19320
+ yield next();
19321
+ return;
19322
+ }
19323
+ }
19146
19324
  const value = yield dispatcher.invoke(data);
19147
19325
  // event don't need response
19148
19326
  if (dispatcher instanceof CardActionHandler) {
@@ -19171,6 +19349,19 @@ const adaptKoaRouter = (dispatcher, options) => (ctx, next) => __awaiter(void 0,
19171
19349
  const data = Object.assign(Object.create({
19172
19350
  headers: req.headers,
19173
19351
  }), reqData);
19352
+ // 是否自动响应challange事件:
19353
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19354
+ const autoChallenge = get(options, 'autoChallenge', false);
19355
+ if (autoChallenge) {
19356
+ const { isChallenge, challenge } = generateChallenge(data, {
19357
+ encryptKey: dispatcher.encryptKey,
19358
+ });
19359
+ if (isChallenge) {
19360
+ ctx.body = challenge;
19361
+ yield next();
19362
+ return;
19363
+ }
19364
+ }
19174
19365
  const value = yield dispatcher.invoke(data);
19175
19366
  // event don't need response
19176
19367
  if (dispatcher instanceof CardActionHandler) {
@@ -19182,4 +19373,4 @@ const adaptKoaRouter = (dispatcher, options) => (ctx, next) => __awaiter(void 0,
19182
19373
  yield next();
19183
19374
  });
19184
19375
 
19185
- export { AESCipher, AppType, CardActionHandler, Client, Domain, EventDispatcher, LoggerLevel, adaptDefault, adaptExpress, adaptKoa, adaptKoaRouter, withAll, withHelpDeskCredential, withTenantKey, withTenantToken, withUserAccessToken };
19376
+ export { AESCipher, AppType, CAppTicket, CardActionHandler, Client, Domain, EventDispatcher, LoggerLevel, adaptDefault, adaptExpress, adaptKoa, adaptKoaRouter, withAll, withHelpDeskCredential, withTenantKey, withTenantToken, withUserAccessToken };
package/lib/index.js CHANGED
@@ -256,7 +256,16 @@ class Client$1 {
256
256
  });
257
257
  return {
258
258
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
259
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
259
+ return new Promise((resolve, reject) => {
260
+ const writableStream = fs__default["default"].createWriteStream(filePath);
261
+ writableStream.on("finish", () => {
262
+ resolve(filePath);
263
+ });
264
+ writableStream.on("error", (e) => {
265
+ reject(e);
266
+ });
267
+ res.pipe(writableStream);
268
+ });
260
269
  }),
261
270
  };
262
271
  }),
@@ -397,7 +406,16 @@ class Client$1 {
397
406
  });
398
407
  return {
399
408
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
400
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
409
+ return new Promise((resolve, reject) => {
410
+ const writableStream = fs__default["default"].createWriteStream(filePath);
411
+ writableStream.on("finish", () => {
412
+ resolve(filePath);
413
+ });
414
+ writableStream.on("error", (e) => {
415
+ reject(e);
416
+ });
417
+ res.pipe(writableStream);
418
+ });
401
419
  }),
402
420
  };
403
421
  }),
@@ -2423,7 +2441,16 @@ class Client$1 {
2423
2441
  });
2424
2442
  return {
2425
2443
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
2426
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
2444
+ return new Promise((resolve, reject) => {
2445
+ const writableStream = fs__default["default"].createWriteStream(filePath);
2446
+ writableStream.on("finish", () => {
2447
+ resolve(filePath);
2448
+ });
2449
+ writableStream.on("error", (e) => {
2450
+ reject(e);
2451
+ });
2452
+ res.pipe(writableStream);
2453
+ });
2427
2454
  }),
2428
2455
  };
2429
2456
  }),
@@ -3708,7 +3735,16 @@ class Client$1 {
3708
3735
  });
3709
3736
  return {
3710
3737
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
3711
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
3738
+ return new Promise((resolve, reject) => {
3739
+ const writableStream = fs__default["default"].createWriteStream(filePath);
3740
+ writableStream.on("finish", () => {
3741
+ resolve(filePath);
3742
+ });
3743
+ writableStream.on("error", (e) => {
3744
+ reject(e);
3745
+ });
3746
+ res.pipe(writableStream);
3747
+ });
3712
3748
  }),
3713
3749
  };
3714
3750
  }),
@@ -8412,7 +8448,16 @@ class Client$1 {
8412
8448
  });
8413
8449
  return {
8414
8450
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
8415
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
8451
+ return new Promise((resolve, reject) => {
8452
+ const writableStream = fs__default["default"].createWriteStream(filePath);
8453
+ writableStream.on("finish", () => {
8454
+ resolve(filePath);
8455
+ });
8456
+ writableStream.on("error", (e) => {
8457
+ reject(e);
8458
+ });
8459
+ res.pipe(writableStream);
8460
+ });
8416
8461
  }),
8417
8462
  };
8418
8463
  }),
@@ -8757,7 +8802,16 @@ class Client$1 {
8757
8802
  });
8758
8803
  return {
8759
8804
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
8760
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
8805
+ return new Promise((resolve, reject) => {
8806
+ const writableStream = fs__default["default"].createWriteStream(filePath);
8807
+ writableStream.on("finish", () => {
8808
+ resolve(filePath);
8809
+ });
8810
+ writableStream.on("error", (e) => {
8811
+ reject(e);
8812
+ });
8813
+ res.pipe(writableStream);
8814
+ });
8761
8815
  }),
8762
8816
  };
8763
8817
  }),
@@ -9233,7 +9287,16 @@ class Client$1 {
9233
9287
  });
9234
9288
  return {
9235
9289
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
9236
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
9290
+ return new Promise((resolve, reject) => {
9291
+ const writableStream = fs__default["default"].createWriteStream(filePath);
9292
+ writableStream.on("finish", () => {
9293
+ resolve(filePath);
9294
+ });
9295
+ writableStream.on("error", (e) => {
9296
+ reject(e);
9297
+ });
9298
+ res.pipe(writableStream);
9299
+ });
9237
9300
  }),
9238
9301
  };
9239
9302
  }),
@@ -9550,7 +9613,16 @@ class Client$1 {
9550
9613
  });
9551
9614
  return {
9552
9615
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
9553
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
9616
+ return new Promise((resolve, reject) => {
9617
+ const writableStream = fs__default["default"].createWriteStream(filePath);
9618
+ writableStream.on("finish", () => {
9619
+ resolve(filePath);
9620
+ });
9621
+ writableStream.on("error", (e) => {
9622
+ reject(e);
9623
+ });
9624
+ res.pipe(writableStream);
9625
+ });
9554
9626
  }),
9555
9627
  };
9556
9628
  }),
@@ -10509,7 +10581,16 @@ class Client$1 {
10509
10581
  });
10510
10582
  return {
10511
10583
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
10512
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
10584
+ return new Promise((resolve, reject) => {
10585
+ const writableStream = fs__default["default"].createWriteStream(filePath);
10586
+ writableStream.on("finish", () => {
10587
+ resolve(filePath);
10588
+ });
10589
+ writableStream.on("error", (e) => {
10590
+ reject(e);
10591
+ });
10592
+ res.pipe(writableStream);
10593
+ });
10513
10594
  }),
10514
10595
  };
10515
10596
  }),
@@ -11053,7 +11134,16 @@ class Client$1 {
11053
11134
  });
11054
11135
  return {
11055
11136
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
11056
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
11137
+ return new Promise((resolve, reject) => {
11138
+ const writableStream = fs__default["default"].createWriteStream(filePath);
11139
+ writableStream.on("finish", () => {
11140
+ resolve(filePath);
11141
+ });
11142
+ writableStream.on("error", (e) => {
11143
+ reject(e);
11144
+ });
11145
+ res.pipe(writableStream);
11146
+ });
11057
11147
  }),
11058
11148
  };
11059
11149
  }),
@@ -13023,7 +13113,16 @@ class Client$1 {
13023
13113
  });
13024
13114
  return {
13025
13115
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13026
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
13116
+ return new Promise((resolve, reject) => {
13117
+ const writableStream = fs__default["default"].createWriteStream(filePath);
13118
+ writableStream.on("finish", () => {
13119
+ resolve(filePath);
13120
+ });
13121
+ writableStream.on("error", (e) => {
13122
+ reject(e);
13123
+ });
13124
+ res.pipe(writableStream);
13125
+ });
13027
13126
  }),
13028
13127
  };
13029
13128
  }),
@@ -13087,7 +13186,16 @@ class Client$1 {
13087
13186
  });
13088
13187
  return {
13089
13188
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13090
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
13189
+ return new Promise((resolve, reject) => {
13190
+ const writableStream = fs__default["default"].createWriteStream(filePath);
13191
+ writableStream.on("finish", () => {
13192
+ resolve(filePath);
13193
+ });
13194
+ writableStream.on("error", (e) => {
13195
+ reject(e);
13196
+ });
13197
+ res.pipe(writableStream);
13198
+ });
13091
13199
  }),
13092
13200
  };
13093
13201
  }),
@@ -13574,7 +13682,16 @@ class Client$1 {
13574
13682
  });
13575
13683
  return {
13576
13684
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
13577
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
13685
+ return new Promise((resolve, reject) => {
13686
+ const writableStream = fs__default["default"].createWriteStream(filePath);
13687
+ writableStream.on("finish", () => {
13688
+ resolve(filePath);
13689
+ });
13690
+ writableStream.on("error", (e) => {
13691
+ reject(e);
13692
+ });
13693
+ res.pipe(writableStream);
13694
+ });
13578
13695
  }),
13579
13696
  };
13580
13697
  }),
@@ -17407,7 +17524,16 @@ class Client$1 {
17407
17524
  });
17408
17525
  return {
17409
17526
  writeFile: (filePath) => __awaiter(this, void 0, void 0, function* () {
17410
- yield res.pipe(fs__default["default"].createWriteStream(filePath));
17527
+ return new Promise((resolve, reject) => {
17528
+ const writableStream = fs__default["default"].createWriteStream(filePath);
17529
+ writableStream.on("finish", () => {
17530
+ resolve(filePath);
17531
+ });
17532
+ writableStream.on("error", (e) => {
17533
+ reject(e);
17534
+ });
17535
+ res.pipe(writableStream);
17536
+ });
17411
17537
  }),
17412
17538
  };
17413
17539
  }),
@@ -19103,13 +19229,40 @@ const pickRequestData = (req) => new Promise((resolve) => {
19103
19229
  });
19104
19230
  });
19105
19231
 
19106
- const adaptDefault = (path, dispatcher) => (req, res) => __awaiter(void 0, void 0, void 0, function* () {
19232
+ const generateChallenge = (data, options) => {
19233
+ if ('encrypt' in data && !options.encryptKey) {
19234
+ throw new Error('auto-challenge need encryptKey, please check for missing in dispatcher');
19235
+ }
19236
+ const targetData = 'encrypt' in data
19237
+ ? JSON.parse(new AESCipher(options.encryptKey).decrypt(data.encrypt))
19238
+ : data;
19239
+ return {
19240
+ isChallenge: targetData.type === 'url_verification',
19241
+ challenge: {
19242
+ challenge: targetData.challenge,
19243
+ },
19244
+ };
19245
+ };
19246
+
19247
+ const adaptDefault = (path, dispatcher, options) => (req, res) => __awaiter(void 0, void 0, void 0, function* () {
19107
19248
  if (req.url !== path) {
19108
19249
  return;
19109
19250
  }
19110
19251
  const data = Object.assign(Object.create({
19111
19252
  headers: req.headers,
19112
19253
  }), yield pickRequestData(req));
19254
+ // 是否自动响应challange事件:
19255
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19256
+ const autoChallenge = get__default["default"](options, 'autoChallenge', false);
19257
+ if (autoChallenge) {
19258
+ const { isChallenge, challenge } = generateChallenge(data, {
19259
+ encryptKey: dispatcher.encryptKey,
19260
+ });
19261
+ if (isChallenge) {
19262
+ res.end(JSON.stringify(challenge));
19263
+ return;
19264
+ }
19265
+ }
19113
19266
  const value = yield dispatcher.invoke(data);
19114
19267
  // event don't need response
19115
19268
  if (dispatcher instanceof CardActionHandler) {
@@ -19133,6 +19286,18 @@ const adaptExpress = (dispatcher, options) => (req, res) => __awaiter(void 0, vo
19133
19286
  const data = Object.assign(Object.create({
19134
19287
  headers: req.headers,
19135
19288
  }), reqData);
19289
+ // 是否自动响应challange事件:
19290
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19291
+ const autoChallenge = get__default["default"](options, 'autoChallenge', false);
19292
+ if (autoChallenge) {
19293
+ const { isChallenge, challenge } = generateChallenge(data, {
19294
+ encryptKey: dispatcher.encryptKey,
19295
+ });
19296
+ if (isChallenge) {
19297
+ res.json(challenge);
19298
+ return;
19299
+ }
19300
+ }
19136
19301
  const value = yield dispatcher.invoke(data);
19137
19302
  // event don't need response
19138
19303
  if (dispatcher instanceof CardActionHandler) {
@@ -19158,6 +19323,19 @@ const adaptKoa = (path, dispatcher, options) => (ctx, next) => __awaiter(void 0,
19158
19323
  const data = Object.assign(Object.create({
19159
19324
  headers: req.headers,
19160
19325
  }), reqData);
19326
+ // 是否自动响应challange事件:
19327
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19328
+ const autoChallenge = get__default["default"](options, 'autoChallenge', false);
19329
+ if (autoChallenge) {
19330
+ const { isChallenge, challenge } = generateChallenge(data, {
19331
+ encryptKey: dispatcher.encryptKey,
19332
+ });
19333
+ if (isChallenge) {
19334
+ ctx.body = challenge;
19335
+ yield next();
19336
+ return;
19337
+ }
19338
+ }
19161
19339
  const value = yield dispatcher.invoke(data);
19162
19340
  // event don't need response
19163
19341
  if (dispatcher instanceof CardActionHandler) {
@@ -19186,6 +19364,19 @@ const adaptKoaRouter = (dispatcher, options) => (ctx, next) => __awaiter(void 0,
19186
19364
  const data = Object.assign(Object.create({
19187
19365
  headers: req.headers,
19188
19366
  }), reqData);
19367
+ // 是否自动响应challange事件:
19368
+ // https://open.feishu.cn/document/ukTMukTMukTM/uYDNxYjL2QTM24iN0EjN/event-subscription-configure-/request-url-configuration-case
19369
+ const autoChallenge = get__default["default"](options, 'autoChallenge', false);
19370
+ if (autoChallenge) {
19371
+ const { isChallenge, challenge } = generateChallenge(data, {
19372
+ encryptKey: dispatcher.encryptKey,
19373
+ });
19374
+ if (isChallenge) {
19375
+ ctx.body = challenge;
19376
+ yield next();
19377
+ return;
19378
+ }
19379
+ }
19189
19380
  const value = yield dispatcher.invoke(data);
19190
19381
  // event don't need response
19191
19382
  if (dispatcher instanceof CardActionHandler) {
@@ -19198,6 +19389,7 @@ const adaptKoaRouter = (dispatcher, options) => (ctx, next) => __awaiter(void 0,
19198
19389
  });
19199
19390
 
19200
19391
  exports.AESCipher = AESCipher;
19392
+ exports.CAppTicket = CAppTicket;
19201
19393
  exports.CardActionHandler = CardActionHandler;
19202
19394
  exports.Client = Client;
19203
19395
  exports.EventDispatcher = EventDispatcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larksuiteoapi/node-sdk",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "larksuite open sdk for nodejs",
5
5
  "keywords": [
6
6
  "feishu",
@@ -37,26 +37,31 @@
37
37
  "lodash.pickby": "^4.6.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@typescript-eslint/parser": "^5.27.1",
40
+ "@koa/router": "^12.0.0",
41
41
  "@rollup/plugin-alias": "^3.1.9",
42
42
  "@rollup/plugin-typescript": "^8.3.2",
43
43
  "@types/jest": "^28.1.3",
44
44
  "@types/lodash.get": "^4.4.7",
45
45
  "@types/lodash.merge": "^4.6.7",
46
46
  "@types/lodash.pick": "^4.4.7",
47
+ "@typescript-eslint/parser": "^5.27.1",
48
+ "body-parser": "^1.20.1",
47
49
  "eslint": "^8.17.0",
48
50
  "eslint-config-airbnb-base": "^15.0.0",
49
51
  "eslint-config-prettier": "^8.5.0",
50
52
  "eslint-plugin-import": "^2.26.0",
51
- "prettier": "2.6.2",
53
+ "express": "^4.18.2",
52
54
  "jest": "^28.1.1",
55
+ "koa": "^2.13.4",
56
+ "koa-body": "^5.0.0",
57
+ "prettier": "2.6.2",
53
58
  "rollup": "^2.75.5",
54
59
  "rollup-plugin-dts": "^4.2.2",
55
60
  "rollup-plugin-license": "^2.8.1",
56
61
  "ts-jest": "^28.0.5",
62
+ "ts-node": "^10.8.1",
57
63
  "tsconfig-paths": "^4.0.0",
58
64
  "tslib": "^2.4.0",
59
- "ts-node": "^10.8.1",
60
65
  "typescript": "^4.7.3"
61
66
  },
62
67
  "publishConfig": {
package/types/index.d.ts CHANGED
@@ -41,6 +41,7 @@ declare enum LoggerLevel {
41
41
  }
42
42
 
43
43
  declare const CTenantKey: unique symbol;
44
+ declare const CAppTicket: unique symbol;
44
45
  declare const CWithHelpdeskAuthorization: unique symbol;
45
46
  declare const CWithUserAccessToken: unique symbol;
46
47
 
@@ -111,7 +112,7 @@ declare abstract class Client$1 {
111
112
  access_record_id?: string;
112
113
  };
113
114
  }, options?: IRequestOptions$1) => Promise<{
114
- writeFile: (filePath: string) => Promise<void>;
115
+ writeFile: (filePath: string) => Promise<unknown>;
115
116
  }>;
116
117
  };
117
118
  /**
@@ -225,7 +226,7 @@ declare abstract class Client$1 {
225
226
  user_id: string;
226
227
  };
227
228
  }, options?: IRequestOptions$1) => Promise<{
228
- writeFile: (filePath: string) => Promise<void>;
229
+ writeFile: (filePath: string) => Promise<unknown>;
229
230
  }>;
230
231
  /**
231
232
  * {@link https://open.feishu.cn/api-explorer?project=acs&resource=user.face&apiName=update&version=v1 click to debug }
@@ -3137,7 +3138,7 @@ declare abstract class Client$1 {
3137
3138
  file_id: string;
3138
3139
  };
3139
3140
  }, options?: IRequestOptions$1) => Promise<{
3140
- writeFile: (filePath: string) => Promise<void>;
3141
+ writeFile: (filePath: string) => Promise<unknown>;
3141
3142
  }>;
3142
3143
  /**
3143
3144
  * {@link https://open.feishu.cn/api-explorer?project=attendance&resource=file&apiName=upload&version=v1 click to debug }
@@ -5914,7 +5915,7 @@ declare abstract class Client$1 {
5914
5915
  file_token?: string;
5915
5916
  };
5916
5917
  }, options?: IRequestOptions$1) => Promise<{
5917
- writeFile: (filePath: string) => Promise<void>;
5918
+ writeFile: (filePath: string) => Promise<unknown>;
5918
5919
  }>;
5919
5920
  /**
5920
5921
  * {@link https://open.feishu.cn/api-explorer?project=baike&resource=file&apiName=upload&version=v1 click to debug }
@@ -22576,7 +22577,7 @@ declare abstract class Client$1 {
22576
22577
  file_token: string;
22577
22578
  };
22578
22579
  }, options?: IRequestOptions$1) => Promise<{
22579
- writeFile: (filePath: string) => Promise<void>;
22580
+ writeFile: (filePath: string) => Promise<unknown>;
22580
22581
  }>;
22581
22582
  /**
22582
22583
  * {@link https://open.feishu.cn/api-explorer?project=drive&resource=export_task&apiName=get&version=v1 click to debug }
@@ -23098,7 +23099,7 @@ declare abstract class Client$1 {
23098
23099
  file_token?: string;
23099
23100
  };
23100
23101
  }, options?: IRequestOptions$1) => Promise<{
23101
- writeFile: (filePath: string) => Promise<void>;
23102
+ writeFile: (filePath: string) => Promise<unknown>;
23102
23103
  }>;
23103
23104
  listWithIterator: (payload?: {
23104
23105
  params?: {
@@ -23560,7 +23561,7 @@ declare abstract class Client$1 {
23560
23561
  file_token: string;
23561
23562
  };
23562
23563
  }, options?: IRequestOptions$1) => Promise<{
23563
- writeFile: (filePath: string) => Promise<void>;
23564
+ writeFile: (filePath: string) => Promise<unknown>;
23564
23565
  }>;
23565
23566
  /**
23566
23567
  * {@link https://open.feishu.cn/api-explorer?project=drive&resource=media&apiName=upload_all&version=v1 click to debug }
@@ -23907,7 +23908,7 @@ declare abstract class Client$1 {
23907
23908
  token: string;
23908
23909
  };
23909
23910
  }, options?: IRequestOptions$1) => Promise<{
23910
- writeFile: (filePath: string) => Promise<void>;
23911
+ writeFile: (filePath: string) => Promise<unknown>;
23911
23912
  }>;
23912
23913
  };
23913
23914
  /**
@@ -25203,7 +25204,7 @@ declare abstract class Client$1 {
25203
25204
  image_key?: string;
25204
25205
  };
25205
25206
  }, options?: IRequestOptions$1) => Promise<{
25206
- writeFile: (filePath: string) => Promise<void>;
25207
+ writeFile: (filePath: string) => Promise<unknown>;
25207
25208
  }>;
25208
25209
  /**
25209
25210
  * {@link https://open.feishu.cn/api-explorer?project=helpdesk&resource=faq&apiName=get&version=v1 click to debug }
@@ -26179,7 +26180,7 @@ declare abstract class Client$1 {
26179
26180
  index?: number;
26180
26181
  };
26181
26182
  }, options?: IRequestOptions$1) => Promise<{
26182
- writeFile: (filePath: string) => Promise<void>;
26183
+ writeFile: (filePath: string) => Promise<unknown>;
26183
26184
  }>;
26184
26185
  /**
26185
26186
  * {@link https://open.feishu.cn/api-explorer?project=helpdesk&resource=ticket&apiName=update&version=v1 click to debug }
@@ -29189,7 +29190,7 @@ declare abstract class Client$1 {
29189
29190
  file_key: string;
29190
29191
  };
29191
29192
  }, options?: IRequestOptions$1) => Promise<{
29192
- writeFile: (filePath: string) => Promise<void>;
29193
+ writeFile: (filePath: string) => Promise<unknown>;
29193
29194
  }>;
29194
29195
  };
29195
29196
  /**
@@ -29231,7 +29232,7 @@ declare abstract class Client$1 {
29231
29232
  image_key: string;
29232
29233
  };
29233
29234
  }, options?: IRequestOptions$1) => Promise<{
29234
- writeFile: (filePath: string) => Promise<void>;
29235
+ writeFile: (filePath: string) => Promise<unknown>;
29235
29236
  }>;
29236
29237
  };
29237
29238
  /**
@@ -29805,7 +29806,7 @@ declare abstract class Client$1 {
29805
29806
  file_key: string;
29806
29807
  };
29807
29808
  }, options?: IRequestOptions$1) => Promise<{
29808
- writeFile: (filePath: string) => Promise<void>;
29809
+ writeFile: (filePath: string) => Promise<unknown>;
29809
29810
  }>;
29810
29811
  };
29811
29812
  /**
@@ -34388,7 +34389,7 @@ declare abstract class Client$1 {
34388
34389
  file_token: string;
34389
34390
  };
34390
34391
  }, options?: IRequestOptions$1) => Promise<{
34391
- writeFile: (filePath: string) => Promise<void>;
34392
+ writeFile: (filePath: string) => Promise<unknown>;
34392
34393
  }>;
34393
34394
  /**
34394
34395
  * {@link https://open.feishu.cn/api-explorer?project=vc&resource=export&apiName=get&version=v1 click to debug }
@@ -39442,18 +39443,23 @@ declare class CardActionHandler {
39442
39443
  invoke(data: any): Promise<any>;
39443
39444
  }
39444
39445
 
39445
- declare const adaptDefault: (path: string, dispatcher: EventDispatcher | CardActionHandler) => (req: any, res: any) => Promise<void>;
39446
+ declare const adaptDefault: (path: string, dispatcher: EventDispatcher | CardActionHandler, options?: {
39447
+ autoChallenge?: boolean;
39448
+ }) => (req: any, res: any) => Promise<void>;
39446
39449
 
39447
39450
  declare const adaptExpress: (dispatcher: EventDispatcher | CardActionHandler, options?: {
39448
39451
  logger?: Logger;
39452
+ autoChallenge?: boolean;
39449
39453
  }) => (req: any, res: any) => Promise<void>;
39450
39454
 
39451
39455
  declare const adaptKoa: (path: string, dispatcher: EventDispatcher | CardActionHandler, options?: {
39452
39456
  logger?: Logger;
39457
+ autoChallenge?: boolean;
39453
39458
  }) => (ctx: any, next: any) => Promise<void>;
39454
39459
 
39455
39460
  declare const adaptKoaRouter: (dispatcher: EventDispatcher | CardActionHandler, options?: {
39456
39461
  logger?: Logger;
39462
+ autoChallenge?: boolean;
39457
39463
  }) => (ctx: any, next: any) => Promise<void>;
39458
39464
 
39459
- export { AESCipher, AppType, CardActionHandler, Client, Domain, EventDispatcher, IHandles as EventHandles, LoggerLevel, adaptDefault, adaptExpress, adaptKoa, adaptKoaRouter, withAll, withHelpDeskCredential, withTenantKey, withTenantToken, withUserAccessToken };
39465
+ export { AESCipher, AppType, CAppTicket, CardActionHandler, Client, Domain, EventDispatcher, IHandles as EventHandles, LoggerLevel, adaptDefault, adaptExpress, adaptKoa, adaptKoaRouter, withAll, withHelpDeskCredential, withTenantKey, withTenantToken, withUserAccessToken };