n8n-nodes-whaapy 0.3.2 → 0.3.4

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.
@@ -17,10 +17,6 @@ function slugify(text) {
17
17
  }
18
18
  // Build interactive message payload from structured fields
19
19
  function buildInteractivePayload(params) {
20
- // If using raw JSON, return it directly
21
- if (params.useRawJson && params.rawJson) {
22
- return params.rawJson;
23
- }
24
20
  const interactive = {
25
21
  type: params.interactiveType,
26
22
  body: {
@@ -318,7 +314,7 @@ class Whaapy {
318
314
  default: 'button',
319
315
  description: 'Type of interactive message. Buttons show up to 3 options, Lists show a menu with sections.',
320
316
  displayOptions: {
321
- show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
317
+ show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
322
318
  },
323
319
  },
324
320
  // Interactive: Body text (required)
@@ -332,7 +328,7 @@ class Whaapy {
332
328
  placeholder: '¿Cómo podemos ayudarte hoy?',
333
329
  description: 'Main text of the message. Max 1024 characters.',
334
330
  displayOptions: {
335
- show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
331
+ show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
336
332
  },
337
333
  },
338
334
  // Interactive: Header type (optional)
@@ -350,7 +346,7 @@ class Whaapy {
350
346
  ],
351
347
  description: 'Optional header for the message',
352
348
  displayOptions: {
353
- show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
349
+ show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
354
350
  },
355
351
  },
356
352
  // Interactive: Header text (if type=text)
@@ -367,7 +363,6 @@ class Whaapy {
367
363
  operation: ['send'],
368
364
  messageType: ['interactive'],
369
365
  interactiveHeaderType: ['text'],
370
- interactiveUseRawJson: [false],
371
366
  },
372
367
  },
373
368
  },
@@ -385,7 +380,6 @@ class Whaapy {
385
380
  operation: ['send'],
386
381
  messageType: ['interactive'],
387
382
  interactiveHeaderType: ['image', 'video', 'document'],
388
- interactiveUseRawJson: [false],
389
383
  },
390
384
  },
391
385
  },
@@ -398,7 +392,7 @@ class Whaapy {
398
392
  placeholder: 'Responde con una opción',
399
393
  description: 'Optional footer text in gray. Max 60 characters. Leave empty to omit.',
400
394
  displayOptions: {
401
- show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
395
+ show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
402
396
  },
403
397
  },
404
398
  // Interactive: Buttons (if type=button)
@@ -418,7 +412,6 @@ class Whaapy {
418
412
  operation: ['send'],
419
413
  messageType: ['interactive'],
420
414
  interactiveType: ['button'],
421
- interactiveUseRawJson: [false],
422
415
  },
423
416
  },
424
417
  options: [
@@ -462,7 +455,6 @@ class Whaapy {
462
455
  operation: ['send'],
463
456
  messageType: ['interactive'],
464
457
  interactiveType: ['list'],
465
- interactiveUseRawJson: [false],
466
458
  },
467
459
  },
468
460
  },
@@ -483,7 +475,6 @@ class Whaapy {
483
475
  operation: ['send'],
484
476
  messageType: ['interactive'],
485
477
  interactiveType: ['list'],
486
- interactiveUseRawJson: [false],
487
478
  },
488
479
  },
489
480
  options: [
@@ -547,32 +538,6 @@ class Whaapy {
547
538
  },
548
539
  ],
549
540
  },
550
- // Interactive: Advanced JSON (fallback for complex cases)
551
- {
552
- displayName: 'Use Raw JSON',
553
- name: 'interactiveUseRawJson',
554
- type: 'boolean',
555
- default: false,
556
- description: 'Use raw JSON instead of structured fields (for advanced use cases)',
557
- displayOptions: {
558
- show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
559
- },
560
- },
561
- {
562
- displayName: 'Interactive JSON',
563
- name: 'interactiveRawJson',
564
- type: 'json',
565
- default: '{}',
566
- description: 'Raw interactive content JSON. See docs.whaapy.com for structure.',
567
- displayOptions: {
568
- show: {
569
- resource: ['message'],
570
- operation: ['send'],
571
- messageType: ['interactive'],
572
- interactiveUseRawJson: [true],
573
- },
574
- },
575
- },
576
541
  // Message: Send - Location
577
542
  {
578
543
  displayName: 'Latitude',
@@ -1283,6 +1248,13 @@ class Whaapy {
1283
1248
  default: '',
1284
1249
  description: 'Comma-separated list of tags'
1285
1250
  },
1251
+ {
1252
+ displayName: 'Funnel Stage ID',
1253
+ name: 'funnelStageId',
1254
+ type: 'string',
1255
+ default: '',
1256
+ description: 'ID of the funnel stage to assign the contact to'
1257
+ },
1286
1258
  {
1287
1259
  displayName: 'Custom Fields',
1288
1260
  name: 'customFields',
@@ -1713,52 +1685,45 @@ class Whaapy {
1713
1685
  }
1714
1686
  else if (messageType === 'interactive') {
1715
1687
  // Build interactive message from structured fields
1716
- const useRawJson = this.getNodeParameter('interactiveUseRawJson', i, false);
1717
- if (useRawJson) {
1718
- const rawJson = this.getNodeParameter('interactiveRawJson', i, '{}');
1719
- body.interactive = typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson;
1688
+ const interactiveType = this.getNodeParameter('interactiveType', i);
1689
+ const bodyText = this.getNodeParameter('interactiveBodyText', i);
1690
+ const headerType = this.getNodeParameter('interactiveHeaderType', i, 'none');
1691
+ const headerText = this.getNodeParameter('interactiveHeaderText', i, '');
1692
+ const headerMediaUrl = this.getNodeParameter('interactiveHeaderMediaUrl', i, '');
1693
+ const footerText = this.getNodeParameter('interactiveFooterText', i, '');
1694
+ // Build buttons array
1695
+ let buttons = [];
1696
+ if (interactiveType === 'button') {
1697
+ const buttonsData = this.getNodeParameter('interactiveButtons', i, { buttonValues: [] });
1698
+ buttons = buttonsData.buttonValues || [];
1720
1699
  }
1721
- else {
1722
- const interactiveType = this.getNodeParameter('interactiveType', i);
1723
- const bodyText = this.getNodeParameter('interactiveBodyText', i);
1724
- const headerType = this.getNodeParameter('interactiveHeaderType', i, 'none');
1725
- const headerText = this.getNodeParameter('interactiveHeaderText', i, '');
1726
- const headerMediaUrl = this.getNodeParameter('interactiveHeaderMediaUrl', i, '');
1727
- const footerText = this.getNodeParameter('interactiveFooterText', i, '');
1728
- // Build buttons array
1729
- let buttons = [];
1730
- if (interactiveType === 'button') {
1731
- const buttonsData = this.getNodeParameter('interactiveButtons', i, { buttonValues: [] });
1732
- buttons = buttonsData.buttonValues || [];
1733
- }
1734
- // Build sections array
1735
- let sections = [];
1736
- let listButtonText = '';
1737
- if (interactiveType === 'list') {
1738
- listButtonText = this.getNodeParameter('interactiveListButtonText', i, 'Ver Opciones');
1739
- const sectionsData = this.getNodeParameter('interactiveSections', i, { sectionValues: [] });
1740
- if (sectionsData.sectionValues) {
1741
- sections = sectionsData.sectionValues.map((section) => {
1742
- var _a;
1743
- return ({
1744
- title: section.title,
1745
- rows: ((_a = section.rows) === null || _a === void 0 ? void 0 : _a.rowValues) || [],
1746
- });
1700
+ // Build sections array
1701
+ let sections = [];
1702
+ let listButtonText = '';
1703
+ if (interactiveType === 'list') {
1704
+ listButtonText = this.getNodeParameter('interactiveListButtonText', i, 'Ver Opciones');
1705
+ const sectionsData = this.getNodeParameter('interactiveSections', i, { sectionValues: [] });
1706
+ if (sectionsData.sectionValues) {
1707
+ sections = sectionsData.sectionValues.map((section) => {
1708
+ var _a;
1709
+ return ({
1710
+ title: section.title,
1711
+ rows: ((_a = section.rows) === null || _a === void 0 ? void 0 : _a.rowValues) || [],
1747
1712
  });
1748
- }
1713
+ });
1749
1714
  }
1750
- body.interactive = buildInteractivePayload({
1751
- interactiveType,
1752
- bodyText,
1753
- headerType,
1754
- headerText,
1755
- headerMediaUrl,
1756
- footerText,
1757
- buttons,
1758
- listButtonText,
1759
- sections,
1760
- });
1761
1715
  }
1716
+ body.interactive = buildInteractivePayload({
1717
+ interactiveType,
1718
+ bodyText,
1719
+ headerType,
1720
+ headerText,
1721
+ headerMediaUrl,
1722
+ footerText,
1723
+ buttons,
1724
+ listButtonText,
1725
+ sections,
1726
+ });
1762
1727
  }
1763
1728
  else if (messageType === 'location') {
1764
1729
  body.location = {
@@ -2086,13 +2051,20 @@ class Whaapy {
2086
2051
  const contactId = this.getNodeParameter('contactId', i);
2087
2052
  const updateFields = this.getNodeParameter('contactUpdateFields', i, {});
2088
2053
  const body = {};
2054
+ // Map camelCase to snake_case for API compatibility
2055
+ const fieldMapping = {
2056
+ phoneNumber: 'phone_number',
2057
+ funnelStageId: 'funnel_stage_id',
2058
+ customFields: 'custom_fields',
2059
+ };
2089
2060
  Object.entries(updateFields).forEach(([key, value]) => {
2090
2061
  if (value !== undefined && value !== '') {
2062
+ const mappedKey = fieldMapping[key] || key;
2091
2063
  if (key === 'customFields') {
2092
- body[key] = typeof value === 'string' ? JSON.parse(value) : value;
2064
+ body[mappedKey] = typeof value === 'string' ? JSON.parse(value) : value;
2093
2065
  }
2094
2066
  else {
2095
- body[key] = value;
2067
+ body[mappedKey] = value;
2096
2068
  }
2097
2069
  }
2098
2070
  });
@@ -2265,7 +2237,7 @@ class Whaapy {
2265
2237
  method: 'POST',
2266
2238
  url: `${baseUrl}/funnel/v1/contacts/${contactId}/move`,
2267
2239
  headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
2268
- body: { stageId },
2240
+ body: { stage_id: stageId },
2269
2241
  json: true,
2270
2242
  });
2271
2243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-whaapy",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "n8n community node for Whaapy - WhatsApp Business API with AI",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",