n8n-nodes-resend 1.0.3 → 1.0.5

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.
@@ -7,10 +7,10 @@ class Resend {
7
7
  this.description = {
8
8
  displayName: 'Resend',
9
9
  name: 'resend',
10
- icon: 'file:Resend.svg',
10
+ icon: 'file:Resendv2.svg',
11
11
  group: ['output'],
12
12
  version: 1,
13
- description: 'Sends emails via Resend API',
13
+ description: 'Interact with Resend API for emails, domains, API keys, broadcasts, audiences, and contacts',
14
14
  defaults: {
15
15
  name: 'Resend',
16
16
  },
@@ -23,27 +23,87 @@ class Resend {
23
23
  inputs: ['main'],
24
24
  outputs: ['main'],
25
25
  properties: [
26
+ {
27
+ displayName: 'Resource',
28
+ name: 'resource',
29
+ type: 'options',
30
+ noDataExpression: true, options: [
31
+ {
32
+ name: 'API Key',
33
+ value: 'apiKeys',
34
+ description: 'Manage API keys',
35
+ },
36
+ {
37
+ name: 'Audience',
38
+ value: 'audiences',
39
+ description: 'Manage email audiences',
40
+ },
41
+ {
42
+ name: 'Broadcast',
43
+ value: 'broadcasts',
44
+ description: 'Manage email broadcasts',
45
+ },
46
+ {
47
+ name: 'Contact',
48
+ value: 'contacts',
49
+ description: 'Manage audience contacts',
50
+ },
51
+ {
52
+ name: 'Domain',
53
+ value: 'domains',
54
+ description: 'Manage email domains',
55
+ },
56
+ {
57
+ name: 'Email',
58
+ value: 'email',
59
+ description: 'Send and manage emails',
60
+ },
61
+ ],
62
+ default: 'email',
63
+ },
26
64
  {
27
65
  displayName: 'Operation',
28
66
  name: 'operation',
29
67
  type: 'options',
30
68
  noDataExpression: true,
31
- options: [
69
+ displayOptions: {
70
+ show: {
71
+ resource: ['email'],
72
+ },
73
+ }, options: [
74
+ {
75
+ name: 'Cancel',
76
+ value: 'cancel',
77
+ description: 'Cancel a scheduled email',
78
+ action: 'Cancel an email',
79
+ },
32
80
  {
33
- name: 'Send Email',
34
- value: 'sendEmail',
81
+ name: 'Retrieve',
82
+ value: 'retrieve',
83
+ description: 'Retrieve an email by ID',
84
+ action: 'Retrieve an email',
85
+ },
86
+ {
87
+ name: 'Send',
88
+ value: 'send',
89
+ description: 'Send an email',
35
90
  action: 'Send an email',
36
- routing: {
37
- request: {
38
- method: 'POST',
39
- url: 'https://api.resend.com/emails',
40
- },
41
- },
91
+ },
92
+ {
93
+ name: 'Send Batch',
94
+ value: 'sendBatch',
95
+ description: 'Send multiple emails at once',
96
+ action: 'Send batch emails',
97
+ },
98
+ {
99
+ name: 'Update',
100
+ value: 'update',
101
+ description: 'Update an email',
102
+ action: 'Update an email',
42
103
  },
43
104
  ],
44
- default: 'sendEmail',
45
- },
46
- {
105
+ default: 'send',
106
+ }, {
47
107
  displayName: 'Email Format',
48
108
  name: 'emailFormat',
49
109
  type: 'options',
@@ -58,47 +118,45 @@ class Resend {
58
118
  value: 'text',
59
119
  description: 'Send email with plain text content',
60
120
  },
61
- {
62
- name: 'Both',
63
- value: 'both',
64
- description: 'Send email with both HTML and text content',
65
- },
66
121
  ],
67
122
  default: 'html',
68
123
  displayOptions: {
69
124
  show: {
70
- operation: ['sendEmail'],
125
+ resource: ['email'],
126
+ operation: ['send', 'sendBatch'],
71
127
  },
72
128
  },
73
- description: 'Choose the format for your email content. HTML allows rich formatting, text is simple and universally compatible, both provides maximum compatibility.',
129
+ description: 'Choose the format for your email content. HTML allows rich formatting, text is simple and universally compatible.',
74
130
  },
75
131
  {
76
132
  displayName: 'From',
77
- name: 'fromEmail',
133
+ name: 'from',
78
134
  type: 'string',
79
135
  required: true,
80
136
  default: '',
81
137
  placeholder: 'you@example.com',
82
138
  displayOptions: {
83
139
  show: {
84
- operation: ['sendEmail'],
140
+ resource: ['email'],
141
+ operation: ['send'],
85
142
  },
86
143
  },
87
- description: 'Sender email address',
144
+ description: 'Sender email address. To include a friendly name, use the format "Your Name <sender@domain.com>".',
88
145
  },
89
146
  {
90
147
  displayName: 'To',
91
- name: 'toEmail',
148
+ name: 'to',
92
149
  type: 'string',
93
150
  required: true,
94
151
  default: '',
95
152
  placeholder: 'user@example.com',
96
153
  displayOptions: {
97
154
  show: {
98
- operation: ['sendEmail'],
155
+ resource: ['email'],
156
+ operation: ['send'],
99
157
  },
100
158
  },
101
- description: 'Comma-separated list of recipient email addresses',
159
+ description: 'Recipient email address. For multiple addresses, separate with commas (max 50).',
102
160
  },
103
161
  {
104
162
  displayName: 'Subject',
@@ -109,14 +167,15 @@ class Resend {
109
167
  placeholder: 'Hello from n8n!',
110
168
  displayOptions: {
111
169
  show: {
112
- operation: ['sendEmail'],
170
+ resource: ['email'],
171
+ operation: ['send'],
113
172
  },
114
173
  },
174
+ description: 'Email subject line',
115
175
  }, {
116
176
  displayName: 'HTML Content',
117
- name: 'htmlBody',
177
+ name: 'html',
118
178
  type: 'string',
119
- required: true,
120
179
  default: '',
121
180
  typeOptions: {
122
181
  multiline: true,
@@ -124,16 +183,17 @@ class Resend {
124
183
  placeholder: '<p>Your HTML content here</p>',
125
184
  displayOptions: {
126
185
  show: {
127
- operation: ['sendEmail'],
128
- emailFormat: ['html', 'both'],
186
+ resource: ['email'],
187
+ operation: ['send', 'sendBatch'],
188
+ emailFormat: ['html'],
129
189
  },
130
190
  },
131
- description: 'HTML content of the email',
132
- }, {
191
+ description: 'HTML version of the email content',
192
+ },
193
+ {
133
194
  displayName: 'Text Content',
134
- name: 'textBody',
195
+ name: 'text',
135
196
  type: 'string',
136
- required: true,
137
197
  default: '',
138
198
  typeOptions: {
139
199
  multiline: true,
@@ -141,98 +201,628 @@ class Resend {
141
201
  placeholder: 'Your plain text content here',
142
202
  displayOptions: {
143
203
  show: {
144
- operation: ['sendEmail'],
145
- emailFormat: ['text', 'both'],
204
+ resource: ['email'],
205
+ operation: ['send', 'sendBatch'],
206
+ emailFormat: ['text'],
146
207
  },
147
208
  },
148
- description: 'Plain text content of the email',
209
+ description: 'Plain text version of the email content',
149
210
  },
150
211
  {
151
- displayName: 'Options',
152
- name: 'options',
212
+ displayName: 'Additional Options',
213
+ name: 'additionalOptions',
153
214
  type: 'collection',
154
215
  placeholder: 'Add Option',
155
216
  default: {},
156
217
  displayOptions: {
157
218
  show: {
158
- operation: ['sendEmail'],
219
+ resource: ['email'],
220
+ operation: ['send'],
159
221
  },
160
222
  },
161
- description: 'Optional email settings like CC, BCC, Reply-To, and tags', options: [
223
+ options: [
162
224
  {
163
- displayName: 'BCC',
164
- name: 'bccEmail',
225
+ displayName: 'CC',
226
+ name: 'cc',
165
227
  type: 'string',
166
228
  default: '',
167
- placeholder: 'bcc@example.com',
168
- description: 'Comma-separated list of BCC email addresses',
229
+ description: 'CC recipient email addresses (comma-separated)',
169
230
  },
170
231
  {
171
- displayName: 'CC',
172
- name: 'ccEmail',
232
+ displayName: 'BCC',
233
+ name: 'bcc',
173
234
  type: 'string',
174
235
  default: '',
175
- placeholder: 'cc@example.com',
176
- description: 'Comma-separated list of CC email addresses',
236
+ description: 'BCC recipient email addresses (comma-separated)',
177
237
  },
178
238
  {
179
239
  displayName: 'Reply To',
180
- name: 'replyToEmail',
240
+ name: 'reply_to',
181
241
  type: 'string',
182
242
  default: '',
183
- placeholder: 'reply@example.com',
184
- description: 'Email address to set as reply-to',
243
+ description: 'Reply-to email address',
185
244
  },
186
245
  {
187
- displayName: 'Tags',
188
- name: 'tags',
189
- type: 'fixedCollection',
190
- default: {},
191
- placeholder: 'Add Tag',
192
- typeOptions: {
193
- multipleValues: true,
194
- },
195
- options: [
246
+ displayName: 'Scheduled At',
247
+ name: 'scheduled_at',
248
+ type: 'string',
249
+ default: '',
250
+ description: 'Schedule email to be sent later (e.g., "in 1 min" or ISO 8601 format)',
251
+ },
252
+ ],
253
+ },
254
+ {
255
+ displayName: 'Emails',
256
+ name: 'emails',
257
+ type: 'fixedCollection',
258
+ required: true,
259
+ default: { emails: [{}] },
260
+ typeOptions: {
261
+ multipleValues: true,
262
+ },
263
+ displayOptions: {
264
+ show: {
265
+ resource: ['email'],
266
+ operation: ['sendBatch'],
267
+ },
268
+ },
269
+ description: 'Array of emails to send (max 100)', options: [{
270
+ name: 'emails',
271
+ displayName: 'Email',
272
+ values: [
196
273
  {
197
- name: 'tag',
198
- displayName: 'Tag',
199
- values: [
200
- {
201
- displayName: 'Name',
202
- name: 'name',
203
- type: 'string',
204
- default: '',
205
- description: 'Name of the tag',
274
+ displayName: 'From',
275
+ name: 'from',
276
+ type: 'string',
277
+ required: true,
278
+ default: '',
279
+ placeholder: 'you@example.com',
280
+ description: 'Sender email address',
281
+ },
282
+ {
283
+ displayName: 'HTML Content',
284
+ name: 'html',
285
+ type: 'string',
286
+ default: '',
287
+ description: 'HTML content of the email',
288
+ displayOptions: {
289
+ show: {
290
+ '/emailFormat': ['html'],
206
291
  },
207
- {
208
- displayName: 'Value',
209
- name: 'value',
210
- type: 'string',
211
- default: '',
212
- description: 'Value of the tag',
292
+ },
293
+ },
294
+ {
295
+ displayName: 'Subject',
296
+ name: 'subject',
297
+ type: 'string',
298
+ required: true,
299
+ default: '',
300
+ placeholder: 'Hello from n8n!',
301
+ description: 'Email subject',
302
+ },
303
+ {
304
+ displayName: 'Text Content',
305
+ name: 'text',
306
+ type: 'string',
307
+ default: '',
308
+ description: 'Plain text content of the email',
309
+ displayOptions: {
310
+ show: {
311
+ '/emailFormat': ['text'],
213
312
  },
214
- ],
313
+ },
314
+ },
315
+ {
316
+ displayName: 'To',
317
+ name: 'to',
318
+ type: 'string',
319
+ required: true,
320
+ default: '',
321
+ placeholder: 'user@example.com',
322
+ description: 'Recipient email address (comma-separated for multiple)',
215
323
  },
216
324
  ],
217
- description: 'Tags to categorize the email',
218
325
  },
326
+ ],
327
+ },
328
+ {
329
+ displayName: 'Email ID',
330
+ name: 'emailId',
331
+ type: 'string',
332
+ required: true,
333
+ default: '',
334
+ placeholder: 'ae2014de-c168-4c61-8267-70d2662a1ce1',
335
+ displayOptions: {
336
+ show: {
337
+ resource: ['email'],
338
+ operation: ['retrieve', 'update', 'cancel'],
339
+ },
340
+ },
341
+ description: 'The ID of the email to retrieve, update, or cancel',
342
+ },
343
+ {
344
+ displayName: 'Domain Name',
345
+ name: 'domainName',
346
+ type: 'string',
347
+ required: true,
348
+ default: '',
349
+ placeholder: 'example.com',
350
+ displayOptions: {
351
+ show: {
352
+ resource: ['domains'],
353
+ operation: ['create'],
354
+ },
355
+ },
356
+ description: 'The name of the domain you want to create',
357
+ },
358
+ {
359
+ displayName: 'Domain ID',
360
+ name: 'domainId',
361
+ type: 'string',
362
+ required: true,
363
+ default: '',
364
+ placeholder: '4dd369bc-aa82-4ff3-97de-514ae3000ee0',
365
+ displayOptions: {
366
+ show: {
367
+ resource: ['domains'],
368
+ operation: ['get', 'verify', 'update', 'delete'],
369
+ },
370
+ },
371
+ description: 'The ID of the domain',
372
+ },
373
+ {
374
+ displayName: 'Additional Options',
375
+ name: 'additionalOptions',
376
+ type: 'collection',
377
+ placeholder: 'Add Option',
378
+ default: {},
379
+ displayOptions: {
380
+ show: {
381
+ resource: ['domains'],
382
+ operation: ['create'],
383
+ },
384
+ },
385
+ options: [
386
+ {
387
+ displayName: 'Region',
388
+ name: 'region',
389
+ type: 'options',
390
+ options: [
391
+ { name: 'US East 1', value: 'us-east-1' },
392
+ { name: 'EU West 1', value: 'eu-west-1' },
393
+ { name: 'South America East 1', value: 'sa-east-1' },
394
+ { name: 'Asia Pacific Northeast 1', value: 'ap-northeast-1' },
395
+ ],
396
+ default: 'us-east-1',
397
+ description: 'The region where emails will be sent from',
398
+ },
399
+ {
400
+ displayName: 'Custom Return Path',
401
+ name: 'custom_return_path',
402
+ type: 'string',
403
+ default: 'send',
404
+ description: 'Custom subdomain for the Return-Path address',
405
+ },
406
+ ],
407
+ },
408
+ {
409
+ displayName: 'API Key Name',
410
+ name: 'apiKeyName',
411
+ type: 'string',
412
+ typeOptions: { password: true },
413
+ required: true,
414
+ default: '',
415
+ placeholder: 'My API Key',
416
+ displayOptions: {
417
+ show: {
418
+ resource: ['apiKeys'],
419
+ operation: ['create'],
420
+ },
421
+ },
422
+ description: 'The name of the API key to create',
423
+ },
424
+ {
425
+ displayName: 'API Key ID',
426
+ name: 'apiKeyId',
427
+ type: 'string',
428
+ typeOptions: { password: true },
429
+ required: true,
430
+ default: '',
431
+ placeholder: 'key_123456',
432
+ displayOptions: {
433
+ show: {
434
+ resource: ['apiKeys'],
435
+ operation: ['delete'],
436
+ },
437
+ },
438
+ description: 'The ID of the API key to delete',
439
+ },
440
+ {
441
+ displayName: 'Permission',
442
+ name: 'permission',
443
+ type: 'options',
444
+ options: [
445
+ { name: 'Full Access', value: 'full_access' },
446
+ { name: 'Sending Access', value: 'sending_access' },
447
+ ],
448
+ default: 'full_access',
449
+ displayOptions: {
450
+ show: {
451
+ resource: ['apiKeys'],
452
+ operation: ['create'],
453
+ },
454
+ },
455
+ description: 'The permission level for the API key',
456
+ },
457
+ {
458
+ displayName: 'Broadcast Name',
459
+ name: 'broadcastName',
460
+ type: 'string',
461
+ required: true,
462
+ default: '',
463
+ placeholder: 'My Newsletter',
464
+ displayOptions: {
465
+ show: {
466
+ resource: ['broadcasts'],
467
+ operation: ['create'],
468
+ },
469
+ },
470
+ description: 'The name of the broadcast',
471
+ },
472
+ {
473
+ displayName: 'Broadcast ID',
474
+ name: 'broadcastId',
475
+ type: 'string',
476
+ required: true,
477
+ default: '',
478
+ placeholder: 'bc_123456',
479
+ displayOptions: {
480
+ show: {
481
+ resource: ['broadcasts'],
482
+ operation: ['get', 'update', 'send', 'delete'],
483
+ },
484
+ },
485
+ description: 'The ID of the broadcast',
486
+ },
487
+ {
488
+ displayName: 'Audience ID',
489
+ name: 'audienceId',
490
+ type: 'string',
491
+ required: true,
492
+ default: '',
493
+ placeholder: 'aud_123456',
494
+ displayOptions: {
495
+ show: {
496
+ resource: ['broadcasts'],
497
+ operation: ['create'],
498
+ },
499
+ },
500
+ description: 'The ID of the audience for this broadcast',
501
+ },
502
+ {
503
+ displayName: 'Audience Name',
504
+ name: 'audienceName',
505
+ type: 'string',
506
+ required: true,
507
+ default: '',
508
+ placeholder: 'Newsletter Subscribers',
509
+ displayOptions: {
510
+ show: {
511
+ resource: ['audiences'],
512
+ operation: ['create'],
513
+ },
514
+ },
515
+ description: 'The name of the audience',
516
+ },
517
+ {
518
+ displayName: 'Audience ID',
519
+ name: 'audienceId',
520
+ type: 'string',
521
+ required: true,
522
+ default: '',
523
+ placeholder: 'aud_123456',
524
+ displayOptions: {
525
+ show: {
526
+ resource: ['audiences'],
527
+ operation: ['get', 'delete'],
528
+ },
529
+ },
530
+ description: 'The ID of the audience',
531
+ },
532
+ {
533
+ displayName: 'Email',
534
+ name: 'email',
535
+ type: 'string',
536
+ required: true,
537
+ default: '',
538
+ placeholder: 'contact@example.com',
539
+ displayOptions: {
540
+ show: {
541
+ resource: ['contacts'],
542
+ operation: ['create'],
543
+ },
544
+ },
545
+ description: 'The email address of the contact',
546
+ },
547
+ {
548
+ displayName: 'Contact ID',
549
+ name: 'contactId',
550
+ type: 'string',
551
+ required: true,
552
+ default: '',
553
+ placeholder: 'con_123456',
554
+ displayOptions: {
555
+ show: {
556
+ resource: ['contacts'],
557
+ operation: ['get', 'update', 'delete'],
558
+ },
559
+ },
560
+ description: 'The ID of the contact',
561
+ },
562
+ {
563
+ displayName: 'Audience ID',
564
+ name: 'audienceId',
565
+ type: 'string',
566
+ required: true,
567
+ default: '',
568
+ placeholder: 'aud_123456',
569
+ displayOptions: {
570
+ show: {
571
+ resource: ['contacts'],
572
+ operation: ['create', 'list'],
573
+ },
574
+ },
575
+ description: 'The ID of the audience',
576
+ },
577
+ {
578
+ displayName: 'Additional Contact Fields',
579
+ name: 'additionalFields',
580
+ type: 'collection',
581
+ placeholder: 'Add Field',
582
+ default: {},
583
+ displayOptions: {
584
+ show: {
585
+ resource: ['contacts'],
586
+ operation: ['create', 'update'],
587
+ },
588
+ },
589
+ options: [
219
590
  {
220
- displayName: 'Text Content (Fallback)',
221
- name: 'textBodyFallback',
591
+ displayName: 'First Name',
592
+ name: 'first_name',
222
593
  type: 'string',
223
594
  default: '',
224
- typeOptions: {
225
- multiline: true,
226
- },
227
- placeholder: 'Plain text fallback for HTML emails',
228
- displayOptions: {
229
- show: {
230
- '/emailFormat': ['html'],
231
- },
232
- },
233
- description: 'Optional plain text version for HTML emails',
595
+ description: 'First name of the contact',
596
+ },
597
+ {
598
+ displayName: 'Last Name',
599
+ name: 'last_name',
600
+ type: 'string',
601
+ default: '',
602
+ description: 'Last name of the contact',
603
+ },
604
+ {
605
+ displayName: 'Unsubscribed',
606
+ name: 'unsubscribed',
607
+ type: 'boolean',
608
+ default: false,
609
+ description: 'Whether the contact is unsubscribed',
610
+ },
611
+ ],
612
+ },
613
+ {
614
+ displayName: 'Operation',
615
+ name: 'operation',
616
+ type: 'options',
617
+ noDataExpression: true,
618
+ displayOptions: {
619
+ show: {
620
+ resource: ['domains'],
621
+ },
622
+ },
623
+ options: [
624
+ {
625
+ name: 'Create',
626
+ value: 'create',
627
+ description: 'Create a new domain',
628
+ action: 'Create a domain',
629
+ },
630
+ {
631
+ name: 'Delete',
632
+ value: 'delete',
633
+ description: 'Delete a domain',
634
+ action: 'Delete a domain',
635
+ },
636
+ {
637
+ name: 'Get',
638
+ value: 'get',
639
+ description: 'Get a domain by ID',
640
+ action: 'Get a domain',
641
+ },
642
+ {
643
+ name: 'List',
644
+ value: 'list',
645
+ description: 'List all domains',
646
+ action: 'List domains',
647
+ },
648
+ {
649
+ name: 'Update',
650
+ value: 'update',
651
+ description: 'Update a domain',
652
+ action: 'Update a domain',
653
+ },
654
+ {
655
+ name: 'Verify',
656
+ value: 'verify',
657
+ description: 'Verify a domain',
658
+ action: 'Verify a domain',
659
+ },
660
+ ],
661
+ default: 'list',
662
+ },
663
+ {
664
+ displayName: 'Operation',
665
+ name: 'operation',
666
+ type: 'options',
667
+ noDataExpression: true,
668
+ displayOptions: {
669
+ show: {
670
+ resource: ['apiKeys'],
671
+ },
672
+ },
673
+ options: [
674
+ {
675
+ name: 'Create',
676
+ value: 'create',
677
+ description: 'Create a new API key',
678
+ action: 'Create an API key',
679
+ },
680
+ {
681
+ name: 'Delete',
682
+ value: 'delete',
683
+ description: 'Delete an API key',
684
+ action: 'Delete an API key',
685
+ },
686
+ {
687
+ name: 'List',
688
+ value: 'list',
689
+ description: 'List all API keys',
690
+ action: 'List API keys',
691
+ },
692
+ ],
693
+ default: 'list',
694
+ },
695
+ {
696
+ displayName: 'Operation',
697
+ name: 'operation',
698
+ type: 'options',
699
+ noDataExpression: true,
700
+ displayOptions: {
701
+ show: {
702
+ resource: ['broadcasts'],
703
+ },
704
+ },
705
+ options: [
706
+ {
707
+ name: 'Create',
708
+ value: 'create',
709
+ description: 'Create a new broadcast',
710
+ action: 'Create a broadcast',
711
+ },
712
+ {
713
+ name: 'Delete',
714
+ value: 'delete',
715
+ description: 'Delete a broadcast',
716
+ action: 'Delete a broadcast',
717
+ },
718
+ {
719
+ name: 'Get',
720
+ value: 'get',
721
+ description: 'Get a broadcast by ID',
722
+ action: 'Get a broadcast',
723
+ },
724
+ {
725
+ name: 'List',
726
+ value: 'list',
727
+ description: 'List all broadcasts',
728
+ action: 'List broadcasts',
729
+ },
730
+ {
731
+ name: 'Send',
732
+ value: 'send',
733
+ description: 'Send a broadcast',
734
+ action: 'Send a broadcast',
735
+ },
736
+ {
737
+ name: 'Update',
738
+ value: 'update',
739
+ description: 'Update a broadcast',
740
+ action: 'Update a broadcast',
234
741
  },
235
742
  ],
743
+ default: 'list',
744
+ },
745
+ {
746
+ displayName: 'Operation',
747
+ name: 'operation',
748
+ type: 'options',
749
+ noDataExpression: true,
750
+ displayOptions: {
751
+ show: {
752
+ resource: ['audiences'],
753
+ },
754
+ },
755
+ options: [
756
+ {
757
+ name: 'Create',
758
+ value: 'create',
759
+ description: 'Create a new audience',
760
+ action: 'Create an audience',
761
+ },
762
+ {
763
+ name: 'Delete',
764
+ value: 'delete',
765
+ description: 'Delete an audience',
766
+ action: 'Delete an audience',
767
+ },
768
+ {
769
+ name: 'Get',
770
+ value: 'get',
771
+ description: 'Get an audience by ID',
772
+ action: 'Get an audience',
773
+ },
774
+ {
775
+ name: 'List',
776
+ value: 'list',
777
+ description: 'List all audiences',
778
+ action: 'List audiences',
779
+ },
780
+ ],
781
+ default: 'list',
782
+ },
783
+ {
784
+ displayName: 'Operation',
785
+ name: 'operation',
786
+ type: 'options',
787
+ noDataExpression: true,
788
+ displayOptions: {
789
+ show: {
790
+ resource: ['contacts'],
791
+ },
792
+ },
793
+ options: [
794
+ {
795
+ name: 'Create',
796
+ value: 'create',
797
+ description: 'Create a new contact',
798
+ action: 'Create a contact',
799
+ },
800
+ {
801
+ name: 'Delete',
802
+ value: 'delete',
803
+ description: 'Delete a contact',
804
+ action: 'Delete a contact',
805
+ },
806
+ {
807
+ name: 'Get',
808
+ value: 'get',
809
+ description: 'Get a contact by ID',
810
+ action: 'Get a contact',
811
+ },
812
+ {
813
+ name: 'List',
814
+ value: 'list',
815
+ description: 'List contacts in an audience',
816
+ action: 'List contacts',
817
+ },
818
+ {
819
+ name: 'Update',
820
+ value: 'update',
821
+ description: 'Update a contact',
822
+ action: 'Update a contact',
823
+ },
824
+ ],
825
+ default: 'list',
236
826
  },
237
827
  ],
238
828
  };
@@ -243,64 +833,447 @@ class Resend {
243
833
  const length = items.length;
244
834
  for (let i = 0; i < length; i++) {
245
835
  try {
836
+ const resource = this.getNodeParameter('resource', i);
246
837
  const operation = this.getNodeParameter('operation', i);
247
838
  const credentials = await this.getCredentials('resendApi');
248
839
  const apiKey = credentials.apiKey;
249
- if (operation === 'sendEmail') {
250
- const fromEmail = this.getNodeParameter('fromEmail', i);
251
- const toEmail = this.getNodeParameter('toEmail', i);
252
- const subject = this.getNodeParameter('subject', i);
253
- const emailFormat = this.getNodeParameter('emailFormat', i);
254
- const htmlBody = (emailFormat === 'html' || emailFormat === 'both')
255
- ? this.getNodeParameter('htmlBody', i)
256
- : '';
257
- const textBody = (emailFormat === 'text' || emailFormat === 'both')
258
- ? this.getNodeParameter('textBody', i)
259
- : '';
260
- const options = this.getNodeParameter('options', i, {});
261
- const ccEmail = options.ccEmail || '';
262
- const bccEmail = options.bccEmail || '';
263
- const replyToEmail = options.replyToEmail || '';
264
- const textBodyFallback = options.textBodyFallback || '';
265
- const tagsData = options.tags || { tag: [] };
266
- const requestBody = {
267
- from: fromEmail,
268
- to: toEmail.split(',').map((email) => email.trim()).filter((email) => email),
269
- subject: subject,
270
- };
271
- if (emailFormat === 'html' || emailFormat === 'both') {
272
- requestBody.html = htmlBody;
840
+ let response;
841
+ if (resource === 'email') {
842
+ if (operation === 'send') {
843
+ const from = this.getNodeParameter('from', i);
844
+ const to = this.getNodeParameter('to', i);
845
+ const subject = this.getNodeParameter('subject', i);
846
+ const emailFormat = this.getNodeParameter('emailFormat', i);
847
+ const additionalOptions = this.getNodeParameter('additionalOptions', i, {});
848
+ const requestBody = {
849
+ from,
850
+ to: to.split(',').map((email) => email.trim()).filter((email) => email),
851
+ subject,
852
+ };
853
+ if (emailFormat === 'html') {
854
+ const html = this.getNodeParameter('html', i);
855
+ if (html)
856
+ requestBody.html = html;
857
+ }
858
+ else if (emailFormat === 'text') {
859
+ const text = this.getNodeParameter('text', i);
860
+ if (text)
861
+ requestBody.text = text;
862
+ }
863
+ if (additionalOptions.cc) {
864
+ requestBody.cc = additionalOptions.cc.split(',').map((email) => email.trim());
865
+ }
866
+ if (additionalOptions.bcc) {
867
+ requestBody.bcc = additionalOptions.bcc.split(',').map((email) => email.trim());
868
+ }
869
+ if (additionalOptions.reply_to)
870
+ requestBody.reply_to = additionalOptions.reply_to;
871
+ if (additionalOptions.scheduled_at)
872
+ requestBody.scheduled_at = additionalOptions.scheduled_at;
873
+ response = await this.helpers.httpRequest({
874
+ url: 'https://api.resend.com/emails',
875
+ method: 'POST',
876
+ headers: {
877
+ Authorization: `Bearer ${apiKey}`,
878
+ 'Content-Type': 'application/json',
879
+ },
880
+ body: requestBody,
881
+ json: true,
882
+ });
273
883
  }
274
- if (emailFormat === 'text' || emailFormat === 'both') {
275
- requestBody.text = textBody;
884
+ else if (operation === 'sendBatch') {
885
+ const emailsData = this.getNodeParameter('emails', i);
886
+ const emailFormat = this.getNodeParameter('emailFormat', i);
887
+ const emails = emailsData.emails.map((email) => {
888
+ const emailObj = {
889
+ from: email.from,
890
+ to: email.to.split(',').map((e) => e.trim()).filter((e) => e),
891
+ subject: email.subject,
892
+ };
893
+ if (emailFormat === 'html' && email.html) {
894
+ emailObj.html = email.html;
895
+ }
896
+ else if (emailFormat === 'text' && email.text) {
897
+ emailObj.text = email.text;
898
+ }
899
+ return emailObj;
900
+ });
901
+ response = await this.helpers.httpRequest({
902
+ url: 'https://api.resend.com/emails/batch',
903
+ method: 'POST',
904
+ headers: {
905
+ Authorization: `Bearer ${apiKey}`,
906
+ 'Content-Type': 'application/json',
907
+ },
908
+ body: emails,
909
+ json: true,
910
+ });
911
+ }
912
+ else if (operation === 'retrieve') {
913
+ const emailId = this.getNodeParameter('emailId', i);
914
+ response = await this.helpers.httpRequest({
915
+ url: `https://api.resend.com/emails/${emailId}`,
916
+ method: 'GET',
917
+ headers: {
918
+ Authorization: `Bearer ${apiKey}`,
919
+ },
920
+ json: true,
921
+ });
276
922
  }
277
- else if (emailFormat === 'html' && textBodyFallback) {
278
- requestBody.text = textBodyFallback;
923
+ else if (operation === 'update') {
924
+ const emailId = this.getNodeParameter('emailId', i);
925
+ response = await this.helpers.httpRequest({
926
+ url: `https://api.resend.com/emails/${emailId}`,
927
+ method: 'PATCH',
928
+ headers: {
929
+ Authorization: `Bearer ${apiKey}`,
930
+ 'Content-Type': 'application/json',
931
+ },
932
+ body: {},
933
+ json: true,
934
+ });
279
935
  }
280
- if (ccEmail) {
281
- requestBody.cc = ccEmail.split(',').map((email) => email.trim()).filter((email) => email);
936
+ else if (operation === 'cancel') {
937
+ const emailId = this.getNodeParameter('emailId', i);
938
+ response = await this.helpers.httpRequest({
939
+ url: `https://api.resend.com/emails/${emailId}/cancel`,
940
+ method: 'POST',
941
+ headers: {
942
+ Authorization: `Bearer ${apiKey}`,
943
+ 'Content-Type': 'application/json',
944
+ },
945
+ body: {},
946
+ json: true,
947
+ });
282
948
  }
283
- if (bccEmail) {
284
- requestBody.bcc = bccEmail.split(',').map((email) => email.trim()).filter((email) => email);
949
+ }
950
+ else if (resource === 'domains') {
951
+ if (operation === 'create') {
952
+ const domainName = this.getNodeParameter('domainName', i);
953
+ const additionalOptions = this.getNodeParameter('additionalOptions', i, {});
954
+ const requestBody = { name: domainName };
955
+ if (additionalOptions.region)
956
+ requestBody.region = additionalOptions.region;
957
+ if (additionalOptions.custom_return_path)
958
+ requestBody.custom_return_path = additionalOptions.custom_return_path;
959
+ response = await this.helpers.httpRequest({
960
+ url: 'https://api.resend.com/domains',
961
+ method: 'POST',
962
+ headers: {
963
+ Authorization: `Bearer ${apiKey}`,
964
+ 'Content-Type': 'application/json',
965
+ },
966
+ body: requestBody,
967
+ json: true,
968
+ });
285
969
  }
286
- if (replyToEmail) {
287
- requestBody.reply_to = replyToEmail;
970
+ else if (operation === 'get') {
971
+ const domainId = this.getNodeParameter('domainId', i);
972
+ response = await this.helpers.httpRequest({
973
+ url: `https://api.resend.com/domains/${domainId}`,
974
+ method: 'GET',
975
+ headers: {
976
+ Authorization: `Bearer ${apiKey}`,
977
+ },
978
+ json: true,
979
+ });
288
980
  }
289
- if (tagsData.tag && tagsData.tag.length > 0) {
290
- requestBody.tags = tagsData.tag.map((t) => ({ name: t.name, value: t.value }));
981
+ else if (operation === 'verify') {
982
+ const domainId = this.getNodeParameter('domainId', i);
983
+ response = await this.helpers.httpRequest({
984
+ url: `https://api.resend.com/domains/${domainId}/verify`,
985
+ method: 'POST',
986
+ headers: {
987
+ Authorization: `Bearer ${apiKey}`,
988
+ 'Content-Type': 'application/json',
989
+ },
990
+ body: {},
991
+ json: true,
992
+ });
993
+ }
994
+ else if (operation === 'update') {
995
+ const domainId = this.getNodeParameter('domainId', i);
996
+ response = await this.helpers.httpRequest({
997
+ url: `https://api.resend.com/domains/${domainId}`,
998
+ method: 'PATCH',
999
+ headers: {
1000
+ Authorization: `Bearer ${apiKey}`,
1001
+ 'Content-Type': 'application/json',
1002
+ },
1003
+ body: {},
1004
+ json: true,
1005
+ });
1006
+ }
1007
+ else if (operation === 'list') {
1008
+ response = await this.helpers.httpRequest({
1009
+ url: 'https://api.resend.com/domains',
1010
+ method: 'GET',
1011
+ headers: {
1012
+ Authorization: `Bearer ${apiKey}`,
1013
+ },
1014
+ json: true,
1015
+ });
1016
+ }
1017
+ else if (operation === 'delete') {
1018
+ const domainId = this.getNodeParameter('domainId', i);
1019
+ response = await this.helpers.httpRequest({
1020
+ url: `https://api.resend.com/domains/${domainId}`,
1021
+ method: 'DELETE',
1022
+ headers: {
1023
+ Authorization: `Bearer ${apiKey}`,
1024
+ },
1025
+ json: true,
1026
+ });
1027
+ }
1028
+ }
1029
+ else if (resource === 'apiKeys') {
1030
+ if (operation === 'create') {
1031
+ const apiKeyName = this.getNodeParameter('apiKeyName', i);
1032
+ const permission = this.getNodeParameter('permission', i);
1033
+ response = await this.helpers.httpRequest({
1034
+ url: 'https://api.resend.com/api-keys',
1035
+ method: 'POST',
1036
+ headers: {
1037
+ Authorization: `Bearer ${apiKey}`,
1038
+ 'Content-Type': 'application/json',
1039
+ },
1040
+ body: {
1041
+ name: apiKeyName,
1042
+ permission,
1043
+ },
1044
+ json: true,
1045
+ });
1046
+ }
1047
+ else if (operation === 'list') {
1048
+ response = await this.helpers.httpRequest({
1049
+ url: 'https://api.resend.com/api-keys',
1050
+ method: 'GET',
1051
+ headers: {
1052
+ Authorization: `Bearer ${apiKey}`,
1053
+ },
1054
+ json: true,
1055
+ });
1056
+ }
1057
+ else if (operation === 'delete') {
1058
+ const apiKeyId = this.getNodeParameter('apiKeyId', i);
1059
+ response = await this.helpers.httpRequest({
1060
+ url: `https://api.resend.com/api-keys/${apiKeyId}`,
1061
+ method: 'DELETE',
1062
+ headers: {
1063
+ Authorization: `Bearer ${apiKey}`,
1064
+ },
1065
+ json: true,
1066
+ });
1067
+ }
1068
+ }
1069
+ else if (resource === 'broadcasts') {
1070
+ if (operation === 'create') {
1071
+ const broadcastName = this.getNodeParameter('broadcastName', i);
1072
+ const audienceId = this.getNodeParameter('audienceId', i);
1073
+ response = await this.helpers.httpRequest({
1074
+ url: 'https://api.resend.com/broadcasts',
1075
+ method: 'POST',
1076
+ headers: {
1077
+ Authorization: `Bearer ${apiKey}`,
1078
+ 'Content-Type': 'application/json',
1079
+ },
1080
+ body: {
1081
+ name: broadcastName,
1082
+ audience_id: audienceId,
1083
+ },
1084
+ json: true,
1085
+ });
1086
+ }
1087
+ else if (operation === 'get') {
1088
+ const broadcastId = this.getNodeParameter('broadcastId', i);
1089
+ response = await this.helpers.httpRequest({
1090
+ url: `https://api.resend.com/broadcasts/${broadcastId}`,
1091
+ method: 'GET',
1092
+ headers: {
1093
+ Authorization: `Bearer ${apiKey}`,
1094
+ },
1095
+ json: true,
1096
+ });
1097
+ }
1098
+ else if (operation === 'update') {
1099
+ const broadcastId = this.getNodeParameter('broadcastId', i);
1100
+ response = await this.helpers.httpRequest({
1101
+ url: `https://api.resend.com/broadcasts/${broadcastId}`,
1102
+ method: 'PATCH',
1103
+ headers: {
1104
+ Authorization: `Bearer ${apiKey}`,
1105
+ 'Content-Type': 'application/json',
1106
+ },
1107
+ body: {},
1108
+ json: true,
1109
+ });
1110
+ }
1111
+ else if (operation === 'send') {
1112
+ const broadcastId = this.getNodeParameter('broadcastId', i);
1113
+ response = await this.helpers.httpRequest({
1114
+ url: `https://api.resend.com/broadcasts/${broadcastId}/send`,
1115
+ method: 'POST',
1116
+ headers: {
1117
+ Authorization: `Bearer ${apiKey}`,
1118
+ 'Content-Type': 'application/json',
1119
+ },
1120
+ body: {},
1121
+ json: true,
1122
+ });
1123
+ }
1124
+ else if (operation === 'list') {
1125
+ response = await this.helpers.httpRequest({
1126
+ url: 'https://api.resend.com/broadcasts',
1127
+ method: 'GET',
1128
+ headers: {
1129
+ Authorization: `Bearer ${apiKey}`,
1130
+ },
1131
+ json: true,
1132
+ });
1133
+ }
1134
+ else if (operation === 'delete') {
1135
+ const broadcastId = this.getNodeParameter('broadcastId', i);
1136
+ response = await this.helpers.httpRequest({
1137
+ url: `https://api.resend.com/broadcasts/${broadcastId}`,
1138
+ method: 'DELETE',
1139
+ headers: {
1140
+ Authorization: `Bearer ${apiKey}`,
1141
+ },
1142
+ json: true,
1143
+ });
1144
+ }
1145
+ }
1146
+ else if (resource === 'audiences') {
1147
+ if (operation === 'create') {
1148
+ const audienceName = this.getNodeParameter('audienceName', i);
1149
+ response = await this.helpers.httpRequest({
1150
+ url: 'https://api.resend.com/audiences',
1151
+ method: 'POST',
1152
+ headers: {
1153
+ Authorization: `Bearer ${apiKey}`,
1154
+ 'Content-Type': 'application/json',
1155
+ },
1156
+ body: {
1157
+ name: audienceName,
1158
+ },
1159
+ json: true,
1160
+ });
1161
+ }
1162
+ else if (operation === 'get') {
1163
+ const audienceId = this.getNodeParameter('audienceId', i);
1164
+ response = await this.helpers.httpRequest({
1165
+ url: `https://api.resend.com/audiences/${audienceId}`,
1166
+ method: 'GET',
1167
+ headers: {
1168
+ Authorization: `Bearer ${apiKey}`,
1169
+ },
1170
+ json: true,
1171
+ });
1172
+ }
1173
+ else if (operation === 'list') {
1174
+ response = await this.helpers.httpRequest({
1175
+ url: 'https://api.resend.com/audiences',
1176
+ method: 'GET',
1177
+ headers: {
1178
+ Authorization: `Bearer ${apiKey}`,
1179
+ },
1180
+ json: true,
1181
+ });
1182
+ }
1183
+ else if (operation === 'delete') {
1184
+ const audienceId = this.getNodeParameter('audienceId', i);
1185
+ response = await this.helpers.httpRequest({
1186
+ url: `https://api.resend.com/audiences/${audienceId}`,
1187
+ method: 'DELETE',
1188
+ headers: {
1189
+ Authorization: `Bearer ${apiKey}`,
1190
+ },
1191
+ json: true,
1192
+ });
1193
+ }
1194
+ }
1195
+ else if (resource === 'contacts') {
1196
+ if (operation === 'create') {
1197
+ const email = this.getNodeParameter('email', i);
1198
+ const audienceId = this.getNodeParameter('audienceId', i);
1199
+ const additionalFields = this.getNodeParameter('additionalFields', i, {});
1200
+ const requestBody = {
1201
+ email,
1202
+ audience_id: audienceId,
1203
+ };
1204
+ if (additionalFields.first_name)
1205
+ requestBody.first_name = additionalFields.first_name;
1206
+ if (additionalFields.last_name)
1207
+ requestBody.last_name = additionalFields.last_name;
1208
+ if (additionalFields.unsubscribed !== undefined)
1209
+ requestBody.unsubscribed = additionalFields.unsubscribed;
1210
+ response = await this.helpers.httpRequest({
1211
+ url: 'https://api.resend.com/contacts',
1212
+ method: 'POST',
1213
+ headers: {
1214
+ Authorization: `Bearer ${apiKey}`,
1215
+ 'Content-Type': 'application/json',
1216
+ },
1217
+ body: requestBody,
1218
+ json: true,
1219
+ });
1220
+ }
1221
+ else if (operation === 'get') {
1222
+ const contactId = this.getNodeParameter('contactId', i);
1223
+ response = await this.helpers.httpRequest({
1224
+ url: `https://api.resend.com/contacts/${contactId}`,
1225
+ method: 'GET',
1226
+ headers: {
1227
+ Authorization: `Bearer ${apiKey}`,
1228
+ },
1229
+ json: true,
1230
+ });
1231
+ }
1232
+ else if (operation === 'update') {
1233
+ const contactId = this.getNodeParameter('contactId', i);
1234
+ const additionalFields = this.getNodeParameter('additionalFields', i, {});
1235
+ const requestBody = {};
1236
+ if (additionalFields.first_name)
1237
+ requestBody.first_name = additionalFields.first_name;
1238
+ if (additionalFields.last_name)
1239
+ requestBody.last_name = additionalFields.last_name;
1240
+ if (additionalFields.unsubscribed !== undefined)
1241
+ requestBody.unsubscribed = additionalFields.unsubscribed;
1242
+ response = await this.helpers.httpRequest({
1243
+ url: `https://api.resend.com/contacts/${contactId}`,
1244
+ method: 'PATCH',
1245
+ headers: {
1246
+ Authorization: `Bearer ${apiKey}`,
1247
+ 'Content-Type': 'application/json',
1248
+ },
1249
+ body: requestBody,
1250
+ json: true,
1251
+ });
1252
+ }
1253
+ else if (operation === 'list') {
1254
+ const audienceId = this.getNodeParameter('audienceId', i);
1255
+ response = await this.helpers.httpRequest({
1256
+ url: `https://api.resend.com/audiences/${audienceId}/contacts`,
1257
+ method: 'GET',
1258
+ headers: {
1259
+ Authorization: `Bearer ${apiKey}`,
1260
+ },
1261
+ json: true,
1262
+ });
1263
+ }
1264
+ else if (operation === 'delete') {
1265
+ const contactId = this.getNodeParameter('contactId', i);
1266
+ response = await this.helpers.httpRequest({
1267
+ url: `https://api.resend.com/contacts/${contactId}`,
1268
+ method: 'DELETE',
1269
+ headers: {
1270
+ Authorization: `Bearer ${apiKey}`,
1271
+ },
1272
+ json: true,
1273
+ });
291
1274
  }
292
- const response = await this.helpers.httpRequest({
293
- url: 'https://api.resend.com/emails',
294
- method: 'POST',
295
- headers: {
296
- Authorization: `Bearer ${apiKey}`,
297
- 'Content-Type': 'application/json',
298
- },
299
- body: requestBody,
300
- json: true,
301
- });
302
- returnData.push({ json: response, pairedItem: { item: i } });
303
1275
  }
1276
+ returnData.push({ json: response, pairedItem: { item: i } });
304
1277
  }
305
1278
  catch (error) {
306
1279
  if (this.continueOnFail()) {