n8n-dingtalk 0.0.13

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.
@@ -0,0 +1,1254 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.DingTalkRobot = exports.appendMentions = exports.parseMentionList = void 0;
30
+ const n8n_workflow_1 = require("n8n-workflow");
31
+ const crypto_1 = __importDefault(require("crypto"));
32
+ const axios_1 = __importDefault(require("axios"));
33
+ const $Util = __importStar(require("@alicloud/tea-util"));
34
+ const client_1 = __importStar(require("@alicloud/dingtalk/dist/robot_1_0/client")), $RobotClient = client_1;
35
+ const $OpenApi = __importStar(require("@alicloud/openapi-client"));
36
+ const client_2 = __importStar(require("@alicloud/dingtalk/dist/oauth2_1_0/client")), $AuthClient = client_2;
37
+ const form_data_1 = __importDefault(require("form-data"));
38
+ const fs_1 = __importDefault(require("fs"));
39
+ const path_1 = __importDefault(require("path"));
40
+ const os_1 = __importDefault(require("os"));
41
+ function parseMentionList(value) {
42
+ if (!value) {
43
+ return [];
44
+ }
45
+ return value
46
+ .split(',')
47
+ .map((item) => item.trim())
48
+ .filter((item) => item.length > 0);
49
+ }
50
+ exports.parseMentionList = parseMentionList;
51
+ function appendMentions(content, atMobiles, atUserIds) {
52
+ const mentions = [
53
+ ...atMobiles.map((mobile) => `@${mobile}`),
54
+ ...atUserIds.map((userId) => `@${userId}`),
55
+ ];
56
+ const uniqueMentions = [...new Set(mentions)];
57
+ const missingMentions = uniqueMentions.filter((mention) => !content.includes(mention));
58
+ if (missingMentions.length === 0) {
59
+ return content;
60
+ }
61
+ const separator = content.endsWith('\n') || content.length === 0 ? '' : '\n';
62
+ return `${content}${separator}${missingMentions.join(' ')}`;
63
+ }
64
+ exports.appendMentions = appendMentions;
65
+ class DingTalkRobot {
66
+ constructor() {
67
+ this.description = {
68
+ displayName: '钉钉机器人',
69
+ name: 'dingTalkRobot',
70
+ icon: 'file:dingtalk.svg',
71
+ group: ['input'],
72
+ version: 1,
73
+ subtitle: '={{$parameter["msgtype"]}}',
74
+ description: '钉钉机器人API',
75
+ defaults: {
76
+ name: '钉钉机器人',
77
+ },
78
+ inputs: ['main'],
79
+ outputs: ['main'],
80
+ credentials: [
81
+ {
82
+ name: 'dingTalkCustomRobotApi',
83
+ required: true,
84
+ displayOptions: {
85
+ show: {
86
+ type: ['customRobot'],
87
+ },
88
+ },
89
+ },
90
+ {
91
+ name: 'dingTalkCompanyApi',
92
+ required: true,
93
+ displayOptions: {
94
+ show: {
95
+ type: ['companyInternalRobot'],
96
+ },
97
+ },
98
+ },
99
+ ],
100
+ properties: [
101
+ {
102
+ displayName: 'Type',
103
+ name: 'type',
104
+ type: 'options',
105
+ required: true,
106
+ noDataExpression: true,
107
+ options: [
108
+ {
109
+ name: '自定义机器人',
110
+ value: 'customRobot',
111
+ description: '自定义机器人存在限流, 每分钟20次',
112
+ action: '自定义机器人',
113
+ },
114
+ {
115
+ name: '企业内部开发机器人',
116
+ value: 'companyInternalRobot',
117
+ action: '企业内部开发机器人',
118
+ },
119
+ ],
120
+ default: 'customRobot',
121
+ },
122
+ {
123
+ displayName: '是否使用JSON格式数据模式',
124
+ name: 'enableJsonMode',
125
+ type: 'boolean',
126
+ default: false,
127
+ required: true,
128
+ placeholder: 'JSON格式数据模式下自行构建数据结构',
129
+ displayOptions: {
130
+ show: {
131
+ type: ['customRobot', 'companyInternalRobot'],
132
+ },
133
+ },
134
+ },
135
+ {
136
+ displayName: '数据内容',
137
+ name: 'json',
138
+ type: 'json',
139
+ default: '',
140
+ required: true,
141
+ displayOptions: {
142
+ show: {
143
+ type: ['customRobot', 'companyInternalRobot'],
144
+ enableJsonMode: [true],
145
+ },
146
+ },
147
+ },
148
+ {
149
+ displayName: '用户集合',
150
+ name: 'userIds',
151
+ required: true,
152
+ placeholder: '添加用户',
153
+ type: 'fixedCollection',
154
+ typeOptions: {
155
+ multipleValues: true,
156
+ },
157
+ displayOptions: {
158
+ show: {
159
+ type: ['companyInternalRobot'],
160
+ enableJsonMode: [false],
161
+ },
162
+ },
163
+ default: {},
164
+ options: [
165
+ {
166
+ name: 'users',
167
+ displayName: '用户',
168
+ values: [
169
+ {
170
+ displayName: '用户电话',
171
+ name: 'mobile',
172
+ type: 'number',
173
+ default: '',
174
+ },
175
+ ],
176
+ },
177
+ ],
178
+ },
179
+ {
180
+ displayName: '消息类型',
181
+ name: 'msgKey',
182
+ type: 'options',
183
+ required: true,
184
+ options: [
185
+ {
186
+ name: 'sampleActionCard2类型',
187
+ value: 'sampleActionCard2',
188
+ description: '竖向两个按钮类型',
189
+ },
190
+ {
191
+ name: 'sampleActionCard3类型',
192
+ value: 'sampleActionCard3',
193
+ description: '竖向三个按钮类型',
194
+ },
195
+ {
196
+ name: 'sampleActionCard4类型',
197
+ value: 'sampleActionCard4',
198
+ description: '竖向四个按钮类型',
199
+ },
200
+ {
201
+ name: 'sampleActionCard5类型',
202
+ value: 'sampleActionCard5',
203
+ description: '竖向五个按钮类型',
204
+ },
205
+ {
206
+ name: 'sampleActionCard6类型',
207
+ value: 'sampleActionCard6',
208
+ description: '横向两个个按钮类型',
209
+ },
210
+ {
211
+ name: 'sampleActionCard类型',
212
+ value: 'sampleActionCard',
213
+ description: '单按钮类型',
214
+ },
215
+ {
216
+ name: 'sampleImageMsg类型',
217
+ value: 'sampleImageMsg',
218
+ },
219
+ {
220
+ name: 'sampleLink类型',
221
+ value: 'sampleLink',
222
+ },
223
+ {
224
+ name: 'sampleMarkdown类型',
225
+ value: 'sampleMarkdown',
226
+ },
227
+ {
228
+ name: 'sampleText类型',
229
+ value: 'sampleText',
230
+ },
231
+ {
232
+ name: 'sampleFile文件类型',
233
+ value: 'sampleFile',
234
+ },
235
+ ],
236
+ default: 'sampleText',
237
+ displayOptions: {
238
+ show: {
239
+ type: ['companyInternalRobot'],
240
+ enableJsonMode: [false],
241
+ },
242
+ },
243
+ },
244
+ {
245
+ displayName: '消息类型',
246
+ name: 'msgtype',
247
+ type: 'options',
248
+ required: true,
249
+ options: [
250
+ {
251
+ name: 'ActionCard类型',
252
+ value: 'actionCard',
253
+ },
254
+ {
255
+ name: 'FeedCard类型',
256
+ value: 'feedCard',
257
+ },
258
+ {
259
+ name: 'Link类型',
260
+ value: 'link',
261
+ },
262
+ {
263
+ name: 'Markdown类型',
264
+ value: 'markdown',
265
+ },
266
+ {
267
+ name: 'Text类型',
268
+ value: 'text',
269
+ },
270
+ ],
271
+ default: 'text',
272
+ displayOptions: {
273
+ show: {
274
+ type: ['customRobot'],
275
+ enableJsonMode: [false],
276
+ },
277
+ },
278
+ },
279
+ {
280
+ displayName: '是否@所有人',
281
+ name: 'isAtAll',
282
+ type: 'boolean',
283
+ default: false,
284
+ placeholder: '',
285
+ displayOptions: {
286
+ show: {
287
+ type: ['customRobot'],
288
+ enableJsonMode: [false],
289
+ msgtype: ['text', 'markdown'],
290
+ },
291
+ },
292
+ },
293
+ {
294
+ displayName: '被@人的手机号',
295
+ name: 'atMobiles',
296
+ type: 'string',
297
+ default: '',
298
+ description: '被@人的手机号,多个用,隔开',
299
+ displayOptions: {
300
+ show: {
301
+ type: ['customRobot'],
302
+ enableJsonMode: [false],
303
+ msgtype: ['text', 'markdown'],
304
+ isAtAll: [false],
305
+ },
306
+ },
307
+ },
308
+ {
309
+ displayName: '被@人的用户Userid',
310
+ name: 'atUserIds',
311
+ type: 'string',
312
+ default: '',
313
+ description: '被@人的用户userid,多个用,隔开',
314
+ displayOptions: {
315
+ show: {
316
+ type: ['customRobot'],
317
+ enableJsonMode: [false],
318
+ msgtype: ['text', 'markdown'],
319
+ isAtAll: [false],
320
+ },
321
+ },
322
+ },
323
+ {
324
+ displayName: '消息内容',
325
+ name: 'content',
326
+ type: 'string',
327
+ default: '',
328
+ required: true,
329
+ placeholder: '',
330
+ typeOptions: {
331
+ rows: 5,
332
+ },
333
+ displayOptions: {
334
+ show: {
335
+ enableJsonMode: [false],
336
+ type: ['customRobot'],
337
+ msgtype: ['text'],
338
+ },
339
+ },
340
+ },
341
+ {
342
+ displayName: '消息内容',
343
+ name: 'content',
344
+ type: 'string',
345
+ default: '',
346
+ required: true,
347
+ placeholder: '',
348
+ typeOptions: {
349
+ rows: 5,
350
+ },
351
+ displayOptions: {
352
+ show: {
353
+ enableJsonMode: [false],
354
+ type: ['companyInternalRobot'],
355
+ msgKey: ['sampleText'],
356
+ },
357
+ },
358
+ },
359
+ {
360
+ displayName: '消息标题',
361
+ name: 'title',
362
+ type: 'string',
363
+ default: '',
364
+ required: true,
365
+ description: '首屏会话透出的展示内容',
366
+ displayOptions: {
367
+ show: {
368
+ type: ['customRobot'],
369
+ enableJsonMode: [false],
370
+ msgtype: ['markdown', 'actionCard'],
371
+ },
372
+ },
373
+ },
374
+ {
375
+ displayName: 'Markdown格式的消息',
376
+ name: 'markdownText',
377
+ type: 'string',
378
+ default: '',
379
+ required: true,
380
+ placeholder: '',
381
+ typeOptions: {
382
+ rows: 5,
383
+ },
384
+ displayOptions: {
385
+ show: {
386
+ type: ['customRobot'],
387
+ enableJsonMode: [false],
388
+ msgtype: ['markdown', 'actionCard'],
389
+ },
390
+ },
391
+ },
392
+ {
393
+ displayName: '消息标题',
394
+ name: 'title',
395
+ type: 'string',
396
+ default: '',
397
+ required: true,
398
+ displayOptions: {
399
+ show: {
400
+ type: ['customRobot'],
401
+ enableJsonMode: [false],
402
+ msgtype: ['link'],
403
+ },
404
+ },
405
+ },
406
+ {
407
+ displayName: '消息标题',
408
+ name: 'title',
409
+ type: 'string',
410
+ default: '',
411
+ required: true,
412
+ displayOptions: {
413
+ show: {
414
+ type: ['companyInternalRobot'],
415
+ enableJsonMode: [false],
416
+ msgKey: [
417
+ 'sampleMarkdown',
418
+ 'sampleLink',
419
+ 'sampleActionCard',
420
+ 'sampleActionCard2',
421
+ 'sampleActionCard3',
422
+ 'sampleActionCard4',
423
+ 'sampleActionCard5',
424
+ 'sampleActionCard6',
425
+ ],
426
+ },
427
+ },
428
+ },
429
+ {
430
+ displayName: '是否单个按钮',
431
+ name: 'isSingleButton',
432
+ type: 'boolean',
433
+ default: true,
434
+ required: true,
435
+ placeholder: '',
436
+ displayOptions: {
437
+ show: {
438
+ type: ['customRobot'],
439
+ enableJsonMode: [false],
440
+ msgtype: ['actionCard'],
441
+ },
442
+ },
443
+ },
444
+ {
445
+ displayName: '单个按钮的标题',
446
+ name: 'singleTitle',
447
+ type: 'string',
448
+ default: '',
449
+ required: true,
450
+ displayOptions: {
451
+ show: {
452
+ type: ['customRobot'],
453
+ enableJsonMode: [false],
454
+ msgtype: ['actionCard'],
455
+ isSingleButton: [true],
456
+ },
457
+ },
458
+ },
459
+ {
460
+ displayName: '点击消息跳转的URL',
461
+ name: 'singleURL',
462
+ type: 'string',
463
+ default: '',
464
+ required: true,
465
+ description: '点击消息跳转的URL,打开方式如下:\n移动端,在钉钉客户端内打开\nPC端 默认侧边栏打开、希望在外部浏览器打开',
466
+ displayOptions: {
467
+ show: {
468
+ type: ['customRobot'],
469
+ enableJsonMode: [false],
470
+ msgtype: ['actionCard'],
471
+ isSingleButton: [true],
472
+ },
473
+ },
474
+ },
475
+ {
476
+ displayName: '点击消息跳转的URL',
477
+ name: 'singleURL',
478
+ type: 'string',
479
+ default: '',
480
+ required: true,
481
+ description: '点击消息跳转的URL,打开方式如下:\n移动端,在钉钉客户端内打开\nPC端 默认侧边栏打开、希望在外部浏览器打开',
482
+ displayOptions: {
483
+ show: {
484
+ type: ['companyInternalRobot'],
485
+ enableJsonMode: [false],
486
+ msgKey: ['sampleActionCard'],
487
+ },
488
+ },
489
+ },
490
+ {
491
+ displayName: '单个按钮的标题',
492
+ name: 'singleTitle',
493
+ type: 'string',
494
+ default: '',
495
+ required: true,
496
+ displayOptions: {
497
+ show: {
498
+ type: ['companyInternalRobot'],
499
+ enableJsonMode: [false],
500
+ msgKey: ['sampleActionCard'],
501
+ },
502
+ },
503
+ },
504
+ {
505
+ displayName: '点击消息跳转的URL',
506
+ name: 'messageUrl',
507
+ type: 'string',
508
+ default: '',
509
+ required: true,
510
+ description: '点击消息跳转的URL,打开方式如下:\n移动端,在钉钉客户端内打开\nPC端 默认侧边栏打开、希望在外部浏览器打开',
511
+ displayOptions: {
512
+ show: {
513
+ type: ['companyInternalRobot'],
514
+ enableJsonMode: [false],
515
+ msgKey: ['sampleLink'],
516
+ },
517
+ },
518
+ },
519
+ {
520
+ displayName: '点击消息跳转的URL',
521
+ name: 'url',
522
+ type: 'string',
523
+ default: '',
524
+ required: true,
525
+ description: '点击消息跳转的URL,打开方式如下:\n移动端,在钉钉客户端内打开\nPC端 默认侧边栏打开、希望在外部浏览器打开',
526
+ displayOptions: {
527
+ show: {
528
+ type: ['customRobot'],
529
+ enableJsonMode: [false],
530
+ msgtype: ['link'],
531
+ },
532
+ },
533
+ },
534
+ {
535
+ displayName: '图片URL',
536
+ name: 'picUrl',
537
+ type: 'string',
538
+ default: '',
539
+ displayOptions: {
540
+ show: {
541
+ type: ['customRobot'],
542
+ enableJsonMode: [false],
543
+ msgtype: ['link'],
544
+ },
545
+ },
546
+ },
547
+ {
548
+ displayName: '图片URL',
549
+ name: 'picUrl',
550
+ type: 'string',
551
+ default: '',
552
+ displayOptions: {
553
+ show: {
554
+ type: ['companyInternalRobot'],
555
+ enableJsonMode: [false],
556
+ msgKey: ['sampleLink'],
557
+ },
558
+ },
559
+ },
560
+ {
561
+ displayName: '图片URL',
562
+ name: 'photoURL',
563
+ type: 'string',
564
+ default: '',
565
+ displayOptions: {
566
+ show: {
567
+ type: ['companyInternalRobot'],
568
+ enableJsonMode: [false],
569
+ msgKey: ['sampleImageMsg'],
570
+ },
571
+ },
572
+ },
573
+ {
574
+ displayName: '消息内容',
575
+ name: 'text',
576
+ type: 'string',
577
+ default: '',
578
+ required: true,
579
+ description: '消息内容。如果太长只会部分展示。',
580
+ placeholder: '',
581
+ typeOptions: {
582
+ rows: 5,
583
+ },
584
+ displayOptions: {
585
+ show: {
586
+ type: ['customRobot'],
587
+ enableJsonMode: [false],
588
+ msgtype: ['link'],
589
+ },
590
+ },
591
+ },
592
+ {
593
+ displayName: '消息内容',
594
+ name: 'text',
595
+ type: 'string',
596
+ default: '',
597
+ required: true,
598
+ description: '消息内容。如果太长只会部分展示。',
599
+ placeholder: '',
600
+ typeOptions: {
601
+ rows: 5,
602
+ },
603
+ displayOptions: {
604
+ show: {
605
+ type: ['companyInternalRobot'],
606
+ enableJsonMode: [false],
607
+ msgKey: [
608
+ 'sampleMarkdown',
609
+ 'sampleLink',
610
+ 'sampleActionCard',
611
+ 'sampleActionCard2',
612
+ 'sampleActionCard3',
613
+ 'sampleActionCard4',
614
+ 'sampleActionCard5',
615
+ 'sampleActionCard6',
616
+ ],
617
+ },
618
+ },
619
+ },
620
+ {
621
+ displayName: '按钮1标题',
622
+ name: 'actionTitle1',
623
+ type: 'string',
624
+ default: '',
625
+ required: true,
626
+ displayOptions: {
627
+ show: {
628
+ type: ['companyInternalRobot'],
629
+ enableJsonMode: [false],
630
+ msgKey: [
631
+ 'sampleActionCard2',
632
+ 'sampleActionCard3',
633
+ 'sampleActionCard4',
634
+ 'sampleActionCard5',
635
+ ],
636
+ },
637
+ },
638
+ },
639
+ {
640
+ displayName: '按钮2标题',
641
+ name: 'actionTitle2',
642
+ type: 'string',
643
+ default: '',
644
+ required: true,
645
+ displayOptions: {
646
+ show: {
647
+ type: ['companyInternalRobot'],
648
+ enableJsonMode: [false],
649
+ msgKey: [
650
+ 'sampleActionCard2',
651
+ 'sampleActionCard3',
652
+ 'sampleActionCard4',
653
+ 'sampleActionCard5',
654
+ ],
655
+ },
656
+ },
657
+ },
658
+ {
659
+ displayName: '按钮3标题',
660
+ name: 'actionTitle3',
661
+ type: 'string',
662
+ default: '',
663
+ required: true,
664
+ displayOptions: {
665
+ show: {
666
+ type: ['companyInternalRobot'],
667
+ enableJsonMode: [false],
668
+ msgKey: ['sampleActionCard3', 'sampleActionCard4', 'sampleActionCard5'],
669
+ },
670
+ },
671
+ },
672
+ {
673
+ displayName: '按钮4标题',
674
+ name: 'actionTitle4',
675
+ type: 'string',
676
+ default: '',
677
+ required: true,
678
+ displayOptions: {
679
+ show: {
680
+ type: ['companyInternalRobot'],
681
+ enableJsonMode: [false],
682
+ msgKey: ['sampleActionCard4', 'sampleActionCard5'],
683
+ },
684
+ },
685
+ },
686
+ {
687
+ displayName: '按钮5标题',
688
+ name: 'actionTitle5',
689
+ type: 'string',
690
+ default: '',
691
+ required: true,
692
+ displayOptions: {
693
+ show: {
694
+ type: ['companyInternalRobot'],
695
+ enableJsonMode: [false],
696
+ msgKey: ['sampleActionCard5'],
697
+ },
698
+ },
699
+ },
700
+ {
701
+ displayName: '按钮1链接',
702
+ name: 'actionURL1',
703
+ type: 'string',
704
+ default: '',
705
+ required: true,
706
+ placeholder: '',
707
+ displayOptions: {
708
+ show: {
709
+ type: ['companyInternalRobot'],
710
+ enableJsonMode: [false],
711
+ msgKey: [
712
+ 'sampleActionCard2',
713
+ 'sampleActionCard3',
714
+ 'sampleActionCard4',
715
+ 'sampleActionCard5',
716
+ ],
717
+ },
718
+ },
719
+ },
720
+ {
721
+ displayName: '按钮2链接',
722
+ name: 'actionURL2',
723
+ type: 'string',
724
+ default: '',
725
+ required: true,
726
+ displayOptions: {
727
+ show: {
728
+ type: ['companyInternalRobot'],
729
+ enableJsonMode: [false],
730
+ msgKey: [
731
+ 'sampleActionCard2',
732
+ 'sampleActionCard3',
733
+ 'sampleActionCard4',
734
+ 'sampleActionCard5',
735
+ ],
736
+ },
737
+ },
738
+ },
739
+ {
740
+ displayName: '按钮3链接',
741
+ name: 'actionURL3',
742
+ type: 'string',
743
+ default: '',
744
+ required: true,
745
+ displayOptions: {
746
+ show: {
747
+ type: ['companyInternalRobot'],
748
+ enableJsonMode: [false],
749
+ msgKey: ['sampleActionCard3', 'sampleActionCard4', 'sampleActionCard5'],
750
+ },
751
+ },
752
+ },
753
+ {
754
+ displayName: '按钮4链接',
755
+ name: 'actionURL4',
756
+ type: 'string',
757
+ default: '',
758
+ required: true,
759
+ displayOptions: {
760
+ show: {
761
+ type: ['companyInternalRobot'],
762
+ enableJsonMode: [false],
763
+ msgKey: ['sampleActionCard4', 'sampleActionCard5'],
764
+ },
765
+ },
766
+ },
767
+ {
768
+ displayName: '按钮5链接',
769
+ name: 'actionURL5',
770
+ type: 'string',
771
+ default: '',
772
+ required: true,
773
+ displayOptions: {
774
+ show: {
775
+ type: ['companyInternalRobot'],
776
+ enableJsonMode: [false],
777
+ msgKey: ['sampleActionCard5'],
778
+ },
779
+ },
780
+ },
781
+ {
782
+ displayName: '横向按钮1标题',
783
+ name: 'buttonTitle1',
784
+ type: 'string',
785
+ default: '',
786
+ required: true,
787
+ displayOptions: {
788
+ show: {
789
+ type: ['companyInternalRobot'],
790
+ enableJsonMode: [false],
791
+ msgKey: ['sampleActionCard6'],
792
+ },
793
+ },
794
+ },
795
+ {
796
+ displayName: '横向按钮2标题',
797
+ name: 'buttonTitle2',
798
+ type: 'string',
799
+ default: '',
800
+ required: true,
801
+ displayOptions: {
802
+ show: {
803
+ type: ['companyInternalRobot'],
804
+ enableJsonMode: [false],
805
+ msgKey: ['sampleActionCard6'],
806
+ },
807
+ },
808
+ },
809
+ {
810
+ displayName: '横向按钮2跳转链接',
811
+ name: 'actionTitle1',
812
+ type: 'string',
813
+ default: '',
814
+ required: true,
815
+ displayOptions: {
816
+ show: {
817
+ type: ['companyInternalRobot'],
818
+ enableJsonMode: [false],
819
+ msgKey: ['sampleActionCard6'],
820
+ },
821
+ },
822
+ },
823
+ {
824
+ displayName: '横向按钮1跳转链接',
825
+ name: 'buttonUrl1',
826
+ type: 'string',
827
+ default: '',
828
+ required: true,
829
+ displayOptions: {
830
+ show: {
831
+ type: ['companyInternalRobot'],
832
+ enableJsonMode: [false],
833
+ msgKey: ['sampleActionCard6'],
834
+ },
835
+ },
836
+ },
837
+ {
838
+ displayName: '按钮集合',
839
+ name: 'btns',
840
+ placeholder: '添加按钮',
841
+ required: true,
842
+ type: 'fixedCollection',
843
+ typeOptions: {
844
+ multipleValues: true,
845
+ },
846
+ displayOptions: {
847
+ show: {
848
+ type: ['customRobot'],
849
+ enableJsonMode: [false],
850
+ msgtype: ['actionCard'],
851
+ isSingleButton: [false],
852
+ },
853
+ },
854
+ default: {},
855
+ options: [
856
+ {
857
+ name: 'buttons',
858
+ displayName: '按钮',
859
+ values: [
860
+ {
861
+ displayName: '按钮标题',
862
+ name: 'title',
863
+ type: 'string',
864
+ default: '',
865
+ description: '按钮的标题',
866
+ },
867
+ {
868
+ displayName: '按钮跳转URL',
869
+ name: 'actionURL',
870
+ type: 'string',
871
+ default: '',
872
+ description: '点击消息跳转的URL',
873
+ },
874
+ ],
875
+ },
876
+ ],
877
+ },
878
+ {
879
+ displayName: '排列方式',
880
+ name: 'btnOrientation',
881
+ type: 'options',
882
+ default: '0',
883
+ options: [
884
+ {
885
+ name: '按钮竖直排列',
886
+ value: '0',
887
+ },
888
+ {
889
+ name: '按钮横向排列',
890
+ value: '1',
891
+ },
892
+ ],
893
+ displayOptions: {
894
+ show: {
895
+ type: ['customRobot'],
896
+ enableJsonMode: [false],
897
+ msgtype: ['actionCard'],
898
+ },
899
+ },
900
+ },
901
+ {
902
+ displayName: '链接集合',
903
+ name: 'lks',
904
+ required: true,
905
+ placeholder: '添加链接',
906
+ type: 'fixedCollection',
907
+ typeOptions: {
908
+ multipleValues: true,
909
+ },
910
+ displayOptions: {
911
+ show: {
912
+ type: ['customRobot'],
913
+ enableJsonMode: [false],
914
+ msgtype: ['feedCard'],
915
+ },
916
+ },
917
+ default: {},
918
+ options: [
919
+ {
920
+ name: 'links',
921
+ displayName: '链接',
922
+ values: [
923
+ {
924
+ displayName: '链接标题',
925
+ name: 'title',
926
+ type: 'string',
927
+ default: '',
928
+ description: '单条信息文本',
929
+ },
930
+ {
931
+ displayName: '链接URL',
932
+ name: 'messageURL',
933
+ type: 'string',
934
+ default: '',
935
+ description: '点击单条信息到跳转链接',
936
+ },
937
+ {
938
+ displayName: '链接图片URL',
939
+ name: 'picURL',
940
+ type: 'string',
941
+ default: '',
942
+ description: '单条信息后面图片的URL',
943
+ },
944
+ ],
945
+ },
946
+ ],
947
+ },
948
+ {
949
+ displayName: '文件名称',
950
+ name: 'fileName',
951
+ type: 'string',
952
+ default: '',
953
+ required: false,
954
+ displayOptions: {
955
+ show: {
956
+ type: ['companyInternalRobot'],
957
+ enableJsonMode: [false],
958
+ msgKey: ['sampleFile'],
959
+ },
960
+ },
961
+ hint: '要在钉钉消息中显示的文件名称。不填写则自动使用上一节点的文件名称。',
962
+ },
963
+ {
964
+ displayName: '文件类型',
965
+ name: 'fileType',
966
+ type: 'string',
967
+ default: '',
968
+ required: false,
969
+ displayOptions: {
970
+ show: {
971
+ type: ['companyInternalRobot'],
972
+ enableJsonMode: [false],
973
+ msgKey: ['sampleFile'],
974
+ },
975
+ },
976
+ hint: '文件类型,支持xlsx、pdf、zip、rar、doc、docx格式。不填写则自动使用上一节点的文件类型。',
977
+ },
978
+ {
979
+ displayName: 'Input Binary Field',
980
+ name: 'binaryPropertyName',
981
+ type: 'string',
982
+ default: 'data',
983
+ required: true,
984
+ displayOptions: {
985
+ show: {
986
+ type: ['companyInternalRobot'],
987
+ enableJsonMode: [false],
988
+ msgKey: ['sampleFile'],
989
+ },
990
+ },
991
+ hint: 'The name of the input binary field containing the file to be uploaded',
992
+ },
993
+ ],
994
+ };
995
+ }
996
+ async execute() {
997
+ var _a, _b, _c, _d;
998
+ const type = this.getNodeParameter('type', 0);
999
+ const items = this.getInputData();
1000
+ if (type === 'customRobot') {
1001
+ const credentials = await this.getCredentials('dingTalkCustomRobotApi');
1002
+ const timestamp = Date.parse(new Date().toString());
1003
+ const stringToSign = `${timestamp}\n${credentials.webhookSign}`;
1004
+ const signBase64 = crypto_1.default
1005
+ .createHmac('sha256', credentials.webhookSign)
1006
+ .update(stringToSign)
1007
+ .digest('base64');
1008
+ const sign = encodeURIComponent(signBase64);
1009
+ const url = credentials.webhookSign
1010
+ ? `${credentials.webhookUrl}&timestamp=${timestamp}&sign=${sign}`
1011
+ : credentials.webhookUrl;
1012
+ const result = [];
1013
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
1014
+ try {
1015
+ const enableJsonMode = this.getNodeParameter('enableJsonMode', itemIndex);
1016
+ const msgtype = enableJsonMode
1017
+ ? null
1018
+ : this.getNodeParameter('msgtype', itemIndex);
1019
+ const data = { msgtype };
1020
+ if (enableJsonMode) {
1021
+ const json = this.getNodeParameter('json', itemIndex);
1022
+ Object.assign(data, json);
1023
+ }
1024
+ else if ('text' === msgtype || 'markdown' === msgtype) {
1025
+ const isAtAll = this.getNodeParameter('isAtAll', itemIndex);
1026
+ const atMobiles = isAtAll
1027
+ ? []
1028
+ : parseMentionList(this.getNodeParameter('atMobiles', itemIndex));
1029
+ const atUserIds = isAtAll
1030
+ ? []
1031
+ : parseMentionList(this.getNodeParameter('atUserIds', itemIndex));
1032
+ const at = { isAtAll };
1033
+ if (atMobiles.length > 0) {
1034
+ at.atMobiles = atMobiles;
1035
+ }
1036
+ if (atUserIds.length > 0) {
1037
+ at.atUserIds = atUserIds;
1038
+ }
1039
+ data.at = at;
1040
+ if ('text' === msgtype) {
1041
+ const content = this.getNodeParameter('content', itemIndex);
1042
+ data.text = {
1043
+ content: appendMentions(content, atMobiles, atUserIds),
1044
+ };
1045
+ }
1046
+ else if ('markdown' === msgtype) {
1047
+ const markdownText = this.getNodeParameter('markdownText', itemIndex);
1048
+ data.markdown = {
1049
+ title: this.getNodeParameter('title', itemIndex),
1050
+ text: appendMentions(markdownText, atMobiles, atUserIds),
1051
+ };
1052
+ }
1053
+ }
1054
+ else if ('link' === msgtype) {
1055
+ data.link = {
1056
+ text: this.getNodeParameter('text', itemIndex),
1057
+ title: this.getNodeParameter('title', itemIndex),
1058
+ picUrl: this.getNodeParameter('picUrl', itemIndex) || '',
1059
+ messageUrl: this.getNodeParameter('url', itemIndex),
1060
+ };
1061
+ }
1062
+ else if ('actionCard' === msgtype) {
1063
+ const actionCard = {
1064
+ title: String(this.getNodeParameter('title', itemIndex)),
1065
+ text: String(this.getNodeParameter('markdownText', itemIndex)),
1066
+ };
1067
+ const btnOrientation = this.getNodeParameter('btnOrientation', itemIndex);
1068
+ if (btnOrientation) {
1069
+ actionCard.btnOrientation = btnOrientation;
1070
+ }
1071
+ const isSingleButton = this.getNodeParameter('isSingleButton', itemIndex);
1072
+ if (isSingleButton) {
1073
+ actionCard.singleTitle = String(this.getNodeParameter('singleTitle', itemIndex));
1074
+ actionCard.singleURL = String(this.getNodeParameter('singleURL', itemIndex));
1075
+ }
1076
+ else {
1077
+ const btns = this.getNodeParameter('btns', itemIndex);
1078
+ actionCard.btns = btns.buttons;
1079
+ }
1080
+ data.actionCard = actionCard;
1081
+ }
1082
+ else if ('feedCard' === msgtype) {
1083
+ const lks = this.getNodeParameter('lks', itemIndex);
1084
+ data.feedCard = {
1085
+ links: lks.links,
1086
+ };
1087
+ }
1088
+ console.log(data);
1089
+ const res = await axios_1.default.post(url, data, {
1090
+ headers: {
1091
+ 'Content-Type': 'application/json',
1092
+ },
1093
+ });
1094
+ result.push({ json: res.data });
1095
+ }
1096
+ catch (error) {
1097
+ if (this.continueOnFail()) {
1098
+ result.push({
1099
+ json: this.getInputData(itemIndex)[0].json,
1100
+ error,
1101
+ pairedItem: itemIndex,
1102
+ });
1103
+ }
1104
+ else {
1105
+ if (error.context) {
1106
+ error.context.itemIndex = itemIndex;
1107
+ throw error;
1108
+ }
1109
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
1110
+ itemIndex,
1111
+ });
1112
+ }
1113
+ }
1114
+ }
1115
+ return this.prepareOutputData(result);
1116
+ }
1117
+ else if (type === 'companyInternalRobot') {
1118
+ const credentials = await this.getCredentials('dingTalkCompanyApi');
1119
+ const config = new $OpenApi.Config({});
1120
+ config.protocol = credentials.protocol;
1121
+ config.regionId = credentials.regionId;
1122
+ const robotClient = new client_1.default(config);
1123
+ const oauth2Client = new client_2.default(config);
1124
+ const getAccessTokenRequest = new $AuthClient.GetAccessTokenRequest({
1125
+ appKey: credentials.accessKeyId,
1126
+ appSecret: credentials.accessKeySecret,
1127
+ });
1128
+ const accessTokenResult = await oauth2Client.getAccessToken(getAccessTokenRequest);
1129
+ const token = (_a = accessTokenResult === null || accessTokenResult === void 0 ? void 0 : accessTokenResult.body) === null || _a === void 0 ? void 0 : _a.accessToken;
1130
+ const batchSendOTOHeaders = new $RobotClient.BatchSendOTOHeaders({});
1131
+ if (!token) {
1132
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'get token fail');
1133
+ }
1134
+ const getUserIdByMobileUrl = 'https://oapi.dingtalk.com/topapi/v2/user/getbymobile?access_token=' + token;
1135
+ const result = [];
1136
+ const robotCode = credentials.robotCode;
1137
+ for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
1138
+ try {
1139
+ const enableJsonMode = this.getNodeParameter('enableJsonMode', itemIndex);
1140
+ const msgKey = enableJsonMode
1141
+ ? null
1142
+ : this.getNodeParameter('msgKey', itemIndex);
1143
+ const msgtype = enableJsonMode
1144
+ ? null
1145
+ : this.getNodeParameter('msgKey', itemIndex);
1146
+ const data = { msgtype };
1147
+ batchSendOTOHeaders.xAcsDingtalkAccessToken = token;
1148
+ if (enableJsonMode) {
1149
+ const json = JSON.parse(this.getNodeParameter('json', itemIndex));
1150
+ Object.assign(data, json);
1151
+ const batchSendOTORequest = new $RobotClient.BatchSendOTORequest(data);
1152
+ await robotClient.batchSendOTOWithOptions(batchSendOTORequest, batchSendOTOHeaders, new $Util.RuntimeOptions({}));
1153
+ }
1154
+ else {
1155
+ const nodeParameters = JSON.parse(JSON.stringify(this.getNode().parameters));
1156
+ const userIds = nodeParameters === null || nodeParameters === void 0 ? void 0 : nodeParameters.userIds;
1157
+ const userIdList = [];
1158
+ const failUser = [];
1159
+ for (let i = 0; i < userIds.users.length; i++) {
1160
+ const user = userIds.users[i];
1161
+ const mobile = user.mobile;
1162
+ const res = await axios_1.default.post(getUserIdByMobileUrl, { mobile }, {
1163
+ headers: {
1164
+ 'Content-Type': 'application/json',
1165
+ },
1166
+ });
1167
+ if (((_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.errcode) !== 0) {
1168
+ failUser.push(mobile);
1169
+ }
1170
+ else {
1171
+ userIdList.push((_d = (_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.result) === null || _d === void 0 ? void 0 : _d.userid);
1172
+ }
1173
+ }
1174
+ if (failUser && failUser.length > 0) {
1175
+ result.push({ json: { failUser } });
1176
+ }
1177
+ if (!userIdList || userIdList.length === 0) {
1178
+ return this.prepareOutputData(result);
1179
+ }
1180
+ delete nodeParameters.type;
1181
+ delete nodeParameters.enableJsonMode;
1182
+ delete nodeParameters.userIds;
1183
+ delete nodeParameters.msgKey;
1184
+ const sendMsgParams = {};
1185
+ for (const nodeParametersKey in nodeParameters) {
1186
+ sendMsgParams[nodeParametersKey] = this.getNodeParameter(nodeParametersKey, itemIndex);
1187
+ }
1188
+ if (msgKey === 'sampleFile') {
1189
+ const binaryPropertyName = sendMsgParams.binaryPropertyName;
1190
+ const binaryData = this.helpers.assertBinaryData(itemIndex, binaryPropertyName);
1191
+ if (!sendMsgParams.fileName) {
1192
+ sendMsgParams.fileName = binaryData.fileName;
1193
+ }
1194
+ if (!sendMsgParams.fileType) {
1195
+ sendMsgParams.fileType = binaryData.fileExtension;
1196
+ }
1197
+ const uploadMediaUrl = 'https://oapi.dingtalk.com/media/upload?access_token=' + token;
1198
+ const formData = new form_data_1.default();
1199
+ let filePath = null;
1200
+ if (binaryData.directory && binaryData.fileName) {
1201
+ filePath = `${binaryData.directory}/${binaryData.fileName}`;
1202
+ }
1203
+ else {
1204
+ const randomName = crypto_1.default.randomBytes(16).toString('hex');
1205
+ filePath = path_1.default.join(os_1.default.tmpdir(), randomName);
1206
+ fs_1.default.writeFileSync(filePath, Buffer.from(binaryData.data, 'base64'));
1207
+ }
1208
+ formData.append('media', fs_1.default.createReadStream(filePath));
1209
+ formData.append('type', 'file');
1210
+ const response = await axios_1.default.post(uploadMediaUrl, formData, {
1211
+ headers: {
1212
+ ...formData.getHeaders(),
1213
+ },
1214
+ });
1215
+ sendMsgParams.mediaId = response.data.media_id;
1216
+ }
1217
+ const sendParams = {
1218
+ robotCode,
1219
+ msgKey,
1220
+ userIds: userIdList,
1221
+ msgParam: JSON.stringify(sendMsgParams).replace(/\\\\/g, '\\'),
1222
+ };
1223
+ const batchSendOTORequest = new $RobotClient.BatchSendOTORequest(sendParams);
1224
+ const sendRes = await robotClient.batchSendOTOWithOptions(batchSendOTORequest, batchSendOTOHeaders, new $Util.RuntimeOptions({}));
1225
+ result.push({ json: sendRes.body });
1226
+ }
1227
+ }
1228
+ catch (error) {
1229
+ if (this.continueOnFail()) {
1230
+ result.push({
1231
+ json: this.getInputData(itemIndex)[0].json,
1232
+ error,
1233
+ pairedItem: itemIndex,
1234
+ });
1235
+ }
1236
+ else {
1237
+ if (error.context) {
1238
+ error.context.itemIndex = itemIndex;
1239
+ throw error;
1240
+ }
1241
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, {
1242
+ itemIndex,
1243
+ });
1244
+ }
1245
+ }
1246
+ return this.prepareOutputData(result);
1247
+ }
1248
+ return this.prepareOutputData([]);
1249
+ }
1250
+ return this.prepareOutputData([]);
1251
+ }
1252
+ }
1253
+ exports.DingTalkRobot = DingTalkRobot;
1254
+ //# sourceMappingURL=DingTalkRobot.node.js.map