@wesell/n8n-nodes-confirmx 0.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -0
  3. package/credentials/ConfirmXApi.credentials.d.ts +18 -0
  4. package/credentials/ConfirmXApi.credentials.js +31 -0
  5. package/credentials/ConfirmXApi.credentials.js.map +1 -0
  6. package/credentials/ConfirmXApi.credentials.ts +40 -0
  7. package/index.d.ts +14 -0
  8. package/index.js +26 -0
  9. package/nodes/ConfirmX/ConfirmXAccount.node.d.ts +5 -0
  10. package/nodes/ConfirmX/ConfirmXAccount.node.js +81 -0
  11. package/nodes/ConfirmX/ConfirmXAccount.node.js.map +1 -0
  12. package/nodes/ConfirmX/ConfirmXAccount.node.ts +81 -0
  13. package/nodes/ConfirmX/ConfirmXConversation.node.d.ts +13 -0
  14. package/nodes/ConfirmX/ConfirmXConversation.node.js +266 -0
  15. package/nodes/ConfirmX/ConfirmXConversation.node.js.map +1 -0
  16. package/nodes/ConfirmX/ConfirmXConversation.node.ts +263 -0
  17. package/nodes/ConfirmX/ConfirmXMessage.node.d.ts +13 -0
  18. package/nodes/ConfirmX/ConfirmXMessage.node.js +364 -0
  19. package/nodes/ConfirmX/ConfirmXMessage.node.js.map +1 -0
  20. package/nodes/ConfirmX/ConfirmXMessage.node.ts +361 -0
  21. package/nodes/ConfirmX/ConfirmXShippingZone.node.d.ts +5 -0
  22. package/nodes/ConfirmX/ConfirmXShippingZone.node.js +100 -0
  23. package/nodes/ConfirmX/ConfirmXShippingZone.node.js.map +1 -0
  24. package/nodes/ConfirmX/ConfirmXShippingZone.node.ts +103 -0
  25. package/nodes/ConfirmX/ConfirmXTemplate.node.d.ts +13 -0
  26. package/nodes/ConfirmX/ConfirmXTemplate.node.js +310 -0
  27. package/nodes/ConfirmX/ConfirmXTemplate.node.js.map +1 -0
  28. package/nodes/ConfirmX/ConfirmXTemplate.node.ts +310 -0
  29. package/nodes/ConfirmX/ConfirmXTrigger.node.d.ts +29 -0
  30. package/nodes/ConfirmX/ConfirmXTrigger.node.js +190 -0
  31. package/nodes/ConfirmX/ConfirmXTrigger.node.js.map +1 -0
  32. package/nodes/ConfirmX/ConfirmXTrigger.node.ts +245 -0
  33. package/nodes/ConfirmX/ConfirmXWebhook.node.d.ts +5 -0
  34. package/nodes/ConfirmX/ConfirmXWebhook.node.js +169 -0
  35. package/nodes/ConfirmX/ConfirmXWebhook.node.js.map +1 -0
  36. package/nodes/ConfirmX/ConfirmXWebhook.node.ts +163 -0
  37. package/nodes/ConfirmX/confirmx.svg +4 -0
  38. package/package.json +69 -0
  39. package/transports/http.d.ts +43 -0
  40. package/transports/http.js +117 -0
  41. package/transports/http.js.map +1 -0
  42. package/transports/http.ts +170 -0
  43. package/transports/signature.d.ts +21 -0
  44. package/transports/signature.js +50 -0
  45. package/transports/signature.js.map +1 -0
  46. package/transports/signature.ts +55 -0
  47. package/types/api.d.ts +199 -0
  48. package/types/api.js +21 -0
  49. package/types/api.js.map +1 -0
  50. package/types/api.ts +238 -0
@@ -0,0 +1,310 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfirmXTemplate = void 0;
4
+ const http_1 = require("../../transports/http");
5
+ class ConfirmXTemplate {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'ConfirmX Template',
9
+ name: 'confirmXTemplate',
10
+ icon: 'file:confirmx.svg',
11
+ group: ['transform'],
12
+ version: 1,
13
+ subtitle: '={{$parameter["operation"]}}',
14
+ description: 'Manage Meta WhatsApp message templates — list, get, create, delete. Templates must be approved by Meta before use.',
15
+ defaults: { name: 'ConfirmX Template' },
16
+ inputs: ['main'],
17
+ outputs: ['main'],
18
+ credentials: [{ name: 'confirmXApi', required: true }],
19
+ properties: [
20
+ {
21
+ displayName: 'Operation',
22
+ name: 'operation',
23
+ type: 'options',
24
+ noDataExpression: true,
25
+ options: [
26
+ {
27
+ name: 'List',
28
+ value: 'list',
29
+ action: 'List templates',
30
+ description: 'List all WhatsApp message templates for an account. Returns every status — APPROVED, PENDING, REJECTED — with full `components[]`. Requires `accountId`. Use when you need to discover which templates exist before sending or auditing.',
31
+ },
32
+ {
33
+ name: 'Get',
34
+ value: 'get',
35
+ action: 'Get template',
36
+ description: 'Fetch a single template by name and language. Returns the live `components[]` and current Meta approval status. Requires `accountId`, `name`, and `language`. Use after a `template.status` webhook to inspect the latest version.',
37
+ },
38
+ {
39
+ name: 'Create',
40
+ value: 'create',
41
+ action: 'Create template',
42
+ description: 'Submit a new template for Meta approval. Returns the new template in PENDING status.',
43
+ },
44
+ {
45
+ name: 'Delete',
46
+ value: 'delete',
47
+ action: 'Delete template',
48
+ description: 'Permanently delete a template.',
49
+ },
50
+ ],
51
+ default: 'list',
52
+ },
53
+ {
54
+ displayName: 'Account',
55
+ name: 'accountId',
56
+ type: 'resourceLocator',
57
+ default: { mode: 'list', value: '' },
58
+ required: true,
59
+ displayOptions: {
60
+ show: { operation: ['list', 'get', 'create', 'delete'] },
61
+ },
62
+ modes: [
63
+ {
64
+ displayName: 'From List',
65
+ name: 'list',
66
+ type: 'list',
67
+ placeholder: 'Select an account…',
68
+ typeOptions: { searchable: true },
69
+ },
70
+ {
71
+ displayName: 'By ID',
72
+ name: 'id',
73
+ type: 'string',
74
+ placeholder: 'acc_…',
75
+ },
76
+ ],
77
+ typeOptions: {
78
+ loadOptionsMethod: 'getAccounts',
79
+ },
80
+ description: 'WhatsApp account to act on',
81
+ },
82
+ // --- Get / Delete ---
83
+ {
84
+ displayName: 'Name',
85
+ name: 'name',
86
+ type: 'string',
87
+ default: '',
88
+ required: true,
89
+ displayOptions: { show: { operation: ['get', 'delete'] } },
90
+ description: 'Template name (lowercase, snake_case)',
91
+ },
92
+ {
93
+ displayName: 'Language',
94
+ name: 'language',
95
+ type: 'string',
96
+ default: 'en',
97
+ required: true,
98
+ displayOptions: { show: { operation: ['get', 'delete'] } },
99
+ description: 'Template language code (e.g. en, ar)',
100
+ },
101
+ // --- List ---
102
+ {
103
+ displayName: 'Return All',
104
+ name: 'returnAll',
105
+ type: 'boolean',
106
+ default: false,
107
+ displayOptions: { show: { operation: ['list'] } },
108
+ },
109
+ {
110
+ displayName: 'Limit',
111
+ name: 'limit',
112
+ type: 'number',
113
+ default: 50,
114
+ typeOptions: { minValue: 1, maxValue: 500 },
115
+ displayOptions: { show: { operation: ['list'], returnAll: [false] } },
116
+ },
117
+ // --- Create ---
118
+ {
119
+ displayName: 'Template Name',
120
+ name: 'createName',
121
+ type: 'string',
122
+ default: '',
123
+ required: true,
124
+ displayOptions: { show: { operation: ['create'] } },
125
+ description: 'Lowercase, snake_case, must match /^[a-z][a-z0-9_]*$/',
126
+ },
127
+ {
128
+ displayName: 'Language',
129
+ name: 'createLanguage',
130
+ type: 'string',
131
+ default: 'en',
132
+ required: true,
133
+ displayOptions: { show: { operation: ['create'] } },
134
+ },
135
+ {
136
+ displayName: 'Category',
137
+ name: 'createCategory',
138
+ type: 'options',
139
+ default: 'UTILITY',
140
+ required: true,
141
+ options: [
142
+ { name: 'Utility', value: 'UTILITY' },
143
+ { name: 'Marketing', value: 'MARKETING' },
144
+ { name: 'Authentication', value: 'AUTHENTICATION' },
145
+ ],
146
+ displayOptions: { show: { operation: ['create'] } },
147
+ },
148
+ {
149
+ displayName: 'Header Type',
150
+ name: 'createHeaderType',
151
+ type: 'options',
152
+ default: 'NONE',
153
+ options: [
154
+ { name: 'None', value: 'NONE' },
155
+ { name: 'Text', value: 'TEXT' },
156
+ { name: 'Image', value: 'IMAGE' },
157
+ { name: 'Video', value: 'VIDEO' },
158
+ { name: 'Document', value: 'DOCUMENT' },
159
+ ],
160
+ displayOptions: { show: { operation: ['create'] } },
161
+ },
162
+ {
163
+ displayName: 'Header Text',
164
+ name: 'createHeaderText',
165
+ type: 'string',
166
+ default: '',
167
+ displayOptions: {
168
+ show: { operation: ['create'], createHeaderType: ['TEXT'] },
169
+ },
170
+ description: 'Required when header type = TEXT. Supports {{1}}, {{2}}, … placeholders.',
171
+ },
172
+ {
173
+ displayName: 'Header Samples',
174
+ name: 'createHeaderSamples',
175
+ type: 'string',
176
+ default: '',
177
+ displayOptions: {
178
+ show: { operation: ['create'], createHeaderType: ['TEXT'] },
179
+ },
180
+ description: 'Comma-separated sample values, e.g. "Acme Inc,ConfirmX"',
181
+ },
182
+ {
183
+ displayName: 'Body Text',
184
+ name: 'createBodyText',
185
+ type: 'string',
186
+ typeOptions: { rows: 4 },
187
+ default: '',
188
+ required: true,
189
+ displayOptions: { show: { operation: ['create'] } },
190
+ description: 'Body text with {{1}}, {{2}}, … placeholders',
191
+ },
192
+ {
193
+ displayName: 'Body Samples',
194
+ name: 'createBodySamples',
195
+ type: 'string',
196
+ default: '',
197
+ displayOptions: { show: { operation: ['create'] } },
198
+ description: 'Comma-separated sample values',
199
+ },
200
+ {
201
+ displayName: 'Footer Text',
202
+ name: 'createFooterText',
203
+ type: 'string',
204
+ default: '',
205
+ displayOptions: { show: { operation: ['create'] } },
206
+ },
207
+ {
208
+ displayName: 'Buttons (JSON)',
209
+ name: 'createButtons',
210
+ type: 'json',
211
+ default: '[]',
212
+ displayOptions: { show: { operation: ['create'] } },
213
+ description: 'JSON array of buttons, each `{type:"QUICK_REPLY"|"URL"|"PHONE_NUMBER", text, url?, phone_number?}`. Example: `[{"type":"URL","text":"Track","url":"https://example.com/track/{{1}}"}]`.',
214
+ },
215
+ ],
216
+ usableAsTool: true,
217
+ };
218
+ this.methods = {
219
+ loadOptions: {
220
+ async getAccounts() {
221
+ return await (0, http_1.loadAccountOptions)(this);
222
+ },
223
+ },
224
+ };
225
+ }
226
+ async execute() {
227
+ const items = this.getInputData();
228
+ const returnData = [];
229
+ const resolveAccountId = (i) => {
230
+ const v = this.getNodeParameter('accountId', i);
231
+ return typeof v === 'string' ? v : v?.value;
232
+ };
233
+ for (let i = 0; i < items.length; i++) {
234
+ const operation = this.getNodeParameter('operation', i);
235
+ const accountId = resolveAccountId(i);
236
+ if (operation === 'list') {
237
+ const returnAll = this.getNodeParameter('returnAll', i);
238
+ const limit = this.getNodeParameter('limit', i) || 50;
239
+ const res = await (0, http_1.confirmxApiRequest)(this, {
240
+ method: 'GET',
241
+ endpoint: '/templates',
242
+ qs: { accountId },
243
+ });
244
+ const sliced = returnAll ? res.templates || [] : (res.templates || []).slice(0, limit);
245
+ returnData.push(...sliced.map((t) => ({ json: t })));
246
+ }
247
+ else if (operation === 'get') {
248
+ const name = this.getNodeParameter('name', i);
249
+ const language = this.getNodeParameter('language', i);
250
+ const res = await (0, http_1.confirmxApiRequest)(this, {
251
+ method: 'GET',
252
+ endpoint: `/templates/${accountId}/${encodeURIComponent(name)}`,
253
+ qs: { language },
254
+ });
255
+ returnData.push({ json: res.template });
256
+ }
257
+ else if (operation === 'create') {
258
+ const body = {
259
+ accountId,
260
+ name: this.getNodeParameter('createName', i),
261
+ language: this.getNodeParameter('createLanguage', i),
262
+ category: this.getNodeParameter('createCategory', i),
263
+ headerType: this.getNodeParameter('createHeaderType', i),
264
+ };
265
+ const headerText = this.getNodeParameter('createHeaderText', i, '');
266
+ const headerSamples = this.getNodeParameter('createHeaderSamples', i, '');
267
+ const bodyText = this.getNodeParameter('createBodyText', i);
268
+ const bodySamples = this.getNodeParameter('createBodySamples', i, '');
269
+ const footerText = this.getNodeParameter('createFooterText', i, '');
270
+ const buttonsRaw = this.getNodeParameter('createButtons', i, '[]');
271
+ if (headerText)
272
+ body.headerText = headerText;
273
+ if (headerSamples)
274
+ body.headerSamples = headerSamples.split(',').map((s) => s.trim()).filter(Boolean);
275
+ body.bodyText = bodyText;
276
+ if (bodySamples)
277
+ body.bodySamples = bodySamples.split(',').map((s) => s.trim()).filter(Boolean);
278
+ if (footerText)
279
+ body.footerText = footerText;
280
+ try {
281
+ const parsed = JSON.parse(buttonsRaw || '[]');
282
+ if (Array.isArray(parsed) && parsed.length)
283
+ body.buttons = parsed;
284
+ }
285
+ catch {
286
+ throw new Error('Buttons must be valid JSON array');
287
+ }
288
+ const res = await (0, http_1.confirmxApiRequest)(this, {
289
+ method: 'POST',
290
+ endpoint: '/templates',
291
+ body,
292
+ });
293
+ returnData.push({ json: res });
294
+ }
295
+ else if (operation === 'delete') {
296
+ const name = this.getNodeParameter('name', i);
297
+ const language = this.getNodeParameter('language', i);
298
+ const res = await (0, http_1.confirmxApiRequest)(this, {
299
+ method: 'DELETE',
300
+ endpoint: `/templates/${accountId}/${encodeURIComponent(name)}`,
301
+ qs: { language },
302
+ });
303
+ returnData.push({ json: { success: true, accountId, name, language, ...res } });
304
+ }
305
+ }
306
+ return [returnData];
307
+ }
308
+ }
309
+ exports.ConfirmXTemplate = ConfirmXTemplate;
310
+ //# sourceMappingURL=ConfirmXTemplate.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmXTemplate.node.js","sourceRoot":"","sources":["ConfirmXTemplate.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,310 @@
1
+ import type { INodeType, INodeTypeDescription } from 'n8n-workflow'
2
+ import { confirmxApiRequest, loadAccountOptions } from '../../transports/http'
3
+
4
+ export class ConfirmXTemplate implements INodeType {
5
+ description: INodeTypeDescription = {
6
+ displayName: 'ConfirmX Template',
7
+ name: 'confirmXTemplate',
8
+ icon: 'file:confirmx.svg',
9
+ group: ['transform'],
10
+ version: 1,
11
+ subtitle: '={{$parameter["operation"]}}',
12
+ description:
13
+ 'Manage Meta WhatsApp message templates — list, get, create, delete. Templates must be approved by Meta before use.',
14
+ defaults: { name: 'ConfirmX Template' },
15
+ inputs: ['main'],
16
+ outputs: ['main'],
17
+ credentials: [{ name: 'confirmXApi', required: true }],
18
+ properties: [
19
+ {
20
+ displayName: 'Operation',
21
+ name: 'operation',
22
+ type: 'options',
23
+ noDataExpression: true,
24
+ options: [
25
+ {
26
+ name: 'List',
27
+ value: 'list',
28
+ action: 'List templates',
29
+ description:
30
+ 'List all WhatsApp message templates for an account. Returns every status — APPROVED, PENDING, REJECTED — with full `components[]`. Requires `accountId`. Use when you need to discover which templates exist before sending or auditing.',
31
+ },
32
+ {
33
+ name: 'Get',
34
+ value: 'get',
35
+ action: 'Get template',
36
+ description:
37
+ 'Fetch a single template by name and language. Returns the live `components[]` and current Meta approval status. Requires `accountId`, `name`, and `language`. Use after a `template.status` webhook to inspect the latest version.',
38
+ },
39
+ {
40
+ name: 'Create',
41
+ value: 'create',
42
+ action: 'Create template',
43
+ description:
44
+ 'Submit a new template for Meta approval. Returns the new template in PENDING status.',
45
+ },
46
+ {
47
+ name: 'Delete',
48
+ value: 'delete',
49
+ action: 'Delete template',
50
+ description: 'Permanently delete a template.',
51
+ },
52
+ ],
53
+ default: 'list',
54
+ },
55
+ {
56
+ displayName: 'Account',
57
+ name: 'accountId',
58
+ type: 'resourceLocator',
59
+ default: { mode: 'list', value: '' },
60
+ required: true,
61
+ displayOptions: {
62
+ show: { operation: ['list', 'get', 'create', 'delete'] },
63
+ },
64
+ modes: [
65
+ {
66
+ displayName: 'From List',
67
+ name: 'list',
68
+ type: 'list',
69
+ placeholder: 'Select an account…',
70
+ typeOptions: { searchable: true },
71
+ },
72
+ {
73
+ displayName: 'By ID',
74
+ name: 'id',
75
+ type: 'string',
76
+ placeholder: 'acc_…',
77
+ },
78
+ ],
79
+ typeOptions: {
80
+ loadOptionsMethod: 'getAccounts',
81
+ },
82
+ description: 'WhatsApp account to act on',
83
+ },
84
+ // --- Get / Delete ---
85
+ {
86
+ displayName: 'Name',
87
+ name: 'name',
88
+ type: 'string',
89
+ default: '',
90
+ required: true,
91
+ displayOptions: { show: { operation: ['get', 'delete'] } },
92
+ description: 'Template name (lowercase, snake_case)',
93
+ },
94
+ {
95
+ displayName: 'Language',
96
+ name: 'language',
97
+ type: 'string',
98
+ default: 'en',
99
+ required: true,
100
+ displayOptions: { show: { operation: ['get', 'delete'] } },
101
+ description: 'Template language code (e.g. en, ar)',
102
+ },
103
+ // --- List ---
104
+ {
105
+ displayName: 'Return All',
106
+ name: 'returnAll',
107
+ type: 'boolean',
108
+ default: false,
109
+ displayOptions: { show: { operation: ['list'] } },
110
+ },
111
+ {
112
+ displayName: 'Limit',
113
+ name: 'limit',
114
+ type: 'number',
115
+ default: 50,
116
+ typeOptions: { minValue: 1, maxValue: 500 },
117
+ displayOptions: { show: { operation: ['list'], returnAll: [false] } },
118
+ },
119
+ // --- Create ---
120
+ {
121
+ displayName: 'Template Name',
122
+ name: 'createName',
123
+ type: 'string',
124
+ default: '',
125
+ required: true,
126
+ displayOptions: { show: { operation: ['create'] } },
127
+ description: 'Lowercase, snake_case, must match /^[a-z][a-z0-9_]*$/',
128
+ },
129
+ {
130
+ displayName: 'Language',
131
+ name: 'createLanguage',
132
+ type: 'string',
133
+ default: 'en',
134
+ required: true,
135
+ displayOptions: { show: { operation: ['create'] } },
136
+ },
137
+ {
138
+ displayName: 'Category',
139
+ name: 'createCategory',
140
+ type: 'options',
141
+ default: 'UTILITY',
142
+ required: true,
143
+ options: [
144
+ { name: 'Utility', value: 'UTILITY' },
145
+ { name: 'Marketing', value: 'MARKETING' },
146
+ { name: 'Authentication', value: 'AUTHENTICATION' },
147
+ ],
148
+ displayOptions: { show: { operation: ['create'] } },
149
+ },
150
+ {
151
+ displayName: 'Header Type',
152
+ name: 'createHeaderType',
153
+ type: 'options',
154
+ default: 'NONE',
155
+ options: [
156
+ { name: 'None', value: 'NONE' },
157
+ { name: 'Text', value: 'TEXT' },
158
+ { name: 'Image', value: 'IMAGE' },
159
+ { name: 'Video', value: 'VIDEO' },
160
+ { name: 'Document', value: 'DOCUMENT' },
161
+ ],
162
+ displayOptions: { show: { operation: ['create'] } },
163
+ },
164
+ {
165
+ displayName: 'Header Text',
166
+ name: 'createHeaderText',
167
+ type: 'string',
168
+ default: '',
169
+ displayOptions: {
170
+ show: { operation: ['create'], createHeaderType: ['TEXT'] },
171
+ },
172
+ description: 'Required when header type = TEXT. Supports {{1}}, {{2}}, … placeholders.',
173
+ },
174
+ {
175
+ displayName: 'Header Samples',
176
+ name: 'createHeaderSamples',
177
+ type: 'string',
178
+ default: '',
179
+ displayOptions: {
180
+ show: { operation: ['create'], createHeaderType: ['TEXT'] },
181
+ },
182
+ description: 'Comma-separated sample values, e.g. "Acme Inc,ConfirmX"',
183
+ },
184
+ {
185
+ displayName: 'Body Text',
186
+ name: 'createBodyText',
187
+ type: 'string',
188
+ typeOptions: { rows: 4 },
189
+ default: '',
190
+ required: true,
191
+ displayOptions: { show: { operation: ['create'] } },
192
+ description: 'Body text with {{1}}, {{2}}, … placeholders',
193
+ },
194
+ {
195
+ displayName: 'Body Samples',
196
+ name: 'createBodySamples',
197
+ type: 'string',
198
+ default: '',
199
+ displayOptions: { show: { operation: ['create'] } },
200
+ description: 'Comma-separated sample values',
201
+ },
202
+ {
203
+ displayName: 'Footer Text',
204
+ name: 'createFooterText',
205
+ type: 'string',
206
+ default: '',
207
+ displayOptions: { show: { operation: ['create'] } },
208
+ },
209
+ {
210
+ displayName: 'Buttons (JSON)',
211
+ name: 'createButtons',
212
+ type: 'json',
213
+ default: '[]',
214
+ displayOptions: { show: { operation: ['create'] } },
215
+ description:
216
+ 'JSON array of buttons, each `{type:"QUICK_REPLY"|"URL"|"PHONE_NUMBER", text, url?, phone_number?}`. Example: `[{"type":"URL","text":"Track","url":"https://example.com/track/{{1}}"}]`.',
217
+ },
218
+ ],
219
+ usableAsTool: true,
220
+ }
221
+
222
+ methods = {
223
+ loadOptions: {
224
+ async getAccounts(this: any) {
225
+ return await loadAccountOptions(this)
226
+ },
227
+ },
228
+ }
229
+
230
+ async execute(this: any) {
231
+ const items = this.getInputData()
232
+ const returnData: any[] = []
233
+ const resolveAccountId = (i: number) => {
234
+ const v = this.getNodeParameter('accountId', i) as any
235
+ return typeof v === 'string' ? v : v?.value
236
+ }
237
+
238
+ for (let i = 0; i < items.length; i++) {
239
+ const operation = this.getNodeParameter('operation', i) as string
240
+ const accountId = resolveAccountId(i)
241
+
242
+ if (operation === 'list') {
243
+ const returnAll = this.getNodeParameter('returnAll', i) as boolean
244
+ const limit = (this.getNodeParameter('limit', i) as number) || 50
245
+ const res = await confirmxApiRequest<{ templates: any[] }>(this, {
246
+ method: 'GET',
247
+ endpoint: '/templates',
248
+ qs: { accountId },
249
+ })
250
+ const sliced = returnAll ? res.templates || [] : (res.templates || []).slice(0, limit)
251
+ returnData.push(...sliced.map((t) => ({ json: t })))
252
+ } else if (operation === 'get') {
253
+ const name = this.getNodeParameter('name', i) as string
254
+ const language = this.getNodeParameter('language', i) as string
255
+ const res = await confirmxApiRequest<{ template: any }>(this, {
256
+ method: 'GET',
257
+ endpoint: `/templates/${accountId}/${encodeURIComponent(name)}`,
258
+ qs: { language },
259
+ })
260
+ returnData.push({ json: res.template })
261
+ } else if (operation === 'create') {
262
+ const body: Record<string, any> = {
263
+ accountId,
264
+ name: this.getNodeParameter('createName', i) as string,
265
+ language: this.getNodeParameter('createLanguage', i) as string,
266
+ category: this.getNodeParameter('createCategory', i) as string,
267
+ headerType: this.getNodeParameter('createHeaderType', i) as string,
268
+ }
269
+ const headerText = this.getNodeParameter('createHeaderText', i, '') as string
270
+ const headerSamples = this.getNodeParameter('createHeaderSamples', i, '') as string
271
+ const bodyText = this.getNodeParameter('createBodyText', i) as string
272
+ const bodySamples = this.getNodeParameter('createBodySamples', i, '') as string
273
+ const footerText = this.getNodeParameter('createFooterText', i, '') as string
274
+ const buttonsRaw = this.getNodeParameter('createButtons', i, '[]') as string
275
+
276
+ if (headerText) body.headerText = headerText
277
+ if (headerSamples)
278
+ body.headerSamples = headerSamples.split(',').map((s) => s.trim()).filter(Boolean)
279
+ body.bodyText = bodyText
280
+ if (bodySamples)
281
+ body.bodySamples = bodySamples.split(',').map((s) => s.trim()).filter(Boolean)
282
+ if (footerText) body.footerText = footerText
283
+ try {
284
+ const parsed = JSON.parse(buttonsRaw || '[]')
285
+ if (Array.isArray(parsed) && parsed.length) body.buttons = parsed
286
+ } catch {
287
+ throw new Error('Buttons must be valid JSON array')
288
+ }
289
+
290
+ const res = await confirmxApiRequest<any>(this, {
291
+ method: 'POST',
292
+ endpoint: '/templates',
293
+ body,
294
+ })
295
+ returnData.push({ json: res })
296
+ } else if (operation === 'delete') {
297
+ const name = this.getNodeParameter('name', i) as string
298
+ const language = this.getNodeParameter('language', i) as string
299
+ const res = await confirmxApiRequest<any>(this, {
300
+ method: 'DELETE',
301
+ endpoint: `/templates/${accountId}/${encodeURIComponent(name)}`,
302
+ qs: { language },
303
+ })
304
+ returnData.push({ json: { success: true, accountId, name, language, ...res } })
305
+ }
306
+ }
307
+
308
+ return [returnData]
309
+ }
310
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * ConfirmX Trigger — starts a flow when ConfirmX emits a webhook event.
3
+ *
4
+ * Self-registration lifecycle:
5
+ * 1. `trigger()` — n8n calls this when the trigger is added/edited or
6
+ * the workflow is saved/activated. We POST /api/v1/webhooks with
7
+ * the n8n-generated URL + the selected events, then persist the
8
+ * returned `secret` in workflow staticData.
9
+ * 2. `webhook()` — n8n calls this for each incoming POST from ConfirmX.
10
+ * We verify the HMAC signature, reject stale timestamps (300s window),
11
+ * and emit the envelope's `data` field as the n8n item.
12
+ * 3. `delete()` / `deactivate()` — best-effort DELETE /api/v1/webhooks/:id.
13
+ *
14
+ * Critical invariant: the `secret` MUST persist client-side because
15
+ * `GET /api/v1/webhooks/:id` does NOT return it. If staticData is wiped
16
+ * (e.g. n8n SQLite volume loss), the trigger throws a clear error
17
+ * and the user must re-add the node to re-register.
18
+ */
19
+ import type { ITriggerFunctions, ITriggerResponse, IWebhookFunctions, INodeType, INodeTypeDescription } from 'n8n-workflow';
20
+ export declare class ConfirmXTrigger implements INodeType {
21
+ description: INodeTypeDescription;
22
+ trigger(this: ITriggerFunctions): Promise<ITriggerResponse>;
23
+ webhook(this: IWebhookFunctions): Promise<{
24
+ workflowData: {
25
+ json: any;
26
+ }[][];
27
+ }>;
28
+ delete(this: ITriggerFunctions): Promise<void>;
29
+ }