n8n-nodes-cakemail 1.0.13 → 1.1.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.
@@ -292,10 +292,76 @@ class Cakemail {
292
292
  action: 'Delete campaign',
293
293
  },
294
294
  {
295
- name: 'Send',
296
- value: 'send',
297
- description: 'Send a campaign',
298
- action: 'Send campaign',
295
+ name: 'Schedule',
296
+ value: 'schedule',
297
+ description: 'Schedule a campaign for sending',
298
+ action: 'Schedule campaign',
299
+ },
300
+ {
301
+ name: 'Unschedule',
302
+ value: 'unschedule',
303
+ description: 'Cancel scheduled campaign',
304
+ action: 'Unschedule campaign',
305
+ },
306
+ {
307
+ name: 'Reschedule',
308
+ value: 'reschedule',
309
+ description: 'Reschedule a campaign',
310
+ action: 'Reschedule campaign',
311
+ },
312
+ {
313
+ name: 'Send Test',
314
+ value: 'sendTest',
315
+ description: 'Send test email',
316
+ action: 'Send test email',
317
+ },
318
+ {
319
+ name: 'Archive',
320
+ value: 'archive',
321
+ description: 'Archive a campaign',
322
+ action: 'Archive campaign',
323
+ },
324
+ {
325
+ name: 'Unarchive',
326
+ value: 'unarchive',
327
+ description: 'Unarchive a campaign',
328
+ action: 'Unarchive campaign',
329
+ },
330
+ {
331
+ name: 'Suspend',
332
+ value: 'suspend',
333
+ description: 'Suspend a sending campaign',
334
+ action: 'Suspend campaign',
335
+ },
336
+ {
337
+ name: 'Resume',
338
+ value: 'resume',
339
+ description: 'Resume a suspended campaign',
340
+ action: 'Resume campaign',
341
+ },
342
+ {
343
+ name: 'Cancel',
344
+ value: 'cancel',
345
+ description: 'Cancel a campaign',
346
+ action: 'Cancel campaign',
347
+ },
348
+ {
349
+ name: 'Get Links',
350
+ value: 'getLinks',
351
+ description: 'Get tracked links in campaign',
352
+ action: 'Get campaign links',
353
+ },
354
+ {
355
+ name: 'Render',
356
+ value: 'render',
357
+ description: 'Preview campaign',
358
+ action: 'Render campaign',
359
+ },
360
+ {
361
+ name: 'Get Revisions',
362
+ value: 'getRevisions',
363
+ description: 'Get campaign revision history',
364
+ action: 'Get campaign revisions',
299
365
  },
300
366
  ],
301
367
  default: 'get',
@@ -965,6 +1031,215 @@ class Cakemail {
965
1031
  },
966
1032
  ],
967
1033
  },
1034
+ {
1035
+ displayName: 'Campaign ID',
1036
+ name: 'campaignId',
1037
+ type: 'number',
1038
+ required: true,
1039
+ displayOptions: {
1040
+ show: {
1041
+ resource: ['campaign'],
1042
+ operation: ['get', 'update', 'delete', 'schedule', 'unschedule', 'reschedule', 'sendTest', 'archive', 'unarchive', 'suspend', 'resume', 'cancel', 'getLinks', 'render', 'getRevisions'],
1043
+ },
1044
+ },
1045
+ default: 0,
1046
+ description: 'The ID of the campaign',
1047
+ },
1048
+ {
1049
+ displayName: 'Campaign Name',
1050
+ name: 'campaignName',
1051
+ type: 'string',
1052
+ required: true,
1053
+ displayOptions: {
1054
+ show: {
1055
+ resource: ['campaign'],
1056
+ operation: ['create'],
1057
+ },
1058
+ },
1059
+ default: '',
1060
+ description: 'Name of the campaign',
1061
+ },
1062
+ {
1063
+ displayName: 'Campaign Name',
1064
+ name: 'campaignName',
1065
+ type: 'string',
1066
+ displayOptions: {
1067
+ show: {
1068
+ resource: ['campaign'],
1069
+ operation: ['update'],
1070
+ },
1071
+ },
1072
+ default: '',
1073
+ description: 'New name for the campaign (leave empty to keep current)',
1074
+ },
1075
+ {
1076
+ displayName: 'List ID',
1077
+ name: 'listId',
1078
+ type: 'number',
1079
+ required: true,
1080
+ displayOptions: {
1081
+ show: {
1082
+ resource: ['campaign'],
1083
+ operation: ['create'],
1084
+ },
1085
+ },
1086
+ default: 0,
1087
+ description: 'ID of the list to send the campaign to',
1088
+ },
1089
+ {
1090
+ displayName: 'Sender Name',
1091
+ name: 'senderName',
1092
+ type: 'string',
1093
+ required: true,
1094
+ displayOptions: {
1095
+ show: {
1096
+ resource: ['campaign'],
1097
+ operation: ['create'],
1098
+ },
1099
+ },
1100
+ default: '',
1101
+ description: 'Name of the sender',
1102
+ },
1103
+ {
1104
+ displayName: 'Sender Email',
1105
+ name: 'senderEmail',
1106
+ type: 'string',
1107
+ required: true,
1108
+ displayOptions: {
1109
+ show: {
1110
+ resource: ['campaign'],
1111
+ operation: ['create'],
1112
+ },
1113
+ },
1114
+ default: '',
1115
+ description: 'Email address of the sender',
1116
+ },
1117
+ {
1118
+ displayName: 'Subject',
1119
+ name: 'subject',
1120
+ type: 'string',
1121
+ required: true,
1122
+ displayOptions: {
1123
+ show: {
1124
+ resource: ['campaign'],
1125
+ operation: ['create'],
1126
+ },
1127
+ },
1128
+ default: '',
1129
+ description: 'Email subject line',
1130
+ },
1131
+ {
1132
+ displayName: 'Subject',
1133
+ name: 'subject',
1134
+ type: 'string',
1135
+ displayOptions: {
1136
+ show: {
1137
+ resource: ['campaign'],
1138
+ operation: ['update'],
1139
+ },
1140
+ },
1141
+ default: '',
1142
+ description: 'New subject line (leave empty to keep current)',
1143
+ },
1144
+ {
1145
+ displayName: 'HTML Content',
1146
+ name: 'htmlContent',
1147
+ type: 'string',
1148
+ typeOptions: {
1149
+ rows: 10,
1150
+ },
1151
+ displayOptions: {
1152
+ show: {
1153
+ resource: ['campaign'],
1154
+ operation: ['create', 'update'],
1155
+ },
1156
+ },
1157
+ default: '',
1158
+ description: 'HTML content of the email',
1159
+ },
1160
+ {
1161
+ displayName: 'Text Content',
1162
+ name: 'textContent',
1163
+ type: 'string',
1164
+ typeOptions: {
1165
+ rows: 5,
1166
+ },
1167
+ displayOptions: {
1168
+ show: {
1169
+ resource: ['campaign'],
1170
+ operation: ['create', 'update'],
1171
+ },
1172
+ },
1173
+ default: '',
1174
+ description: 'Plain text content of the email (optional)',
1175
+ },
1176
+ {
1177
+ displayName: 'Preview Text',
1178
+ name: 'previewText',
1179
+ type: 'string',
1180
+ displayOptions: {
1181
+ show: {
1182
+ resource: ['campaign'],
1183
+ operation: ['create'],
1184
+ },
1185
+ },
1186
+ default: '',
1187
+ description: 'Preview text shown in email clients (optional)',
1188
+ },
1189
+ {
1190
+ displayName: 'Scheduled For',
1191
+ name: 'scheduledFor',
1192
+ type: 'string',
1193
+ displayOptions: {
1194
+ show: {
1195
+ resource: ['campaign'],
1196
+ operation: ['schedule', 'reschedule'],
1197
+ },
1198
+ },
1199
+ default: '',
1200
+ description: 'ISO 8601 datetime when to send the campaign (e.g., 2024-12-31T23:59:59Z). Leave empty for immediate scheduling.',
1201
+ },
1202
+ {
1203
+ displayName: 'Test Emails',
1204
+ name: 'testEmails',
1205
+ type: 'string',
1206
+ required: true,
1207
+ displayOptions: {
1208
+ show: {
1209
+ resource: ['campaign'],
1210
+ operation: ['sendTest'],
1211
+ },
1212
+ },
1213
+ default: '',
1214
+ description: 'Comma-separated list of email addresses to send test to',
1215
+ placeholder: 'test1@example.com, test2@example.com',
1216
+ },
1217
+ {
1218
+ displayName: 'Filter',
1219
+ name: 'filter',
1220
+ type: 'string',
1221
+ displayOptions: {
1222
+ show: {
1223
+ resource: ['campaign'],
1224
+ operation: ['list'],
1225
+ },
1226
+ },
1227
+ default: '',
1228
+ description: 'Filter campaigns (e.g., "status==sent;name==Newsletter")',
1229
+ },
1230
+ {
1231
+ displayName: 'Sort',
1232
+ name: 'sort',
1233
+ type: 'string',
1234
+ displayOptions: {
1235
+ show: {
1236
+ resource: ['campaign'],
1237
+ operation: ['list'],
1238
+ },
1239
+ },
1240
+ default: '',
1241
+ description: 'Sort campaigns (e.g., "-created_on" for descending, "+name" for ascending)',
1242
+ },
968
1243
  {
969
1244
  displayName: 'Webhook ID',
970
1245
  name: 'webhookId',
@@ -1374,12 +1649,128 @@ class Cakemail {
1374
1649
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not yet implemented for list resource`, { itemIndex });
1375
1650
  }
1376
1651
  async executeCampaignOperation(client, operation, itemIndex, options) {
1377
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Campaign operations are not yet implemented`, { itemIndex });
1652
+ if (operation === 'list') {
1653
+ const params = {};
1654
+ const filter = this.getNodeParameter('filter', itemIndex, '');
1655
+ const sort = this.getNodeParameter('sort', itemIndex, '');
1656
+ if (filter)
1657
+ params.filter = filter;
1658
+ if (sort)
1659
+ params.sort = sort;
1660
+ return await client.campaigns.list(params, options);
1661
+ }
1662
+ else if (operation === 'get') {
1663
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1664
+ return await client.campaigns.get(campaignId, options);
1665
+ }
1666
+ else if (operation === 'create') {
1667
+ const name = this.getNodeParameter('campaignName', itemIndex);
1668
+ const listId = this.getNodeParameter('listId', itemIndex);
1669
+ const senderName = this.getNodeParameter('senderName', itemIndex);
1670
+ const senderEmail = this.getNodeParameter('senderEmail', itemIndex);
1671
+ const subject = this.getNodeParameter('subject', itemIndex);
1672
+ const htmlContent = this.getNodeParameter('htmlContent', itemIndex, '');
1673
+ const textContent = this.getNodeParameter('textContent', itemIndex, '');
1674
+ const previewText = this.getNodeParameter('previewText', itemIndex, '');
1675
+ return await client.campaigns.create({
1676
+ name,
1677
+ list_ids: [listId],
1678
+ sender_name: senderName,
1679
+ sender_email: senderEmail,
1680
+ subject,
1681
+ preview_text: previewText || undefined,
1682
+ content: {
1683
+ html: htmlContent || undefined,
1684
+ text: textContent || undefined,
1685
+ },
1686
+ }, options);
1687
+ }
1688
+ else if (operation === 'update') {
1689
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1690
+ const updateData = {};
1691
+ const name = this.getNodeParameter('campaignName', itemIndex, '');
1692
+ const subject = this.getNodeParameter('subject', itemIndex, '');
1693
+ const htmlContent = this.getNodeParameter('htmlContent', itemIndex, '');
1694
+ const textContent = this.getNodeParameter('textContent', itemIndex, '');
1695
+ if (name)
1696
+ updateData.name = name;
1697
+ if (subject)
1698
+ updateData.subject = subject;
1699
+ if (htmlContent || textContent) {
1700
+ updateData.content = {
1701
+ html: htmlContent || undefined,
1702
+ text: textContent || undefined,
1703
+ };
1704
+ }
1705
+ return await client.campaigns.update(campaignId, updateData, options);
1706
+ }
1707
+ else if (operation === 'delete') {
1708
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1709
+ await client.campaigns.delete(campaignId, options);
1710
+ return { success: true, id: campaignId };
1711
+ }
1712
+ else if (operation === 'schedule') {
1713
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1714
+ const scheduledFor = this.getNodeParameter('scheduledFor', itemIndex, '');
1715
+ return await client.campaigns.schedule(campaignId, {
1716
+ scheduled_at: scheduledFor || undefined,
1717
+ }, options);
1718
+ }
1719
+ else if (operation === 'unschedule') {
1720
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1721
+ return await client.campaigns.unschedule(campaignId, options);
1722
+ }
1723
+ else if (operation === 'reschedule') {
1724
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1725
+ const scheduledFor = this.getNodeParameter('scheduledFor', itemIndex, '');
1726
+ return await client.campaigns.reschedule(campaignId, {
1727
+ scheduled_at: scheduledFor || new Date().toISOString(),
1728
+ }, options);
1729
+ }
1730
+ else if (operation === 'sendTest') {
1731
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1732
+ const emails = this.getNodeParameter('testEmails', itemIndex);
1733
+ const emailArray = emails.split(',').map(e => e.trim());
1734
+ return await client.campaigns.sendTest(campaignId, emailArray, options);
1735
+ }
1736
+ else if (operation === 'archive') {
1737
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1738
+ return await client.campaigns.archive(campaignId, options);
1739
+ }
1740
+ else if (operation === 'unarchive') {
1741
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1742
+ return await client.campaigns.unarchive(campaignId, options);
1743
+ }
1744
+ else if (operation === 'suspend') {
1745
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1746
+ return await client.campaigns.suspend(campaignId, options);
1747
+ }
1748
+ else if (operation === 'resume') {
1749
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1750
+ return await client.campaigns.resume(campaignId, options);
1751
+ }
1752
+ else if (operation === 'cancel') {
1753
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1754
+ return await client.campaigns.cancel(campaignId, options);
1755
+ }
1756
+ else if (operation === 'getLinks') {
1757
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1758
+ return await client.campaigns.getLinks(campaignId, options);
1759
+ }
1760
+ else if (operation === 'render') {
1761
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1762
+ return await client.campaigns.render(campaignId, options);
1763
+ }
1764
+ else if (operation === 'getRevisions') {
1765
+ const campaignId = this.getNodeParameter('campaignId', itemIndex);
1766
+ return await client.campaigns.getRevisions(campaignId, options);
1767
+ }
1768
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The operation "${operation}" is not supported for campaign resource`, { itemIndex });
1378
1769
  }
1379
1770
  async executeWebhookOperation(client, operation, itemIndex, options) {
1380
1771
  if (operation === 'list') {
1381
1772
  const params = {};
1382
- if (options.accountId) {
1773
+ if (options?.accountId) {
1383
1774
  params.account_id = options.accountId;
1384
1775
  }
1385
1776
  return await client.webhooks.list(params);
@@ -309,10 +309,76 @@ export class Cakemail implements INodeType {
309
309
  action: 'Delete campaign',
310
310
  },
311
311
  {
312
- name: 'Send',
313
- value: 'send',
314
- description: 'Send a campaign',
315
- action: 'Send campaign',
312
+ name: 'Schedule',
313
+ value: 'schedule',
314
+ description: 'Schedule a campaign for sending',
315
+ action: 'Schedule campaign',
316
+ },
317
+ {
318
+ name: 'Unschedule',
319
+ value: 'unschedule',
320
+ description: 'Cancel scheduled campaign',
321
+ action: 'Unschedule campaign',
322
+ },
323
+ {
324
+ name: 'Reschedule',
325
+ value: 'reschedule',
326
+ description: 'Reschedule a campaign',
327
+ action: 'Reschedule campaign',
328
+ },
329
+ {
330
+ name: 'Send Test',
331
+ value: 'sendTest',
332
+ description: 'Send test email',
333
+ action: 'Send test email',
334
+ },
335
+ {
336
+ name: 'Archive',
337
+ value: 'archive',
338
+ description: 'Archive a campaign',
339
+ action: 'Archive campaign',
340
+ },
341
+ {
342
+ name: 'Unarchive',
343
+ value: 'unarchive',
344
+ description: 'Unarchive a campaign',
345
+ action: 'Unarchive campaign',
346
+ },
347
+ {
348
+ name: 'Suspend',
349
+ value: 'suspend',
350
+ description: 'Suspend a sending campaign',
351
+ action: 'Suspend campaign',
352
+ },
353
+ {
354
+ name: 'Resume',
355
+ value: 'resume',
356
+ description: 'Resume a suspended campaign',
357
+ action: 'Resume campaign',
358
+ },
359
+ {
360
+ name: 'Cancel',
361
+ value: 'cancel',
362
+ description: 'Cancel a campaign',
363
+ action: 'Cancel campaign',
364
+ },
365
+ {
366
+ name: 'Get Links',
367
+ value: 'getLinks',
368
+ description: 'Get tracked links in campaign',
369
+ action: 'Get campaign links',
370
+ },
371
+ {
372
+ name: 'Render',
373
+ value: 'render',
374
+ description: 'Preview campaign',
375
+ action: 'Render campaign',
376
+ },
377
+ {
378
+ name: 'Get Revisions',
379
+ value: 'getRevisions',
380
+ description: 'Get campaign revision history',
381
+ action: 'Get campaign revisions',
316
382
  },
317
383
  ],
318
384
  default: 'get',
@@ -1031,6 +1097,237 @@ export class Cakemail implements INodeType {
1031
1097
  ],
1032
1098
  },
1033
1099
 
1100
+ // ================== Campaign Operation Parameters ==================
1101
+
1102
+ // Campaign ID (for get, update, delete, schedule, etc.)
1103
+ {
1104
+ displayName: 'Campaign ID',
1105
+ name: 'campaignId',
1106
+ type: 'number',
1107
+ required: true,
1108
+ displayOptions: {
1109
+ show: {
1110
+ resource: ['campaign'],
1111
+ operation: ['get', 'update', 'delete', 'schedule', 'unschedule', 'reschedule', 'sendTest', 'archive', 'unarchive', 'suspend', 'resume', 'cancel', 'getLinks', 'render', 'getRevisions'],
1112
+ },
1113
+ },
1114
+ default: 0,
1115
+ description: 'The ID of the campaign',
1116
+ },
1117
+
1118
+ // Campaign Name (for create, update)
1119
+ {
1120
+ displayName: 'Campaign Name',
1121
+ name: 'campaignName',
1122
+ type: 'string',
1123
+ required: true,
1124
+ displayOptions: {
1125
+ show: {
1126
+ resource: ['campaign'],
1127
+ operation: ['create'],
1128
+ },
1129
+ },
1130
+ default: '',
1131
+ description: 'Name of the campaign',
1132
+ },
1133
+ {
1134
+ displayName: 'Campaign Name',
1135
+ name: 'campaignName',
1136
+ type: 'string',
1137
+ displayOptions: {
1138
+ show: {
1139
+ resource: ['campaign'],
1140
+ operation: ['update'],
1141
+ },
1142
+ },
1143
+ default: '',
1144
+ description: 'New name for the campaign (leave empty to keep current)',
1145
+ },
1146
+
1147
+ // List ID (for create)
1148
+ {
1149
+ displayName: 'List ID',
1150
+ name: 'listId',
1151
+ type: 'number',
1152
+ required: true,
1153
+ displayOptions: {
1154
+ show: {
1155
+ resource: ['campaign'],
1156
+ operation: ['create'],
1157
+ },
1158
+ },
1159
+ default: 0,
1160
+ description: 'ID of the list to send the campaign to',
1161
+ },
1162
+
1163
+ // Sender information (for create)
1164
+ {
1165
+ displayName: 'Sender Name',
1166
+ name: 'senderName',
1167
+ type: 'string',
1168
+ required: true,
1169
+ displayOptions: {
1170
+ show: {
1171
+ resource: ['campaign'],
1172
+ operation: ['create'],
1173
+ },
1174
+ },
1175
+ default: '',
1176
+ description: 'Name of the sender',
1177
+ },
1178
+ {
1179
+ displayName: 'Sender Email',
1180
+ name: 'senderEmail',
1181
+ type: 'string',
1182
+ required: true,
1183
+ displayOptions: {
1184
+ show: {
1185
+ resource: ['campaign'],
1186
+ operation: ['create'],
1187
+ },
1188
+ },
1189
+ default: '',
1190
+ description: 'Email address of the sender',
1191
+ },
1192
+
1193
+ // Subject (for create, update)
1194
+ {
1195
+ displayName: 'Subject',
1196
+ name: 'subject',
1197
+ type: 'string',
1198
+ required: true,
1199
+ displayOptions: {
1200
+ show: {
1201
+ resource: ['campaign'],
1202
+ operation: ['create'],
1203
+ },
1204
+ },
1205
+ default: '',
1206
+ description: 'Email subject line',
1207
+ },
1208
+ {
1209
+ displayName: 'Subject',
1210
+ name: 'subject',
1211
+ type: 'string',
1212
+ displayOptions: {
1213
+ show: {
1214
+ resource: ['campaign'],
1215
+ operation: ['update'],
1216
+ },
1217
+ },
1218
+ default: '',
1219
+ description: 'New subject line (leave empty to keep current)',
1220
+ },
1221
+
1222
+ // Content (for create, update)
1223
+ {
1224
+ displayName: 'HTML Content',
1225
+ name: 'htmlContent',
1226
+ type: 'string',
1227
+ typeOptions: {
1228
+ rows: 10,
1229
+ },
1230
+ displayOptions: {
1231
+ show: {
1232
+ resource: ['campaign'],
1233
+ operation: ['create', 'update'],
1234
+ },
1235
+ },
1236
+ default: '',
1237
+ description: 'HTML content of the email',
1238
+ },
1239
+ {
1240
+ displayName: 'Text Content',
1241
+ name: 'textContent',
1242
+ type: 'string',
1243
+ typeOptions: {
1244
+ rows: 5,
1245
+ },
1246
+ displayOptions: {
1247
+ show: {
1248
+ resource: ['campaign'],
1249
+ operation: ['create', 'update'],
1250
+ },
1251
+ },
1252
+ default: '',
1253
+ description: 'Plain text content of the email (optional)',
1254
+ },
1255
+ {
1256
+ displayName: 'Preview Text',
1257
+ name: 'previewText',
1258
+ type: 'string',
1259
+ displayOptions: {
1260
+ show: {
1261
+ resource: ['campaign'],
1262
+ operation: ['create'],
1263
+ },
1264
+ },
1265
+ default: '',
1266
+ description: 'Preview text shown in email clients (optional)',
1267
+ },
1268
+
1269
+ // Scheduled For (for schedule, reschedule)
1270
+ {
1271
+ displayName: 'Scheduled For',
1272
+ name: 'scheduledFor',
1273
+ type: 'string',
1274
+ displayOptions: {
1275
+ show: {
1276
+ resource: ['campaign'],
1277
+ operation: ['schedule', 'reschedule'],
1278
+ },
1279
+ },
1280
+ default: '',
1281
+ description: 'ISO 8601 datetime when to send the campaign (e.g., 2024-12-31T23:59:59Z). Leave empty for immediate scheduling.',
1282
+ },
1283
+
1284
+ // Test Emails (for sendTest)
1285
+ {
1286
+ displayName: 'Test Emails',
1287
+ name: 'testEmails',
1288
+ type: 'string',
1289
+ required: true,
1290
+ displayOptions: {
1291
+ show: {
1292
+ resource: ['campaign'],
1293
+ operation: ['sendTest'],
1294
+ },
1295
+ },
1296
+ default: '',
1297
+ description: 'Comma-separated list of email addresses to send test to',
1298
+ placeholder: 'test1@example.com, test2@example.com',
1299
+ },
1300
+
1301
+ // Filter (for list)
1302
+ {
1303
+ displayName: 'Filter',
1304
+ name: 'filter',
1305
+ type: 'string',
1306
+ displayOptions: {
1307
+ show: {
1308
+ resource: ['campaign'],
1309
+ operation: ['list'],
1310
+ },
1311
+ },
1312
+ default: '',
1313
+ description: 'Filter campaigns (e.g., "status==sent;name==Newsletter")',
1314
+ },
1315
+
1316
+ // Sort (for list)
1317
+ {
1318
+ displayName: 'Sort',
1319
+ name: 'sort',
1320
+ type: 'string',
1321
+ displayOptions: {
1322
+ show: {
1323
+ resource: ['campaign'],
1324
+ operation: ['list'],
1325
+ },
1326
+ },
1327
+ default: '',
1328
+ description: 'Sort campaigns (e.g., "-created_on" for descending, "+name" for ascending)',
1329
+ },
1330
+
1034
1331
  // ================== Webhook Operation Parameters ==================
1035
1332
 
1036
1333
  // Webhook ID (for get, update, archive, unarchive)
@@ -1697,9 +1994,117 @@ export class Cakemail implements INodeType {
1697
1994
  itemIndex: number,
1698
1995
  options?: any
1699
1996
  ): Promise<any> {
1997
+ if (operation === 'list') {
1998
+ const params: any = {};
1999
+
2000
+ // Get optional filter parameters
2001
+ const filter = this.getNodeParameter('filter', itemIndex, '') as string;
2002
+ const sort = this.getNodeParameter('sort', itemIndex, '') as string;
2003
+
2004
+ if (filter) params.filter = filter;
2005
+ if (sort) params.sort = sort;
2006
+
2007
+ return await client.campaigns.list(params, options);
2008
+ } else if (operation === 'get') {
2009
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2010
+ return await client.campaigns.get(campaignId, options);
2011
+ } else if (operation === 'create') {
2012
+ const name = this.getNodeParameter('campaignName', itemIndex) as string;
2013
+ const listId = this.getNodeParameter('listId', itemIndex) as number;
2014
+ const senderName = this.getNodeParameter('senderName', itemIndex) as string;
2015
+ const senderEmail = this.getNodeParameter('senderEmail', itemIndex) as string;
2016
+ const subject = this.getNodeParameter('subject', itemIndex) as string;
2017
+ const htmlContent = this.getNodeParameter('htmlContent', itemIndex, '') as string;
2018
+ const textContent = this.getNodeParameter('textContent', itemIndex, '') as string;
2019
+ const previewText = this.getNodeParameter('previewText', itemIndex, '') as string;
2020
+
2021
+ return await client.campaigns.create({
2022
+ name,
2023
+ list_ids: [listId],
2024
+ sender_name: senderName,
2025
+ sender_email: senderEmail,
2026
+ subject,
2027
+ preview_text: previewText || undefined,
2028
+ content: {
2029
+ html: htmlContent || undefined,
2030
+ text: textContent || undefined,
2031
+ },
2032
+ }, options);
2033
+ } else if (operation === 'update') {
2034
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2035
+ const updateData: any = {};
2036
+
2037
+ const name = this.getNodeParameter('campaignName', itemIndex, '') as string;
2038
+ const subject = this.getNodeParameter('subject', itemIndex, '') as string;
2039
+ const htmlContent = this.getNodeParameter('htmlContent', itemIndex, '') as string;
2040
+ const textContent = this.getNodeParameter('textContent', itemIndex, '') as string;
2041
+
2042
+ if (name) updateData.name = name;
2043
+ if (subject) updateData.subject = subject;
2044
+ if (htmlContent || textContent) {
2045
+ updateData.content = {
2046
+ html: htmlContent || undefined,
2047
+ text: textContent || undefined,
2048
+ };
2049
+ }
2050
+
2051
+ return await client.campaigns.update(campaignId, updateData, options);
2052
+ } else if (operation === 'delete') {
2053
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2054
+ await client.campaigns.delete(campaignId, options);
2055
+ return { success: true, id: campaignId };
2056
+ } else if (operation === 'schedule') {
2057
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2058
+ const scheduledFor = this.getNodeParameter('scheduledFor', itemIndex, '') as string;
2059
+
2060
+ return await client.campaigns.schedule(campaignId, {
2061
+ scheduled_at: scheduledFor || undefined,
2062
+ }, options);
2063
+ } else if (operation === 'unschedule') {
2064
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2065
+ return await client.campaigns.unschedule(campaignId, options);
2066
+ } else if (operation === 'reschedule') {
2067
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2068
+ const scheduledFor = this.getNodeParameter('scheduledFor', itemIndex, '') as string;
2069
+
2070
+ return await client.campaigns.reschedule(campaignId, {
2071
+ scheduled_at: scheduledFor || new Date().toISOString(),
2072
+ }, options);
2073
+ } else if (operation === 'sendTest') {
2074
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2075
+ const emails = this.getNodeParameter('testEmails', itemIndex) as string;
2076
+ const emailArray = emails.split(',').map(e => e.trim());
2077
+
2078
+ return await client.campaigns.sendTest(campaignId, emailArray, options);
2079
+ } else if (operation === 'archive') {
2080
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2081
+ return await client.campaigns.archive(campaignId, options);
2082
+ } else if (operation === 'unarchive') {
2083
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2084
+ return await client.campaigns.unarchive(campaignId, options);
2085
+ } else if (operation === 'suspend') {
2086
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2087
+ return await client.campaigns.suspend(campaignId, options);
2088
+ } else if (operation === 'resume') {
2089
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2090
+ return await client.campaigns.resume(campaignId, options);
2091
+ } else if (operation === 'cancel') {
2092
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2093
+ return await client.campaigns.cancel(campaignId, options);
2094
+ } else if (operation === 'getLinks') {
2095
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2096
+ return await client.campaigns.getLinks(campaignId, options);
2097
+ } else if (operation === 'render') {
2098
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2099
+ return await client.campaigns.render(campaignId, options);
2100
+ } else if (operation === 'getRevisions') {
2101
+ const campaignId = this.getNodeParameter('campaignId', itemIndex) as number;
2102
+ return await client.campaigns.getRevisions(campaignId, options);
2103
+ }
2104
+
1700
2105
  throw new NodeOperationError(
1701
2106
  this.getNode(),
1702
- `Campaign operations are not yet implemented`,
2107
+ `The operation "${operation}" is not supported for campaign resource`,
1703
2108
  { itemIndex }
1704
2109
  );
1705
2110
  }
@@ -1717,7 +2122,7 @@ export class Cakemail implements INodeType {
1717
2122
  if (operation === 'list') {
1718
2123
  const params: any = {};
1719
2124
 
1720
- if (options.accountId) {
2125
+ if (options?.accountId) {
1721
2126
  params.account_id = options.accountId;
1722
2127
  }
1723
2128
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-cakemail",
3
- "version": "1.0.13",
3
+ "version": "1.1.0",
4
4
  "description": "n8n node for Cakemail - workflow-native email platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",