@connectorx/n8n-nodes-cortex 0.1.21 → 0.1.23

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.
@@ -210,10 +210,66 @@ class Cortex {
210
210
  description: 'Optional caption for the media',
211
211
  },
212
212
  {
213
- displayName: 'Template JSON',
213
+ displayName: 'Template',
214
+ name: 'template_id',
215
+ type: 'options',
216
+ typeOptions: {
217
+ loadOptionsMethod: 'getTemplates',
218
+ },
219
+ required: true,
220
+ displayOptions: {
221
+ show: {
222
+ resource: ['message'],
223
+ operation: ['send'],
224
+ msg_type: ['template'],
225
+ },
226
+ },
227
+ default: '',
228
+ description: 'Select an approved WhatsApp template',
229
+ },
230
+ {
231
+ displayName: 'Template Variables',
232
+ name: 'template_variables',
233
+ type: 'fixedCollection',
234
+ typeOptions: {
235
+ multipleValues: true,
236
+ },
237
+ displayOptions: {
238
+ show: {
239
+ resource: ['message'],
240
+ operation: ['send'],
241
+ msg_type: ['template'],
242
+ },
243
+ },
244
+ default: {},
245
+ options: [
246
+ {
247
+ name: 'variable',
248
+ displayName: 'Variable',
249
+ values: [
250
+ {
251
+ displayName: 'Name',
252
+ name: 'name',
253
+ type: 'string',
254
+ default: '',
255
+ description: 'Variable name (e.g. "name") or positional label (e.g. "Variável 1")',
256
+ },
257
+ {
258
+ displayName: 'Value',
259
+ name: 'value',
260
+ type: 'string',
261
+ default: '',
262
+ description: 'Value to fill in the variable',
263
+ },
264
+ ],
265
+ },
266
+ ],
267
+ description: 'Fill in the template variables. Use the variable names shown in the template.',
268
+ },
269
+ {
270
+ displayName: 'Template JSON (Advanced)',
214
271
  name: 'template_json',
215
272
  type: 'json',
216
- required: true,
217
273
  displayOptions: {
218
274
  show: {
219
275
  resource: ['message'],
@@ -221,8 +277,8 @@ class Cortex {
221
277
  msg_type: ['template'],
222
278
  },
223
279
  },
224
- default: '{\n "name": "template_name",\n "language": "pt_BR",\n "components": [\n {\n "type": "BODY",\n "parameters": [\n {\n "type": "text",\n "text": "variable_value"\n }\n ]\n }\n ]\n}',
225
- description: 'JSON structure for the WhatsApp template',
280
+ default: '',
281
+ description: 'Optional: Override the auto-generated payload with raw JSON. Leave empty to use the template dropdown + variables above.',
226
282
  typeOptions: {
227
283
  alwaysOpenEditWindow: true,
228
284
  },
@@ -230,7 +286,10 @@ class Cortex {
230
286
  {
231
287
  displayName: 'Sender ID',
232
288
  name: 'sender_id',
233
- type: 'string',
289
+ type: 'options',
290
+ typeOptions: {
291
+ loadOptionsMethod: 'getUsers',
292
+ },
234
293
  displayOptions: {
235
294
  show: {
236
295
  resource: ['message'],
@@ -453,6 +512,35 @@ class Cortex {
453
512
  return [];
454
513
  }
455
514
  },
515
+ async getTemplates() {
516
+ const credentials = await this.getCredentials('cortexApi');
517
+ const baseUrl = credentials.apiBaseUrl.replace(/\/$/, '');
518
+ const options = {
519
+ headers: {
520
+ 'Content-Type': 'application/json',
521
+ 'Authorization': `Bearer ${credentials.accessToken}`,
522
+ },
523
+ method: 'GET',
524
+ uri: `${baseUrl}/templates`,
525
+ json: true,
526
+ };
527
+ try {
528
+ const response = await this.helpers.request(options);
529
+ const data = Array.isArray(response) ? response : (response.data || []);
530
+ return data.map((t) => {
531
+ const vars = (t.variables || []);
532
+ const varNames = vars.map((v) => v.name).join(', ');
533
+ const label = `${t.name} (${t.language || 'pt_BR'})${varNames ? ' — Vars: ' + varNames : ''}`;
534
+ return {
535
+ name: label,
536
+ value: JSON.stringify({ id: t.id, name: t.name, language: t.language, components: t.components, variables: t.variables }),
537
+ };
538
+ });
539
+ }
540
+ catch (error) {
541
+ return [];
542
+ }
543
+ },
456
544
  },
457
545
  };
458
546
  }
@@ -479,9 +567,17 @@ class Cortex {
479
567
  if (operation === 'send') {
480
568
  options.uri = `${baseUrl}/messages/send`;
481
569
  const msgType = this.getNodeParameter('msg_type', i);
482
- const senderId = this.getNodeParameter('sender_id', i);
483
- const replyTo = this.getNodeParameter('reply_to_message_id', i);
484
- const reactTo = this.getNodeParameter('react_to_message_id', i);
570
+ const senderId = this.getNodeParameter('sender_id', i, '');
571
+ let replyTo = '';
572
+ try {
573
+ replyTo = this.getNodeParameter('reply_to_message_id', i, '');
574
+ }
575
+ catch (_e) { }
576
+ let reactTo = '';
577
+ try {
578
+ reactTo = this.getNodeParameter('react_to_message_id', i, '');
579
+ }
580
+ catch (_e) { }
485
581
  let content = '';
486
582
  let caption = '';
487
583
  if (['text', 'internal_note', 'reaction'].includes(msgType)) {
@@ -494,17 +590,74 @@ class Cortex {
494
590
  }
495
591
  }
496
592
  else if (msgType === 'template') {
497
- const templateJson = this.getNodeParameter('template_json', i);
498
- if (typeof templateJson === 'string') {
499
- try {
500
- content = JSON.parse(templateJson);
593
+ const templateJsonOverride = (() => { try {
594
+ return this.getNodeParameter('template_json', i, '');
595
+ }
596
+ catch (_e) {
597
+ return '';
598
+ } })();
599
+ if (templateJsonOverride && templateJsonOverride.trim()) {
600
+ if (typeof templateJsonOverride === 'string') {
601
+ try {
602
+ content = JSON.parse(templateJsonOverride);
603
+ }
604
+ catch (e) {
605
+ throw new Error('Invalid JSON in Template JSON field');
606
+ }
501
607
  }
502
- catch (e) {
503
- throw new Error('Invalid JSON in Template JSON field');
608
+ else {
609
+ content = templateJsonOverride;
504
610
  }
505
611
  }
506
612
  else {
507
- content = templateJson;
613
+ const templateDataStr = this.getNodeParameter('template_id', i);
614
+ if (!templateDataStr)
615
+ throw new Error('Please select a template');
616
+ let templateData;
617
+ try {
618
+ templateData = JSON.parse(templateDataStr);
619
+ }
620
+ catch (e) {
621
+ throw new Error('Invalid template selection');
622
+ }
623
+ const varsCollection = (() => { try {
624
+ return this.getNodeParameter('template_variables', i, {});
625
+ }
626
+ catch (_e) {
627
+ return {};
628
+ } })();
629
+ const userVars = (varsCollection === null || varsCollection === void 0 ? void 0 : varsCollection.variable) || [];
630
+ const templateVars = templateData.variables || [];
631
+ const components = [];
632
+ const headerVars = templateVars.filter((v) => v.component === 'header');
633
+ const bodyVars = templateVars.filter((v) => v.component === 'body');
634
+ if (headerVars.length > 0) {
635
+ const params = headerVars.map((tv) => {
636
+ const userVar = userVars.find(uv => uv.name === tv.name);
637
+ const isPositional = /^Variável \d+$/.test(tv.name);
638
+ const param = { type: 'text', text: (userVar === null || userVar === void 0 ? void 0 : userVar.value) || '' };
639
+ if (!isPositional)
640
+ param.parameter_name = tv.name;
641
+ return param;
642
+ });
643
+ components.push({ type: 'header', parameters: params });
644
+ }
645
+ if (bodyVars.length > 0) {
646
+ const params = bodyVars.map((tv) => {
647
+ const userVar = userVars.find(uv => uv.name === tv.name);
648
+ const isPositional = /^Variável \d+$/.test(tv.name);
649
+ const param = { type: 'text', text: (userVar === null || userVar === void 0 ? void 0 : userVar.value) || '' };
650
+ if (!isPositional)
651
+ param.parameter_name = tv.name;
652
+ return param;
653
+ });
654
+ components.push({ type: 'body', parameters: params });
655
+ }
656
+ content = {
657
+ name: templateData.name,
658
+ language: templateData.language || 'pt_BR',
659
+ components,
660
+ };
508
661
  }
509
662
  }
510
663
  const body = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@connectorx/n8n-nodes-cortex",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "n8n nodes for Cortex API",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"