n8n-nodes-postmark-smtp 0.1.1 → 0.1.3

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
@@ -13,15 +13,14 @@ This is an n8n community node. It lets you use Postmark to send transactional em
13
13
  - Attachments (binary data).
14
14
  - CC and BCC recipients.
15
15
  - Dynamic sender verification (loads verified domains from your account).
16
- - **Batch Send Email**: Send multiple emails in a single API request for better performance.
17
- - **Send Email with Template**: Use Postmark's template feature to send emails by providing a Template ID and a Model (JSON).
16
+ - **Send Email with Template**: Use Postmark's template feature to send emails with full sender/recipient control.
18
17
 
19
18
  ## Credentials
20
19
 
21
- This node requires two types of credentials:
20
+ This node requires a **Postmark API** credential which includes:
22
21
 
23
- 1. **Postmark Server Token**: Required for sending emails. You can find this in your Postmark server settings under "API Tokens".
24
- 2. **Postmark Account Token**: Required *only* if you want to use the "From (Domain)" dropdown to fetch verified domains. You can find this in your Postmark account settings.
22
+ 1. **Server Token**: Required for sending emails. You can find this in your Postmark server settings under "API Tokens".
23
+ 2. **Account Token**: Required *only* if you want to fetch verified domains dynamically. You can find this in your Postmark account settings.
25
24
 
26
25
  ## Installation
27
26
 
@@ -37,25 +36,31 @@ docker exec -it n8n npm install n8n-nodes-postmark-smtp
37
36
 
38
37
  ## Usage
39
38
 
40
- ### sending an Email
39
+ ### Sending an Email
41
40
  1. Select the **Send Email** operation.
42
- 2. Connect your **Postmark Server Token**.
43
- 3. (Optional) Connect your **Postmark Account Token** to auto-populate the *From (Domain)* field.
44
- 4. Enter the *From (Local Part)* (e.g., `info` for `info@example.com`).
45
- 5. Select a valid *From (Domain)*.
46
- 6. Enter the recipient(s) in *To*.
47
- 7. Fill in *Subject*, *HTML Body*, and *Text Body*.
41
+ 2. Connect your **Postmark API** credential (fill in Server Token and optionally Account Token).
42
+ 3. Select a valid **From Domain** (dynamically loaded).
43
+ 4. (Optional) Enter **From Name**.
44
+ 5. Enter **From Email**. *Note: This must belong to the selected 'From Domain' or the node will error.*
45
+ 6. (Optional) Enter **To Name**.
46
+ 7. Enter **To Email**.
47
+ 8. Fill in *Subject*, *HTML Body*, and *Text Body*.
48
48
 
49
49
  ### Sending with Templates
50
50
  1. Select the **Send Email with Template** operation.
51
- 2. Enter the **Template ID** (found in Postmark UI).
52
- 3. Provide the **Template Model** as a JSON object matching your template variables.
51
+ 2. Connect your **Postmark API** credential.
52
+ 3. Select a valid **From Domain**.
53
+ 4. Enter **From Name** and **From Email**.
54
+ 5. Enter **To Name** and **To Email**.
55
+ 6. Enter the **Template ID** (found in Postmark UI).
56
+ 7. Provide the **Template Model** as a JSON object matching your template variables.
53
57
  ```json
54
58
  {
55
59
  "user_name": "John Doe",
56
60
  "action_url": "https://example.com/login"
57
61
  }
58
62
  ```
63
+ 8. (Optional) Add **Attachments**.
59
64
 
60
65
  ## Development
61
66
 
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostmarkApi = void 0;
4
+ class PostmarkApi {
5
+ constructor() {
6
+ this.name = 'postmarkApi';
7
+ this.displayName = 'Postmark API';
8
+ this.documentationUrl = 'https://postmarkapp.com/developer';
9
+ this.properties = [
10
+ {
11
+ displayName: 'Server Token',
12
+ name: 'serverToken',
13
+ type: 'string',
14
+ default: '',
15
+ typeOptions: {
16
+ password: true,
17
+ },
18
+ description: 'The "Server API Token" found in your server settings.',
19
+ },
20
+ {
21
+ displayName: 'Account Token',
22
+ name: 'accountToken',
23
+ type: 'string',
24
+ default: '',
25
+ typeOptions: {
26
+ password: true,
27
+ },
28
+ description: 'The "Account API Token" found in your account settings. Required fopr fetching verified domains.',
29
+ },
30
+ ];
31
+ }
32
+ }
33
+ exports.PostmarkApi = PostmarkApi;
@@ -18,11 +18,7 @@ class PostmarkSmtp {
18
18
  outputs: ['main'],
19
19
  credentials: [
20
20
  {
21
- name: 'postmarkServerToken',
22
- required: true,
23
- },
24
- {
25
- name: 'postmarkAccountToken',
21
+ name: 'postmarkApi',
26
22
  required: true,
27
23
  },
28
24
  ],
@@ -56,11 +52,6 @@ class PostmarkSmtp {
56
52
  value: 'sendEmail',
57
53
  action: 'Send an email',
58
54
  },
59
- {
60
- name: 'Batch Send Email',
61
- value: 'batchSendEmail',
62
- action: 'Send multiple emails in a batch',
63
- },
64
55
  {
65
56
  name: 'Send Email with Template',
66
57
  value: 'sendEmailWithTemplate',
@@ -69,44 +60,67 @@ class PostmarkSmtp {
69
60
  ],
70
61
  default: 'sendEmail',
71
62
  },
72
- // ----------------------------------
73
- // sendEmail
74
- // ----------------------------------
75
63
  {
76
- displayName: 'From (Local Part)',
77
- name: 'fromLocalPart',
64
+ displayName: 'From Domain',
65
+ name: 'fromDomain',
66
+ type: 'options',
67
+ required: true,
68
+ typeOptions: {
69
+ loadOptionsMethod: 'getDomains',
70
+ },
71
+ default: '',
72
+ displayOptions: {
73
+ show: {
74
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
75
+ resource: ['email'],
76
+ },
77
+ },
78
+ description: 'Choose a verified domain',
79
+ },
80
+ {
81
+ displayName: 'From Name',
82
+ name: 'fromName',
78
83
  type: 'string',
79
84
  default: '',
80
- placeholder: 'sender',
81
- required: true,
85
+ placeholder: 'Sender Name',
82
86
  displayOptions: {
83
87
  show: {
84
- operation: ['sendEmail', 'batchSendEmail'],
88
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
85
89
  resource: ['email'],
86
90
  },
87
91
  },
88
- description: 'The local part of the sender email address (before @)',
89
92
  },
90
93
  {
91
- displayName: 'From (Domain)',
92
- name: 'fromDomain',
93
- type: 'options',
94
+ displayName: 'From Email',
95
+ name: 'fromEmail',
96
+ type: 'string',
97
+ default: '',
98
+ placeholder: 'sender@example.com',
94
99
  required: true,
95
- typeOptions: {
96
- loadOptionsMethod: 'getDomains',
100
+ displayOptions: {
101
+ show: {
102
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
103
+ resource: ['email'],
104
+ },
97
105
  },
106
+ description: 'The sender email address. Must be from the selected domain.',
107
+ },
108
+ {
109
+ displayName: 'To Name',
110
+ name: 'toName',
111
+ type: 'string',
98
112
  default: '',
113
+ placeholder: 'Recipient Name',
99
114
  displayOptions: {
100
115
  show: {
101
- operation: ['sendEmail', 'batchSendEmail'],
116
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
102
117
  resource: ['email'],
103
118
  },
104
119
  },
105
- description: 'Choose a verified domain',
106
120
  },
107
121
  {
108
- displayName: 'To',
109
- name: 'to',
122
+ displayName: 'To Email',
123
+ name: 'toEmail',
110
124
  type: 'string',
111
125
  default: '',
112
126
  placeholder: 'receiver@example.com',
@@ -169,7 +183,7 @@ class PostmarkSmtp {
169
183
  default: false,
170
184
  displayOptions: {
171
185
  show: {
172
- operation: ['sendEmail'],
186
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
173
187
  resource: ['email'],
174
188
  },
175
189
  },
@@ -184,7 +198,7 @@ class PostmarkSmtp {
184
198
  displayOptions: {
185
199
  show: {
186
200
  attachmentsToggle: [true],
187
- operation: ['sendEmail'],
201
+ operation: ['sendEmail', 'sendEmailWithTemplate'],
188
202
  resource: ['email'],
189
203
  },
190
204
  },
@@ -267,43 +281,12 @@ class PostmarkSmtp {
267
281
  },
268
282
  description: 'JSON object containing the template model values',
269
283
  },
270
- {
271
- displayName: 'From',
272
- name: 'from',
273
- type: 'string',
274
- default: '',
275
- required: true,
276
- displayOptions: {
277
- show: {
278
- operation: ['sendEmailWithTemplate'],
279
- resource: ['email'],
280
- },
281
- },
282
- description: 'The sender email address',
283
- },
284
- // ----------------------------------
285
- // batchSendEmail
286
- // ----------------------------------
287
- {
288
- displayName: 'Batch Input (JSON)',
289
- name: 'batchInput',
290
- type: 'json',
291
- default: '[]',
292
- required: true,
293
- displayOptions: {
294
- show: {
295
- operation: ['batchSendEmail'],
296
- resource: ['email'],
297
- },
298
- },
299
- description: 'Array of email objects to send in batch',
300
- },
301
284
  ],
302
285
  };
303
286
  this.methods = {
304
287
  loadOptions: {
305
288
  async getDomains() {
306
- const credentials = await this.getCredentials('postmarkAccountToken');
289
+ const credentials = await this.getCredentials('postmarkApi');
307
290
  const token = credentials.accountToken;
308
291
  const options = {
309
292
  method: 'GET',
@@ -328,16 +311,36 @@ class PostmarkSmtp {
328
311
  const items = this.getInputData();
329
312
  const returnData = [];
330
313
  const operation = this.getNodeParameter('operation', 0);
331
- const credentials = await this.getCredentials('postmarkServerToken');
314
+ const credentials = await this.getCredentials('postmarkApi');
332
315
  const serverToken = credentials.serverToken;
333
316
  for (let i = 0; i < items.length; i++) {
334
317
  try {
335
318
  let responseData;
336
319
  if (operation === 'sendEmail') {
337
- const fromLocalPart = this.getNodeParameter('fromLocalPart', i);
338
320
  const fromDomain = this.getNodeParameter('fromDomain', i);
339
- const from = `${fromLocalPart}@${fromDomain}`;
340
- const to = this.getNodeParameter('to', i);
321
+ const fromName = this.getNodeParameter('fromName', i);
322
+ const fromEmail = this.getNodeParameter('fromEmail', i);
323
+ if (!fromEmail.toLowerCase().endsWith('@' + fromDomain.toLowerCase())) {
324
+ if (this.continueOnFail()) {
325
+ returnData.push({
326
+ json: {
327
+ error: `From Email (${fromEmail}) must belong to the selected domain (${fromDomain})`,
328
+ },
329
+ });
330
+ continue;
331
+ }
332
+ throw new Error(`From Email (${fromEmail}) must belong to the selected domain (${fromDomain})`);
333
+ }
334
+ let from = fromEmail;
335
+ if (fromName) {
336
+ from = `"${fromName}" <${fromEmail}>`;
337
+ }
338
+ const toName = this.getNodeParameter('toName', i);
339
+ const toEmail = this.getNodeParameter('toEmail', i);
340
+ let to = toEmail;
341
+ if (toName) {
342
+ to = `"${toName}" <${toEmail}>`;
343
+ }
341
344
  const subject = this.getNodeParameter('subject', i);
342
345
  const htmlBody = this.getNodeParameter('htmlBody', i);
343
346
  const textBody = this.getNodeParameter('textBody', i);
@@ -387,8 +390,30 @@ class PostmarkSmtp {
387
390
  responseData = await this.helpers.request(options);
388
391
  }
389
392
  else if (operation === 'sendEmailWithTemplate') {
390
- const from = this.getNodeParameter('from', i);
391
- const to = this.getNodeParameter('to', i);
393
+ const fromDomain = this.getNodeParameter('fromDomain', i);
394
+ const fromName = this.getNodeParameter('fromName', i);
395
+ const fromEmail = this.getNodeParameter('fromEmail', i);
396
+ if (!fromEmail.toLowerCase().endsWith('@' + fromDomain.toLowerCase())) {
397
+ if (this.continueOnFail()) {
398
+ returnData.push({
399
+ json: {
400
+ error: `From Email (${fromEmail}) must belong to the selected domain (${fromDomain})`,
401
+ },
402
+ });
403
+ continue;
404
+ }
405
+ throw new Error(`From Email (${fromEmail}) must belong to the selected domain (${fromDomain})`);
406
+ }
407
+ let from = fromEmail;
408
+ if (fromName) {
409
+ from = `"${fromName}" <${fromEmail}>`;
410
+ }
411
+ const toName = this.getNodeParameter('toName', i);
412
+ const toEmail = this.getNodeParameter('toEmail', i);
413
+ let to = toEmail;
414
+ if (toName) {
415
+ to = `"${toName}" <${toEmail}>`;
416
+ }
392
417
  const templateId = this.getNodeParameter('templateId', i);
393
418
  const templateModel = this.getNodeParameter('templateModel', i);
394
419
  const cc = this.getNodeParameter('cc', i);
@@ -402,6 +427,27 @@ class PostmarkSmtp {
402
427
  Bcc: bcc,
403
428
  MessageStream: 'outbound',
404
429
  };
430
+ // Handle Attachments
431
+ const attachmentsToggle = this.getNodeParameter('attachmentsToggle', i);
432
+ if (attachmentsToggle) {
433
+ const attachmentsConfig = this.getNodeParameter('attachments', i);
434
+ const attachments = [];
435
+ if (attachmentsConfig && attachmentsConfig.attachment) {
436
+ for (const att of attachmentsConfig.attachment) {
437
+ const propertyName = att.propertyName;
438
+ const binaryData = this.helpers.assertBinaryData(i, propertyName);
439
+ const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, propertyName);
440
+ attachments.push({
441
+ Name: att.fileName || binaryData.fileName || 'attachment',
442
+ Content: binaryDataBuffer.toString('base64'),
443
+ ContentType: binaryData.mimeType,
444
+ });
445
+ }
446
+ }
447
+ if (attachments.length > 0) {
448
+ body.Attachments = attachments;
449
+ }
450
+ }
405
451
  const options = {
406
452
  method: 'POST',
407
453
  uri: 'https://api.postmarkapp.com/email/withTemplate',
@@ -414,20 +460,6 @@ class PostmarkSmtp {
414
460
  };
415
461
  responseData = await this.helpers.request(options);
416
462
  }
417
- else if (operation === 'batchSendEmail') {
418
- const batchInput = this.getNodeParameter('batchInput', i);
419
- const options = {
420
- method: 'POST',
421
- uri: 'https://api.postmarkapp.com/email/batch',
422
- headers: {
423
- 'X-Postmark-Server-Token': serverToken,
424
- 'Accept': 'application/json',
425
- },
426
- body: batchInput,
427
- json: true,
428
- };
429
- responseData = await this.helpers.request(options);
430
- }
431
463
  returnData.push({
432
464
  json: responseData,
433
465
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-postmark-smtp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Postmark SMTP node for n8n",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"
@@ -32,8 +32,7 @@
32
32
  "dist/nodes/PostmarkSmtp/PostmarkSmtp.node.js"
33
33
  ],
34
34
  "credentials": [
35
- "dist/credentials/PostmarkServerToken.credentials.js",
36
- "dist/credentials/PostmarkAccountToken.credentials.js"
35
+ "dist/credentials/PostmarkApi.credentials.js"
37
36
  ]
38
37
  },
39
38
  "devDependencies": {