n8n-nodes-whaapy 0.2.4 → 0.3.1
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.
|
@@ -1,6 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Whaapy = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
// Helper function to convert string to slug (for auto-generating IDs)
|
|
6
|
+
function slugify(text) {
|
|
7
|
+
return text
|
|
8
|
+
.toString()
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.trim()
|
|
11
|
+
.replace(/\s+/g, '_')
|
|
12
|
+
.replace(/[^\w\-]+/g, '')
|
|
13
|
+
.replace(/\-\-+/g, '_')
|
|
14
|
+
.replace(/^-+/, '')
|
|
15
|
+
.replace(/-+$/, '')
|
|
16
|
+
.substring(0, 256);
|
|
17
|
+
}
|
|
18
|
+
// Build interactive message payload from structured fields
|
|
19
|
+
function buildInteractivePayload(params) {
|
|
20
|
+
// If using raw JSON, return it directly
|
|
21
|
+
if (params.useRawJson && params.rawJson) {
|
|
22
|
+
return params.rawJson;
|
|
23
|
+
}
|
|
24
|
+
const interactive = {
|
|
25
|
+
type: params.interactiveType,
|
|
26
|
+
body: {
|
|
27
|
+
text: params.bodyText,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
// Add header if specified
|
|
31
|
+
if (params.headerType && params.headerType !== 'none') {
|
|
32
|
+
if (params.headerType === 'text' && params.headerText) {
|
|
33
|
+
interactive.header = {
|
|
34
|
+
type: 'text',
|
|
35
|
+
text: params.headerText,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
else if (['image', 'video', 'document'].includes(params.headerType) && params.headerMediaUrl) {
|
|
39
|
+
interactive.header = {
|
|
40
|
+
type: params.headerType,
|
|
41
|
+
[params.headerType]: {
|
|
42
|
+
link: params.headerMediaUrl,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Add footer if specified and not empty
|
|
48
|
+
if (params.footerText && params.footerText.trim()) {
|
|
49
|
+
interactive.footer = {
|
|
50
|
+
text: params.footerText.trim(),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Build action based on type
|
|
54
|
+
if (params.interactiveType === 'button' && params.buttons && params.buttons.length > 0) {
|
|
55
|
+
interactive.action = {
|
|
56
|
+
buttons: params.buttons.map((btn) => ({
|
|
57
|
+
type: 'reply',
|
|
58
|
+
reply: {
|
|
59
|
+
id: btn.id || slugify(btn.title),
|
|
60
|
+
title: btn.title.substring(0, 20),
|
|
61
|
+
},
|
|
62
|
+
})),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
else if (params.interactiveType === 'list' && params.sections && params.sections.length > 0) {
|
|
66
|
+
interactive.action = {
|
|
67
|
+
button: params.listButtonText || 'Ver Opciones',
|
|
68
|
+
sections: params.sections.map((section) => ({
|
|
69
|
+
title: section.title || undefined,
|
|
70
|
+
rows: section.rows.map((row) => ({
|
|
71
|
+
id: row.id || slugify(row.title),
|
|
72
|
+
title: row.title.substring(0, 24),
|
|
73
|
+
description: row.description ? row.description.substring(0, 72) : undefined,
|
|
74
|
+
})),
|
|
75
|
+
})),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return interactive;
|
|
79
|
+
}
|
|
4
80
|
class Whaapy {
|
|
5
81
|
constructor() {
|
|
6
82
|
this.description = {
|
|
@@ -66,24 +142,12 @@ class Whaapy {
|
|
|
66
142
|
value: 'send',
|
|
67
143
|
action: 'Send a message',
|
|
68
144
|
description: 'Send a WhatsApp message',
|
|
69
|
-
routing: {
|
|
70
|
-
request: {
|
|
71
|
-
method: 'POST',
|
|
72
|
-
url: '/messages/v1',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
145
|
},
|
|
76
146
|
{
|
|
77
147
|
name: 'Retry',
|
|
78
148
|
value: 'retry',
|
|
79
149
|
action: 'Retry a failed message',
|
|
80
150
|
description: 'Retry sending a failed message',
|
|
81
|
-
routing: {
|
|
82
|
-
request: {
|
|
83
|
-
method: 'POST',
|
|
84
|
-
url: '=/messages/v1/{{$parameter.messageId}}/retry',
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
151
|
},
|
|
88
152
|
],
|
|
89
153
|
default: 'send',
|
|
@@ -100,9 +164,6 @@ class Whaapy {
|
|
|
100
164
|
displayOptions: {
|
|
101
165
|
show: { resource: ['message'], operation: ['send'] },
|
|
102
166
|
},
|
|
103
|
-
routing: {
|
|
104
|
-
send: { type: 'body', property: 'to' },
|
|
105
|
-
},
|
|
106
167
|
},
|
|
107
168
|
// Message: Send - Type
|
|
108
169
|
{
|
|
@@ -127,9 +188,6 @@ class Whaapy {
|
|
|
127
188
|
displayOptions: {
|
|
128
189
|
show: { resource: ['message'], operation: ['send'] },
|
|
129
190
|
},
|
|
130
|
-
routing: {
|
|
131
|
-
send: { type: 'body', property: 'type' },
|
|
132
|
-
},
|
|
133
191
|
},
|
|
134
192
|
// Message: Send - Text content
|
|
135
193
|
{
|
|
@@ -142,10 +200,7 @@ class Whaapy {
|
|
|
142
200
|
description: 'The text content of the message',
|
|
143
201
|
displayOptions: {
|
|
144
202
|
show: { resource: ['message'], operation: ['send'], messageType: ['text'] },
|
|
145
|
-
}
|
|
146
|
-
routing: {
|
|
147
|
-
send: { type: 'body', property: 'content' },
|
|
148
|
-
},
|
|
203
|
+
}
|
|
149
204
|
},
|
|
150
205
|
// Message: Send - Media URL (for image, video, audio, document, sticker)
|
|
151
206
|
{
|
|
@@ -163,9 +218,6 @@ class Whaapy {
|
|
|
163
218
|
messageType: ['image', 'video', 'audio', 'document', 'sticker'],
|
|
164
219
|
},
|
|
165
220
|
},
|
|
166
|
-
routing: {
|
|
167
|
-
send: { type: 'body', property: '={{$parameter.messageType}}.link' },
|
|
168
|
-
},
|
|
169
221
|
},
|
|
170
222
|
// Message: Send - Caption (for media)
|
|
171
223
|
{
|
|
@@ -181,9 +233,6 @@ class Whaapy {
|
|
|
181
233
|
messageType: ['image', 'video', 'document'],
|
|
182
234
|
},
|
|
183
235
|
},
|
|
184
|
-
routing: {
|
|
185
|
-
send: { type: 'body', property: '={{$parameter.messageType}}.caption' },
|
|
186
|
-
},
|
|
187
236
|
},
|
|
188
237
|
// Message: Send - Template name
|
|
189
238
|
{
|
|
@@ -196,10 +245,7 @@ class Whaapy {
|
|
|
196
245
|
description: 'Exact name of the WhatsApp template as it appears in Meta Business Manager',
|
|
197
246
|
displayOptions: {
|
|
198
247
|
show: { resource: ['message'], operation: ['send'], messageType: ['template'] },
|
|
199
|
-
}
|
|
200
|
-
routing: {
|
|
201
|
-
send: { type: 'body', property: 'templateName' },
|
|
202
|
-
},
|
|
248
|
+
}
|
|
203
249
|
},
|
|
204
250
|
// Message: Send - Template Language
|
|
205
251
|
{
|
|
@@ -221,10 +267,7 @@ class Whaapy {
|
|
|
221
267
|
{ name: 'French', value: 'fr' },
|
|
222
268
|
{ name: 'German', value: 'de' },
|
|
223
269
|
{ name: 'Italian', value: 'it' },
|
|
224
|
-
]
|
|
225
|
-
routing: {
|
|
226
|
-
send: { type: 'body', property: 'language' },
|
|
227
|
-
},
|
|
270
|
+
]
|
|
228
271
|
},
|
|
229
272
|
// Message: Send - Template Additional Options
|
|
230
273
|
{
|
|
@@ -244,13 +287,6 @@ class Whaapy {
|
|
|
244
287
|
default: '',
|
|
245
288
|
placeholder: 'Juan Pérez, #ORD-12345, $1500',
|
|
246
289
|
description: 'Comma-separated values for {{1}}, {{2}}, etc. placeholders in the template body',
|
|
247
|
-
routing: {
|
|
248
|
-
send: {
|
|
249
|
-
type: 'body',
|
|
250
|
-
property: 'template_parameters',
|
|
251
|
-
value: '={{ $value ? $value.split(",").map(v => v.trim()) : undefined }}',
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
290
|
},
|
|
255
291
|
{
|
|
256
292
|
displayName: 'Header Media Type',
|
|
@@ -261,10 +297,7 @@ class Whaapy {
|
|
|
261
297
|
{ name: 'Image', value: 'image' },
|
|
262
298
|
{ name: 'Video', value: 'video' },
|
|
263
299
|
{ name: 'Document', value: 'document' },
|
|
264
|
-
]
|
|
265
|
-
routing: {
|
|
266
|
-
send: { type: 'body', property: 'header_media.type' },
|
|
267
|
-
},
|
|
300
|
+
]
|
|
268
301
|
},
|
|
269
302
|
{
|
|
270
303
|
displayName: 'Header Media URL',
|
|
@@ -272,26 +305,279 @@ class Whaapy {
|
|
|
272
305
|
type: 'string',
|
|
273
306
|
default: '',
|
|
274
307
|
placeholder: 'https://example.com/image.jpg',
|
|
275
|
-
description: 'Public URL of the media file for header'
|
|
276
|
-
routing: {
|
|
277
|
-
send: { type: 'body', property: 'header_media.url' },
|
|
278
|
-
},
|
|
308
|
+
description: 'Public URL of the media file for header'
|
|
279
309
|
},
|
|
280
310
|
],
|
|
281
311
|
},
|
|
282
|
-
//
|
|
312
|
+
// ===========================================
|
|
313
|
+
// INTERACTIVE MESSAGE FIELDS (Structured)
|
|
314
|
+
// ===========================================
|
|
315
|
+
// Interactive: Type selector (button or list)
|
|
283
316
|
{
|
|
284
|
-
displayName: 'Interactive
|
|
285
|
-
name: '
|
|
286
|
-
type: '
|
|
317
|
+
displayName: 'Interactive Type',
|
|
318
|
+
name: 'interactiveType',
|
|
319
|
+
type: 'options',
|
|
287
320
|
required: true,
|
|
288
|
-
|
|
289
|
-
|
|
321
|
+
options: [
|
|
322
|
+
{ name: 'Buttons (Reply Buttons)', value: 'button' },
|
|
323
|
+
{ name: 'List (Menu)', value: 'list' },
|
|
324
|
+
],
|
|
325
|
+
default: 'button',
|
|
326
|
+
description: 'Type of interactive message. Buttons show up to 3 options, Lists show a menu with sections.',
|
|
327
|
+
displayOptions: {
|
|
328
|
+
show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
// Interactive: Body text (required)
|
|
332
|
+
{
|
|
333
|
+
displayName: 'Body Text',
|
|
334
|
+
name: 'interactiveBodyText',
|
|
335
|
+
type: 'string',
|
|
336
|
+
typeOptions: { rows: 3 },
|
|
337
|
+
required: true,
|
|
338
|
+
default: '',
|
|
339
|
+
placeholder: '¿Cómo podemos ayudarte hoy?',
|
|
340
|
+
description: 'Main text of the message. Max 1024 characters.',
|
|
341
|
+
displayOptions: {
|
|
342
|
+
show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
// Interactive: Header type (optional)
|
|
346
|
+
{
|
|
347
|
+
displayName: 'Header Type',
|
|
348
|
+
name: 'interactiveHeaderType',
|
|
349
|
+
type: 'options',
|
|
350
|
+
default: 'none',
|
|
351
|
+
options: [
|
|
352
|
+
{ name: 'None', value: 'none' },
|
|
353
|
+
{ name: 'Text', value: 'text' },
|
|
354
|
+
{ name: 'Image', value: 'image' },
|
|
355
|
+
{ name: 'Video', value: 'video' },
|
|
356
|
+
{ name: 'Document', value: 'document' },
|
|
357
|
+
],
|
|
358
|
+
description: 'Optional header for the message',
|
|
359
|
+
displayOptions: {
|
|
360
|
+
show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
// Interactive: Header text (if type=text)
|
|
364
|
+
{
|
|
365
|
+
displayName: 'Header Text',
|
|
366
|
+
name: 'interactiveHeaderText',
|
|
367
|
+
type: 'string',
|
|
368
|
+
default: '',
|
|
369
|
+
placeholder: '🍕 Pizzería Whaapy',
|
|
370
|
+
description: 'Header text. Max 60 characters.',
|
|
371
|
+
displayOptions: {
|
|
372
|
+
show: {
|
|
373
|
+
resource: ['message'],
|
|
374
|
+
operation: ['send'],
|
|
375
|
+
messageType: ['interactive'],
|
|
376
|
+
interactiveHeaderType: ['text'],
|
|
377
|
+
interactiveUseRawJson: [false],
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
// Interactive: Header media URL (if type=image|video|document)
|
|
382
|
+
{
|
|
383
|
+
displayName: 'Header Media URL',
|
|
384
|
+
name: 'interactiveHeaderMediaUrl',
|
|
385
|
+
type: 'string',
|
|
386
|
+
default: '',
|
|
387
|
+
placeholder: 'https://example.com/image.jpg',
|
|
388
|
+
description: 'Public URL of the media file for header',
|
|
389
|
+
displayOptions: {
|
|
390
|
+
show: {
|
|
391
|
+
resource: ['message'],
|
|
392
|
+
operation: ['send'],
|
|
393
|
+
messageType: ['interactive'],
|
|
394
|
+
interactiveHeaderType: ['image', 'video', 'document'],
|
|
395
|
+
interactiveUseRawJson: [false],
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
// Interactive: Footer text (optional)
|
|
400
|
+
{
|
|
401
|
+
displayName: 'Footer Text',
|
|
402
|
+
name: 'interactiveFooterText',
|
|
403
|
+
type: 'string',
|
|
404
|
+
default: '',
|
|
405
|
+
placeholder: 'Responde con una opción',
|
|
406
|
+
description: 'Optional footer text in gray. Max 60 characters. Leave empty to omit.',
|
|
407
|
+
displayOptions: {
|
|
408
|
+
show: { resource: ['message'], operation: ['send'], messageType: ['interactive'], interactiveUseRawJson: [false] },
|
|
409
|
+
},
|
|
410
|
+
},
|
|
411
|
+
// Interactive: Buttons (if type=button)
|
|
412
|
+
{
|
|
413
|
+
displayName: 'Buttons',
|
|
414
|
+
name: 'interactiveButtons',
|
|
415
|
+
type: 'fixedCollection',
|
|
416
|
+
typeOptions: {
|
|
417
|
+
multipleValues: true,
|
|
418
|
+
maxValue: 3,
|
|
419
|
+
},
|
|
420
|
+
default: { buttonValues: [] },
|
|
421
|
+
description: 'Reply buttons (1-3). Users tap to respond.',
|
|
422
|
+
displayOptions: {
|
|
423
|
+
show: {
|
|
424
|
+
resource: ['message'],
|
|
425
|
+
operation: ['send'],
|
|
426
|
+
messageType: ['interactive'],
|
|
427
|
+
interactiveType: ['button'],
|
|
428
|
+
interactiveUseRawJson: [false],
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
options: [
|
|
432
|
+
{
|
|
433
|
+
displayName: 'Button',
|
|
434
|
+
name: 'buttonValues',
|
|
435
|
+
values: [
|
|
436
|
+
{
|
|
437
|
+
displayName: 'Title',
|
|
438
|
+
name: 'title',
|
|
439
|
+
type: 'string',
|
|
440
|
+
required: true,
|
|
441
|
+
default: '',
|
|
442
|
+
placeholder: 'Ver Menú',
|
|
443
|
+
description: 'Button text visible to user. Max 20 characters.',
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
displayName: 'ID',
|
|
447
|
+
name: 'id',
|
|
448
|
+
type: 'string',
|
|
449
|
+
default: '',
|
|
450
|
+
placeholder: 'ver_menu (optional, auto-generated if empty)',
|
|
451
|
+
description: 'Unique ID returned in webhook when user clicks. If empty, generated from title.',
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
},
|
|
455
|
+
],
|
|
456
|
+
},
|
|
457
|
+
// Interactive: List button text (if type=list)
|
|
458
|
+
{
|
|
459
|
+
displayName: 'List Button Text',
|
|
460
|
+
name: 'interactiveListButtonText',
|
|
461
|
+
type: 'string',
|
|
462
|
+
required: true,
|
|
463
|
+
default: 'Ver Opciones',
|
|
464
|
+
placeholder: 'Ver Menú',
|
|
465
|
+
description: 'Text for the button that opens the list menu. Max 20 characters.',
|
|
466
|
+
displayOptions: {
|
|
467
|
+
show: {
|
|
468
|
+
resource: ['message'],
|
|
469
|
+
operation: ['send'],
|
|
470
|
+
messageType: ['interactive'],
|
|
471
|
+
interactiveType: ['list'],
|
|
472
|
+
interactiveUseRawJson: [false],
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
},
|
|
476
|
+
// Interactive: Sections (if type=list)
|
|
477
|
+
{
|
|
478
|
+
displayName: 'Sections',
|
|
479
|
+
name: 'interactiveSections',
|
|
480
|
+
type: 'fixedCollection',
|
|
481
|
+
typeOptions: {
|
|
482
|
+
multipleValues: true,
|
|
483
|
+
maxValue: 10,
|
|
484
|
+
},
|
|
485
|
+
default: { sectionValues: [] },
|
|
486
|
+
description: 'Menu sections. Each section has a title and rows (options).',
|
|
487
|
+
displayOptions: {
|
|
488
|
+
show: {
|
|
489
|
+
resource: ['message'],
|
|
490
|
+
operation: ['send'],
|
|
491
|
+
messageType: ['interactive'],
|
|
492
|
+
interactiveType: ['list'],
|
|
493
|
+
interactiveUseRawJson: [false],
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
options: [
|
|
497
|
+
{
|
|
498
|
+
displayName: 'Section',
|
|
499
|
+
name: 'sectionValues',
|
|
500
|
+
values: [
|
|
501
|
+
{
|
|
502
|
+
displayName: 'Section Title',
|
|
503
|
+
name: 'title',
|
|
504
|
+
type: 'string',
|
|
505
|
+
default: '',
|
|
506
|
+
placeholder: 'Pizzas',
|
|
507
|
+
description: 'Section title. Required if more than 1 section. Max 24 characters.',
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
displayName: 'Rows',
|
|
511
|
+
name: 'rows',
|
|
512
|
+
type: 'fixedCollection',
|
|
513
|
+
typeOptions: {
|
|
514
|
+
multipleValues: true,
|
|
515
|
+
maxValue: 10,
|
|
516
|
+
},
|
|
517
|
+
default: { rowValues: [] },
|
|
518
|
+
description: 'Options in this section',
|
|
519
|
+
options: [
|
|
520
|
+
{
|
|
521
|
+
displayName: 'Row',
|
|
522
|
+
name: 'rowValues',
|
|
523
|
+
values: [
|
|
524
|
+
{
|
|
525
|
+
displayName: 'Title',
|
|
526
|
+
name: 'title',
|
|
527
|
+
type: 'string',
|
|
528
|
+
required: true,
|
|
529
|
+
default: '',
|
|
530
|
+
placeholder: 'Margarita',
|
|
531
|
+
description: 'Row title. Max 24 characters.',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
displayName: 'Description',
|
|
535
|
+
name: 'description',
|
|
536
|
+
type: 'string',
|
|
537
|
+
default: '',
|
|
538
|
+
placeholder: 'Tomate, mozzarella - $150',
|
|
539
|
+
description: 'Row description. Optional. Max 72 characters.',
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
displayName: 'ID',
|
|
543
|
+
name: 'id',
|
|
544
|
+
type: 'string',
|
|
545
|
+
default: '',
|
|
546
|
+
placeholder: 'pizza_margarita (optional)',
|
|
547
|
+
description: 'Unique ID returned in webhook. If empty, generated from title.',
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
},
|
|
551
|
+
],
|
|
552
|
+
},
|
|
553
|
+
],
|
|
554
|
+
},
|
|
555
|
+
],
|
|
556
|
+
},
|
|
557
|
+
// Interactive: Advanced JSON (fallback for complex cases)
|
|
558
|
+
{
|
|
559
|
+
displayName: 'Use Raw JSON',
|
|
560
|
+
name: 'interactiveUseRawJson',
|
|
561
|
+
type: 'boolean',
|
|
562
|
+
default: false,
|
|
563
|
+
description: 'Use raw JSON instead of structured fields (for advanced use cases)',
|
|
290
564
|
displayOptions: {
|
|
291
565
|
show: { resource: ['message'], operation: ['send'], messageType: ['interactive'] },
|
|
292
566
|
},
|
|
293
|
-
|
|
294
|
-
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
displayName: 'Interactive JSON',
|
|
570
|
+
name: 'interactiveRawJson',
|
|
571
|
+
type: 'json',
|
|
572
|
+
default: '{}',
|
|
573
|
+
description: 'Raw interactive content JSON. See docs.whaapy.com for structure.',
|
|
574
|
+
displayOptions: {
|
|
575
|
+
show: {
|
|
576
|
+
resource: ['message'],
|
|
577
|
+
operation: ['send'],
|
|
578
|
+
messageType: ['interactive'],
|
|
579
|
+
interactiveUseRawJson: [true],
|
|
580
|
+
},
|
|
295
581
|
},
|
|
296
582
|
},
|
|
297
583
|
// Message: Send - Location
|
|
@@ -303,10 +589,7 @@ class Whaapy {
|
|
|
303
589
|
default: 0,
|
|
304
590
|
displayOptions: {
|
|
305
591
|
show: { resource: ['message'], operation: ['send'], messageType: ['location'] },
|
|
306
|
-
}
|
|
307
|
-
routing: {
|
|
308
|
-
send: { type: 'body', property: 'location.latitude' },
|
|
309
|
-
},
|
|
592
|
+
}
|
|
310
593
|
},
|
|
311
594
|
{
|
|
312
595
|
displayName: 'Longitude',
|
|
@@ -316,10 +599,7 @@ class Whaapy {
|
|
|
316
599
|
default: 0,
|
|
317
600
|
displayOptions: {
|
|
318
601
|
show: { resource: ['message'], operation: ['send'], messageType: ['location'] },
|
|
319
|
-
}
|
|
320
|
-
routing: {
|
|
321
|
-
send: { type: 'body', property: 'location.longitude' },
|
|
322
|
-
},
|
|
602
|
+
}
|
|
323
603
|
},
|
|
324
604
|
{
|
|
325
605
|
displayName: 'Location Name',
|
|
@@ -328,10 +608,7 @@ class Whaapy {
|
|
|
328
608
|
default: '',
|
|
329
609
|
displayOptions: {
|
|
330
610
|
show: { resource: ['message'], operation: ['send'], messageType: ['location'] },
|
|
331
|
-
}
|
|
332
|
-
routing: {
|
|
333
|
-
send: { type: 'body', property: 'location.name' },
|
|
334
|
-
},
|
|
611
|
+
}
|
|
335
612
|
},
|
|
336
613
|
// Message: Send - Contacts
|
|
337
614
|
{
|
|
@@ -361,10 +638,7 @@ class Whaapy {
|
|
|
361
638
|
description: 'Array of contact cards to send. Each contact needs: name.formatted_name (required), phones[].phone (required). Optional: emails, org, addresses.',
|
|
362
639
|
displayOptions: {
|
|
363
640
|
show: { resource: ['message'], operation: ['send'], messageType: ['contacts'] },
|
|
364
|
-
}
|
|
365
|
-
routing: {
|
|
366
|
-
send: { type: 'body', property: 'contacts' },
|
|
367
|
-
},
|
|
641
|
+
}
|
|
368
642
|
},
|
|
369
643
|
// Message: Send - Reaction
|
|
370
644
|
{
|
|
@@ -375,10 +649,7 @@ class Whaapy {
|
|
|
375
649
|
default: '',
|
|
376
650
|
displayOptions: {
|
|
377
651
|
show: { resource: ['message'], operation: ['send'], messageType: ['reaction'] },
|
|
378
|
-
}
|
|
379
|
-
routing: {
|
|
380
|
-
send: { type: 'body', property: 'reaction.message_id' },
|
|
381
|
-
},
|
|
652
|
+
}
|
|
382
653
|
},
|
|
383
654
|
{
|
|
384
655
|
displayName: 'Emoji',
|
|
@@ -388,10 +659,7 @@ class Whaapy {
|
|
|
388
659
|
default: '👍',
|
|
389
660
|
displayOptions: {
|
|
390
661
|
show: { resource: ['message'], operation: ['send'], messageType: ['reaction'] },
|
|
391
|
-
}
|
|
392
|
-
routing: {
|
|
393
|
-
send: { type: 'body', property: 'reaction.emoji' },
|
|
394
|
-
},
|
|
662
|
+
}
|
|
395
663
|
},
|
|
396
664
|
// Message: Send - Additional Fields
|
|
397
665
|
{
|
|
@@ -409,60 +677,42 @@ class Whaapy {
|
|
|
409
677
|
name: 'pauseAi',
|
|
410
678
|
type: 'boolean',
|
|
411
679
|
default: false,
|
|
412
|
-
description: 'Pause AI after sending this message'
|
|
413
|
-
routing: {
|
|
414
|
-
send: { type: 'body', property: 'ai.pause' },
|
|
415
|
-
},
|
|
680
|
+
description: 'Pause AI after sending this message'
|
|
416
681
|
},
|
|
417
682
|
{
|
|
418
683
|
displayName: 'Pause Duration (Minutes)',
|
|
419
684
|
name: 'pauseDuration',
|
|
420
685
|
type: 'number',
|
|
421
686
|
default: 5,
|
|
422
|
-
description: 'How long to pause AI (1-1440 minutes)'
|
|
423
|
-
routing: {
|
|
424
|
-
send: { type: 'body', property: 'ai.pauseDuration' },
|
|
425
|
-
},
|
|
687
|
+
description: 'How long to pause AI (1-1440 minutes)'
|
|
426
688
|
},
|
|
427
689
|
{
|
|
428
690
|
displayName: 'Disable AI',
|
|
429
691
|
name: 'disableAi',
|
|
430
692
|
type: 'boolean',
|
|
431
693
|
default: false,
|
|
432
|
-
description: 'Permanently disable AI for this conversation'
|
|
433
|
-
routing: {
|
|
434
|
-
send: { type: 'body', property: 'ai.disable' },
|
|
435
|
-
},
|
|
694
|
+
description: 'Permanently disable AI for this conversation'
|
|
436
695
|
},
|
|
437
696
|
{
|
|
438
697
|
displayName: 'Reply To Message ID',
|
|
439
698
|
name: 'replyTo',
|
|
440
699
|
type: 'string',
|
|
441
700
|
default: '',
|
|
442
|
-
description: 'Message ID to reply to'
|
|
443
|
-
routing: {
|
|
444
|
-
send: { type: 'body', property: 'context.message_id' },
|
|
445
|
-
},
|
|
701
|
+
description: 'Message ID to reply to'
|
|
446
702
|
},
|
|
447
703
|
{
|
|
448
704
|
displayName: 'Create Conversation',
|
|
449
705
|
name: 'createConversation',
|
|
450
706
|
type: 'boolean',
|
|
451
707
|
default: true,
|
|
452
|
-
description: 'Create a conversation if it doesn\'t exist'
|
|
453
|
-
routing: {
|
|
454
|
-
send: { type: 'body', property: 'createConversation' },
|
|
455
|
-
},
|
|
708
|
+
description: 'Create a conversation if it doesn\'t exist'
|
|
456
709
|
},
|
|
457
710
|
{
|
|
458
711
|
displayName: 'Metadata',
|
|
459
712
|
name: 'metadata',
|
|
460
713
|
type: 'json',
|
|
461
714
|
default: '{}',
|
|
462
|
-
description: 'Custom metadata to attach to the message'
|
|
463
|
-
routing: {
|
|
464
|
-
send: { type: 'body', property: 'metadata' },
|
|
465
|
-
},
|
|
715
|
+
description: 'Custom metadata to attach to the message'
|
|
466
716
|
},
|
|
467
717
|
],
|
|
468
718
|
},
|
|
@@ -494,13 +744,7 @@ class Whaapy {
|
|
|
494
744
|
name: 'Upload',
|
|
495
745
|
value: 'upload',
|
|
496
746
|
action: 'Upload media',
|
|
497
|
-
description: 'Upload media to WhatsApp CDN'
|
|
498
|
-
routing: {
|
|
499
|
-
request: {
|
|
500
|
-
method: 'POST',
|
|
501
|
-
url: '/media/v1',
|
|
502
|
-
},
|
|
503
|
-
},
|
|
747
|
+
description: 'Upload media to WhatsApp CDN'
|
|
504
748
|
},
|
|
505
749
|
],
|
|
506
750
|
default: 'upload',
|
|
@@ -521,10 +765,7 @@ class Whaapy {
|
|
|
521
765
|
default: 'image',
|
|
522
766
|
displayOptions: {
|
|
523
767
|
show: { resource: ['media'], operation: ['upload'] },
|
|
524
|
-
}
|
|
525
|
-
routing: {
|
|
526
|
-
send: { type: 'body', property: 'type' },
|
|
527
|
-
},
|
|
768
|
+
}
|
|
528
769
|
},
|
|
529
770
|
// Media: Upload - Binary property
|
|
530
771
|
{
|
|
@@ -554,121 +795,61 @@ class Whaapy {
|
|
|
554
795
|
name: 'List',
|
|
555
796
|
value: 'list',
|
|
556
797
|
action: 'List conversations',
|
|
557
|
-
description: 'Get all conversations'
|
|
558
|
-
routing: {
|
|
559
|
-
request: {
|
|
560
|
-
method: 'GET',
|
|
561
|
-
url: '/conversations/v1',
|
|
562
|
-
},
|
|
563
|
-
},
|
|
798
|
+
description: 'Get all conversations'
|
|
564
799
|
},
|
|
565
800
|
{
|
|
566
801
|
name: 'Get',
|
|
567
802
|
value: 'get',
|
|
568
803
|
action: 'Get a conversation',
|
|
569
804
|
description: 'Get a specific conversation',
|
|
570
|
-
routing: {
|
|
571
|
-
request: {
|
|
572
|
-
method: 'GET',
|
|
573
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}',
|
|
574
|
-
},
|
|
575
|
-
},
|
|
576
805
|
},
|
|
577
806
|
{
|
|
578
807
|
name: 'Get by Phone',
|
|
579
808
|
value: 'getByPhone',
|
|
580
809
|
action: 'Get conversation by phone',
|
|
581
810
|
description: 'Find conversation by phone number',
|
|
582
|
-
routing: {
|
|
583
|
-
request: {
|
|
584
|
-
method: 'GET',
|
|
585
|
-
url: '=/conversations/v1/by-phone/{{$parameter.phoneNumber}}',
|
|
586
|
-
},
|
|
587
|
-
},
|
|
588
811
|
},
|
|
589
812
|
{
|
|
590
813
|
name: 'Get Messages',
|
|
591
814
|
value: 'getMessages',
|
|
592
815
|
action: 'Get conversation messages',
|
|
593
816
|
description: 'Get message history of a conversation',
|
|
594
|
-
routing: {
|
|
595
|
-
request: {
|
|
596
|
-
method: 'GET',
|
|
597
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/messages',
|
|
598
|
-
},
|
|
599
|
-
},
|
|
600
817
|
},
|
|
601
818
|
{
|
|
602
819
|
name: 'Close',
|
|
603
820
|
value: 'close',
|
|
604
821
|
action: 'Close a conversation',
|
|
605
822
|
description: 'Close a conversation',
|
|
606
|
-
routing: {
|
|
607
|
-
request: {
|
|
608
|
-
method: 'POST',
|
|
609
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/close',
|
|
610
|
-
},
|
|
611
|
-
},
|
|
612
823
|
},
|
|
613
824
|
{
|
|
614
825
|
name: 'Archive',
|
|
615
826
|
value: 'archive',
|
|
616
827
|
action: 'Archive a conversation',
|
|
617
828
|
description: 'Archive a conversation',
|
|
618
|
-
routing: {
|
|
619
|
-
request: {
|
|
620
|
-
method: 'POST',
|
|
621
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/archive',
|
|
622
|
-
},
|
|
623
|
-
},
|
|
624
829
|
},
|
|
625
830
|
{
|
|
626
831
|
name: 'Mark Read',
|
|
627
832
|
value: 'markRead',
|
|
628
833
|
action: 'Mark conversation as read',
|
|
629
834
|
description: 'Mark a conversation as read',
|
|
630
|
-
routing: {
|
|
631
|
-
request: {
|
|
632
|
-
method: 'PATCH',
|
|
633
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/mark-read',
|
|
634
|
-
},
|
|
635
|
-
},
|
|
636
835
|
},
|
|
637
836
|
{
|
|
638
837
|
name: 'Set AI',
|
|
639
838
|
value: 'setAi',
|
|
640
839
|
action: 'Enable/disable AI',
|
|
641
840
|
description: 'Enable or disable AI for a conversation',
|
|
642
|
-
routing: {
|
|
643
|
-
request: {
|
|
644
|
-
method: 'PATCH',
|
|
645
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/ai',
|
|
646
|
-
},
|
|
647
|
-
},
|
|
648
841
|
},
|
|
649
842
|
{
|
|
650
843
|
name: 'Pause AI',
|
|
651
844
|
value: 'pauseAi',
|
|
652
845
|
action: 'Pause AI temporarily',
|
|
653
846
|
description: 'Pause AI for a conversation',
|
|
654
|
-
routing: {
|
|
655
|
-
request: {
|
|
656
|
-
method: 'POST',
|
|
657
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/ai/pause',
|
|
658
|
-
},
|
|
659
|
-
},
|
|
660
847
|
},
|
|
661
848
|
{
|
|
662
849
|
name: 'AI Suggest',
|
|
663
850
|
value: 'aiSuggest',
|
|
664
851
|
action: 'Get AI suggestion',
|
|
665
852
|
description: 'Get an AI suggestion without sending',
|
|
666
|
-
routing: {
|
|
667
|
-
request: {
|
|
668
|
-
method: 'POST',
|
|
669
|
-
url: '=/conversations/v1/{{$parameter.conversationId}}/ai-suggest',
|
|
670
|
-
},
|
|
671
|
-
},
|
|
672
853
|
},
|
|
673
854
|
],
|
|
674
855
|
default: 'list',
|
|
@@ -708,10 +889,7 @@ class Whaapy {
|
|
|
708
889
|
default: true,
|
|
709
890
|
displayOptions: {
|
|
710
891
|
show: { resource: ['conversation'], operation: ['setAi'] },
|
|
711
|
-
}
|
|
712
|
-
routing: {
|
|
713
|
-
send: { type: 'body', property: 'aiEnabled' },
|
|
714
|
-
},
|
|
892
|
+
}
|
|
715
893
|
},
|
|
716
894
|
// Conversation: Pause AI - Duration
|
|
717
895
|
{
|
|
@@ -723,10 +901,7 @@ class Whaapy {
|
|
|
723
901
|
description: 'How long to pause AI (1-1440 minutes)',
|
|
724
902
|
displayOptions: {
|
|
725
903
|
show: { resource: ['conversation'], operation: ['pauseAi'] },
|
|
726
|
-
}
|
|
727
|
-
routing: {
|
|
728
|
-
send: { type: 'body', property: 'duration' },
|
|
729
|
-
},
|
|
904
|
+
}
|
|
730
905
|
},
|
|
731
906
|
// Conversation: List - Filters
|
|
732
907
|
{
|
|
@@ -744,10 +919,7 @@ class Whaapy {
|
|
|
744
919
|
name: 'search',
|
|
745
920
|
type: 'string',
|
|
746
921
|
default: '',
|
|
747
|
-
description: 'Search by name or phone'
|
|
748
|
-
routing: {
|
|
749
|
-
send: { type: 'query', property: 'search' },
|
|
750
|
-
},
|
|
922
|
+
description: 'Search by name or phone'
|
|
751
923
|
},
|
|
752
924
|
{
|
|
753
925
|
displayName: 'Status',
|
|
@@ -759,29 +931,20 @@ class Whaapy {
|
|
|
759
931
|
{ name: 'Closed', value: 'closed' },
|
|
760
932
|
{ name: 'Archived', value: 'archived' },
|
|
761
933
|
],
|
|
762
|
-
default: 'all'
|
|
763
|
-
routing: {
|
|
764
|
-
send: { type: 'query', property: 'status' },
|
|
765
|
-
},
|
|
934
|
+
default: 'all'
|
|
766
935
|
},
|
|
767
936
|
{
|
|
768
937
|
displayName: 'Limit',
|
|
769
938
|
name: 'limit',
|
|
770
939
|
type: 'number',
|
|
771
940
|
default: 20,
|
|
772
|
-
description: 'Max results (1-100)'
|
|
773
|
-
routing: {
|
|
774
|
-
send: { type: 'query', property: 'limit' },
|
|
775
|
-
},
|
|
941
|
+
description: 'Max results (1-100)'
|
|
776
942
|
},
|
|
777
943
|
{
|
|
778
944
|
displayName: 'Offset',
|
|
779
945
|
name: 'offset',
|
|
780
946
|
type: 'number',
|
|
781
|
-
default: 0
|
|
782
|
-
routing: {
|
|
783
|
-
send: { type: 'query', property: 'offset' },
|
|
784
|
-
},
|
|
947
|
+
default: 0
|
|
785
948
|
},
|
|
786
949
|
],
|
|
787
950
|
},
|
|
@@ -800,20 +963,14 @@ class Whaapy {
|
|
|
800
963
|
displayName: 'Limit',
|
|
801
964
|
name: 'limit',
|
|
802
965
|
type: 'number',
|
|
803
|
-
default: 50
|
|
804
|
-
routing: {
|
|
805
|
-
send: { type: 'query', property: 'limit' },
|
|
806
|
-
},
|
|
966
|
+
default: 50
|
|
807
967
|
},
|
|
808
968
|
{
|
|
809
969
|
displayName: 'Cursor',
|
|
810
970
|
name: 'cursor',
|
|
811
971
|
type: 'string',
|
|
812
972
|
default: '',
|
|
813
|
-
description: 'Pagination cursor'
|
|
814
|
-
routing: {
|
|
815
|
-
send: { type: 'query', property: 'cursor' },
|
|
816
|
-
},
|
|
973
|
+
description: 'Pagination cursor'
|
|
817
974
|
},
|
|
818
975
|
],
|
|
819
976
|
},
|
|
@@ -833,25 +990,13 @@ class Whaapy {
|
|
|
833
990
|
name: 'Toggle',
|
|
834
991
|
value: 'toggle',
|
|
835
992
|
action: 'Toggle AI globally',
|
|
836
|
-
description: 'Enable or disable AI globally'
|
|
837
|
-
routing: {
|
|
838
|
-
request: {
|
|
839
|
-
method: 'POST',
|
|
840
|
-
url: '/agent/v1/toggle',
|
|
841
|
-
},
|
|
842
|
-
},
|
|
993
|
+
description: 'Enable or disable AI globally'
|
|
843
994
|
},
|
|
844
995
|
{
|
|
845
996
|
name: 'Pause',
|
|
846
997
|
value: 'pause',
|
|
847
998
|
action: 'Pause AI globally',
|
|
848
|
-
description: 'Pause AI globally for X minutes'
|
|
849
|
-
routing: {
|
|
850
|
-
request: {
|
|
851
|
-
method: 'POST',
|
|
852
|
-
url: '/agent/v1/pause',
|
|
853
|
-
},
|
|
854
|
-
},
|
|
999
|
+
description: 'Pause AI globally for X minutes'
|
|
855
1000
|
},
|
|
856
1001
|
],
|
|
857
1002
|
default: 'toggle',
|
|
@@ -865,10 +1010,7 @@ class Whaapy {
|
|
|
865
1010
|
default: true,
|
|
866
1011
|
displayOptions: {
|
|
867
1012
|
show: { resource: ['agent'], operation: ['toggle'] },
|
|
868
|
-
}
|
|
869
|
-
routing: {
|
|
870
|
-
send: { type: 'body', property: 'enabled' },
|
|
871
|
-
},
|
|
1013
|
+
}
|
|
872
1014
|
},
|
|
873
1015
|
// Agent: Pause - Duration
|
|
874
1016
|
{
|
|
@@ -880,10 +1022,7 @@ class Whaapy {
|
|
|
880
1022
|
description: 'How long to pause AI globally',
|
|
881
1023
|
displayOptions: {
|
|
882
1024
|
show: { resource: ['agent'], operation: ['pause'] },
|
|
883
|
-
}
|
|
884
|
-
routing: {
|
|
885
|
-
send: { type: 'body', property: 'duration' },
|
|
886
|
-
},
|
|
1025
|
+
}
|
|
887
1026
|
},
|
|
888
1027
|
// ===========================================
|
|
889
1028
|
// TEMPLATE OPERATIONS
|
|
@@ -901,49 +1040,25 @@ class Whaapy {
|
|
|
901
1040
|
name: 'List',
|
|
902
1041
|
value: 'list',
|
|
903
1042
|
action: 'List templates',
|
|
904
|
-
description: 'Get all WhatsApp templates'
|
|
905
|
-
routing: {
|
|
906
|
-
request: {
|
|
907
|
-
method: 'GET',
|
|
908
|
-
url: '/templates/v1',
|
|
909
|
-
},
|
|
910
|
-
},
|
|
1043
|
+
description: 'Get all WhatsApp templates'
|
|
911
1044
|
},
|
|
912
1045
|
{
|
|
913
1046
|
name: 'Get',
|
|
914
1047
|
value: 'get',
|
|
915
1048
|
action: 'Get a template',
|
|
916
1049
|
description: 'Get a specific template',
|
|
917
|
-
routing: {
|
|
918
|
-
request: {
|
|
919
|
-
method: 'GET',
|
|
920
|
-
url: '=/templates/v1/{{$parameter.templateId}}',
|
|
921
|
-
},
|
|
922
|
-
},
|
|
923
1050
|
},
|
|
924
1051
|
{
|
|
925
1052
|
name: 'Get Variables',
|
|
926
1053
|
value: 'getVariables',
|
|
927
1054
|
action: 'Get template variables',
|
|
928
|
-
description: 'Get available template variables'
|
|
929
|
-
routing: {
|
|
930
|
-
request: {
|
|
931
|
-
method: 'GET',
|
|
932
|
-
url: '/templates/v1/variables',
|
|
933
|
-
},
|
|
934
|
-
},
|
|
1055
|
+
description: 'Get available template variables'
|
|
935
1056
|
},
|
|
936
1057
|
{
|
|
937
1058
|
name: 'Sync',
|
|
938
1059
|
value: 'sync',
|
|
939
1060
|
action: 'Sync templates',
|
|
940
|
-
description: 'Sync templates from Meta'
|
|
941
|
-
routing: {
|
|
942
|
-
request: {
|
|
943
|
-
method: 'POST',
|
|
944
|
-
url: '/templates/v1/sync',
|
|
945
|
-
},
|
|
946
|
-
},
|
|
1061
|
+
description: 'Sync templates from Meta'
|
|
947
1062
|
},
|
|
948
1063
|
],
|
|
949
1064
|
default: 'list',
|
|
@@ -975,28 +1090,19 @@ class Whaapy {
|
|
|
975
1090
|
name: 'status',
|
|
976
1091
|
type: 'string',
|
|
977
1092
|
default: '',
|
|
978
|
-
description: 'Filter by template status'
|
|
979
|
-
routing: {
|
|
980
|
-
send: { type: 'query', property: 'status' },
|
|
981
|
-
},
|
|
1093
|
+
description: 'Filter by template status'
|
|
982
1094
|
},
|
|
983
1095
|
{
|
|
984
1096
|
displayName: 'Limit',
|
|
985
1097
|
name: 'limit',
|
|
986
1098
|
type: 'number',
|
|
987
|
-
default: 20
|
|
988
|
-
routing: {
|
|
989
|
-
send: { type: 'query', property: 'limit' },
|
|
990
|
-
},
|
|
1099
|
+
default: 20
|
|
991
1100
|
},
|
|
992
1101
|
{
|
|
993
1102
|
displayName: 'Offset',
|
|
994
1103
|
name: 'offset',
|
|
995
1104
|
type: 'number',
|
|
996
|
-
default: 0
|
|
997
|
-
routing: {
|
|
998
|
-
send: { type: 'query', property: 'offset' },
|
|
999
|
-
},
|
|
1105
|
+
default: 0
|
|
1000
1106
|
},
|
|
1001
1107
|
],
|
|
1002
1108
|
},
|
|
@@ -1016,121 +1122,61 @@ class Whaapy {
|
|
|
1016
1122
|
name: 'List',
|
|
1017
1123
|
value: 'list',
|
|
1018
1124
|
action: 'List contacts',
|
|
1019
|
-
description: 'Get all contacts'
|
|
1020
|
-
routing: {
|
|
1021
|
-
request: {
|
|
1022
|
-
method: 'GET',
|
|
1023
|
-
url: '/contacts/v1',
|
|
1024
|
-
},
|
|
1025
|
-
},
|
|
1125
|
+
description: 'Get all contacts'
|
|
1026
1126
|
},
|
|
1027
1127
|
{
|
|
1028
1128
|
name: 'Get',
|
|
1029
1129
|
value: 'get',
|
|
1030
1130
|
action: 'Get a contact',
|
|
1031
1131
|
description: 'Get a specific contact',
|
|
1032
|
-
routing: {
|
|
1033
|
-
request: {
|
|
1034
|
-
method: 'GET',
|
|
1035
|
-
url: '=/contacts/v1/{{$parameter.contactId}}',
|
|
1036
|
-
},
|
|
1037
|
-
},
|
|
1038
1132
|
},
|
|
1039
1133
|
{
|
|
1040
1134
|
name: 'Create',
|
|
1041
1135
|
value: 'create',
|
|
1042
1136
|
action: 'Create a contact',
|
|
1043
|
-
description: 'Create a new contact'
|
|
1044
|
-
routing: {
|
|
1045
|
-
request: {
|
|
1046
|
-
method: 'POST',
|
|
1047
|
-
url: '/contacts/v1',
|
|
1048
|
-
},
|
|
1049
|
-
},
|
|
1137
|
+
description: 'Create a new contact'
|
|
1050
1138
|
},
|
|
1051
1139
|
{
|
|
1052
1140
|
name: 'Update',
|
|
1053
1141
|
value: 'update',
|
|
1054
1142
|
action: 'Update a contact',
|
|
1055
1143
|
description: 'Update an existing contact',
|
|
1056
|
-
routing: {
|
|
1057
|
-
request: {
|
|
1058
|
-
method: 'PATCH',
|
|
1059
|
-
url: '=/contacts/v1/{{$parameter.contactId}}',
|
|
1060
|
-
},
|
|
1061
|
-
},
|
|
1062
1144
|
},
|
|
1063
1145
|
{
|
|
1064
1146
|
name: 'Delete',
|
|
1065
1147
|
value: 'delete',
|
|
1066
1148
|
action: 'Delete a contact',
|
|
1067
1149
|
description: 'Delete a contact',
|
|
1068
|
-
routing: {
|
|
1069
|
-
request: {
|
|
1070
|
-
method: 'DELETE',
|
|
1071
|
-
url: '=/contacts/v1/{{$parameter.contactId}}',
|
|
1072
|
-
},
|
|
1073
|
-
},
|
|
1074
1150
|
},
|
|
1075
1151
|
{
|
|
1076
1152
|
name: 'Search',
|
|
1077
1153
|
value: 'search',
|
|
1078
1154
|
action: 'Search contacts',
|
|
1079
|
-
description: 'Advanced search for contacts'
|
|
1080
|
-
routing: {
|
|
1081
|
-
request: {
|
|
1082
|
-
method: 'POST',
|
|
1083
|
-
url: '/contacts/v1/search',
|
|
1084
|
-
},
|
|
1085
|
-
},
|
|
1155
|
+
description: 'Advanced search for contacts'
|
|
1086
1156
|
},
|
|
1087
1157
|
{
|
|
1088
1158
|
name: 'Bulk',
|
|
1089
1159
|
value: 'bulk',
|
|
1090
1160
|
action: 'Bulk operations',
|
|
1091
|
-
description: 'Perform bulk operations on contacts'
|
|
1092
|
-
routing: {
|
|
1093
|
-
request: {
|
|
1094
|
-
method: 'POST',
|
|
1095
|
-
url: '/contacts/v1/bulk',
|
|
1096
|
-
},
|
|
1097
|
-
},
|
|
1161
|
+
description: 'Perform bulk operations on contacts'
|
|
1098
1162
|
},
|
|
1099
1163
|
{
|
|
1100
1164
|
name: 'Merge',
|
|
1101
1165
|
value: 'merge',
|
|
1102
1166
|
action: 'Merge contacts',
|
|
1103
1167
|
description: 'Merge two contacts',
|
|
1104
|
-
routing: {
|
|
1105
|
-
request: {
|
|
1106
|
-
method: 'POST',
|
|
1107
|
-
url: '=/contacts/v1/{{$parameter.contactId}}/merge',
|
|
1108
|
-
},
|
|
1109
|
-
},
|
|
1110
1168
|
},
|
|
1111
1169
|
{
|
|
1112
1170
|
name: 'Get Tags',
|
|
1113
1171
|
value: 'getTags',
|
|
1114
1172
|
action: 'Get all tags',
|
|
1115
|
-
description: 'Get all available tags'
|
|
1116
|
-
routing: {
|
|
1117
|
-
request: {
|
|
1118
|
-
method: 'GET',
|
|
1119
|
-
url: '/contacts/v1/tags',
|
|
1120
|
-
},
|
|
1121
|
-
},
|
|
1173
|
+
description: 'Get all available tags'
|
|
1122
1174
|
},
|
|
1123
1175
|
{
|
|
1124
1176
|
name: 'Get Fields',
|
|
1125
1177
|
value: 'getFields',
|
|
1126
1178
|
action: 'Get custom fields',
|
|
1127
|
-
description: 'Get available custom fields'
|
|
1128
|
-
routing: {
|
|
1129
|
-
request: {
|
|
1130
|
-
method: 'GET',
|
|
1131
|
-
url: '/contacts/v1/fields',
|
|
1132
|
-
},
|
|
1133
|
-
},
|
|
1179
|
+
description: 'Get available custom fields'
|
|
1134
1180
|
},
|
|
1135
1181
|
],
|
|
1136
1182
|
default: 'list',
|
|
@@ -1158,10 +1204,7 @@ class Whaapy {
|
|
|
1158
1204
|
default: '',
|
|
1159
1205
|
displayOptions: {
|
|
1160
1206
|
show: { resource: ['contact'], operation: ['create'] },
|
|
1161
|
-
}
|
|
1162
|
-
routing: {
|
|
1163
|
-
send: { type: 'body', property: 'name' },
|
|
1164
|
-
},
|
|
1207
|
+
}
|
|
1165
1208
|
},
|
|
1166
1209
|
{
|
|
1167
1210
|
displayName: 'Phone Number',
|
|
@@ -1172,10 +1215,7 @@ class Whaapy {
|
|
|
1172
1215
|
placeholder: '+5215512345678',
|
|
1173
1216
|
displayOptions: {
|
|
1174
1217
|
show: { resource: ['contact'], operation: ['create'] },
|
|
1175
|
-
}
|
|
1176
|
-
routing: {
|
|
1177
|
-
send: { type: 'body', property: 'phoneNumber' },
|
|
1178
|
-
},
|
|
1218
|
+
}
|
|
1179
1219
|
},
|
|
1180
1220
|
{
|
|
1181
1221
|
displayName: 'Additional Fields',
|
|
@@ -1191,38 +1231,26 @@ class Whaapy {
|
|
|
1191
1231
|
displayName: 'Email',
|
|
1192
1232
|
name: 'email',
|
|
1193
1233
|
type: 'string',
|
|
1194
|
-
default: ''
|
|
1195
|
-
routing: {
|
|
1196
|
-
send: { type: 'body', property: 'email' },
|
|
1197
|
-
},
|
|
1234
|
+
default: ''
|
|
1198
1235
|
},
|
|
1199
1236
|
{
|
|
1200
1237
|
displayName: 'Tags',
|
|
1201
1238
|
name: 'tags',
|
|
1202
1239
|
type: 'string',
|
|
1203
1240
|
default: '',
|
|
1204
|
-
description: 'Comma-separated list of tags'
|
|
1205
|
-
routing: {
|
|
1206
|
-
send: { type: 'body', property: 'tags' },
|
|
1207
|
-
},
|
|
1241
|
+
description: 'Comma-separated list of tags'
|
|
1208
1242
|
},
|
|
1209
1243
|
{
|
|
1210
1244
|
displayName: 'Custom Fields',
|
|
1211
1245
|
name: 'customFields',
|
|
1212
1246
|
type: 'json',
|
|
1213
|
-
default: '{}'
|
|
1214
|
-
routing: {
|
|
1215
|
-
send: { type: 'body', property: 'customFields' },
|
|
1216
|
-
},
|
|
1247
|
+
default: '{}'
|
|
1217
1248
|
},
|
|
1218
1249
|
{
|
|
1219
1250
|
displayName: 'Metadata',
|
|
1220
1251
|
name: 'metadata',
|
|
1221
1252
|
type: 'json',
|
|
1222
|
-
default: '{}'
|
|
1223
|
-
routing: {
|
|
1224
|
-
send: { type: 'body', property: 'metadata' },
|
|
1225
|
-
},
|
|
1253
|
+
default: '{}'
|
|
1226
1254
|
},
|
|
1227
1255
|
],
|
|
1228
1256
|
},
|
|
@@ -1241,47 +1269,32 @@ class Whaapy {
|
|
|
1241
1269
|
displayName: 'Name',
|
|
1242
1270
|
name: 'name',
|
|
1243
1271
|
type: 'string',
|
|
1244
|
-
default: ''
|
|
1245
|
-
routing: {
|
|
1246
|
-
send: { type: 'body', property: 'name' },
|
|
1247
|
-
},
|
|
1272
|
+
default: ''
|
|
1248
1273
|
},
|
|
1249
1274
|
{
|
|
1250
1275
|
displayName: 'Phone Number',
|
|
1251
1276
|
name: 'phoneNumber',
|
|
1252
1277
|
type: 'string',
|
|
1253
|
-
default: ''
|
|
1254
|
-
routing: {
|
|
1255
|
-
send: { type: 'body', property: 'phoneNumber' },
|
|
1256
|
-
},
|
|
1278
|
+
default: ''
|
|
1257
1279
|
},
|
|
1258
1280
|
{
|
|
1259
1281
|
displayName: 'Email',
|
|
1260
1282
|
name: 'email',
|
|
1261
1283
|
type: 'string',
|
|
1262
|
-
default: ''
|
|
1263
|
-
routing: {
|
|
1264
|
-
send: { type: 'body', property: 'email' },
|
|
1265
|
-
},
|
|
1284
|
+
default: ''
|
|
1266
1285
|
},
|
|
1267
1286
|
{
|
|
1268
1287
|
displayName: 'Tags',
|
|
1269
1288
|
name: 'tags',
|
|
1270
1289
|
type: 'string',
|
|
1271
1290
|
default: '',
|
|
1272
|
-
description: 'Comma-separated list of tags'
|
|
1273
|
-
routing: {
|
|
1274
|
-
send: { type: 'body', property: 'tags' },
|
|
1275
|
-
},
|
|
1291
|
+
description: 'Comma-separated list of tags'
|
|
1276
1292
|
},
|
|
1277
1293
|
{
|
|
1278
1294
|
displayName: 'Custom Fields',
|
|
1279
1295
|
name: 'customFields',
|
|
1280
1296
|
type: 'json',
|
|
1281
|
-
default: '{}'
|
|
1282
|
-
routing: {
|
|
1283
|
-
send: { type: 'body', property: 'customFields' },
|
|
1284
|
-
},
|
|
1297
|
+
default: '{}'
|
|
1285
1298
|
},
|
|
1286
1299
|
],
|
|
1287
1300
|
},
|
|
@@ -1294,10 +1307,7 @@ class Whaapy {
|
|
|
1294
1307
|
default: '',
|
|
1295
1308
|
displayOptions: {
|
|
1296
1309
|
show: { resource: ['contact'], operation: ['search'] },
|
|
1297
|
-
}
|
|
1298
|
-
routing: {
|
|
1299
|
-
send: { type: 'body', property: 'query' },
|
|
1300
|
-
},
|
|
1310
|
+
}
|
|
1301
1311
|
},
|
|
1302
1312
|
{
|
|
1303
1313
|
displayName: 'Search Options',
|
|
@@ -1313,28 +1323,19 @@ class Whaapy {
|
|
|
1313
1323
|
displayName: 'Filters',
|
|
1314
1324
|
name: 'filters',
|
|
1315
1325
|
type: 'json',
|
|
1316
|
-
default: '{}'
|
|
1317
|
-
routing: {
|
|
1318
|
-
send: { type: 'body', property: 'filters' },
|
|
1319
|
-
},
|
|
1326
|
+
default: '{}'
|
|
1320
1327
|
},
|
|
1321
1328
|
{
|
|
1322
1329
|
displayName: 'Limit',
|
|
1323
1330
|
name: 'limit',
|
|
1324
1331
|
type: 'number',
|
|
1325
|
-
default: 20
|
|
1326
|
-
routing: {
|
|
1327
|
-
send: { type: 'body', property: 'limit' },
|
|
1328
|
-
},
|
|
1332
|
+
default: 20
|
|
1329
1333
|
},
|
|
1330
1334
|
{
|
|
1331
1335
|
displayName: 'Cursor',
|
|
1332
1336
|
name: 'cursor',
|
|
1333
1337
|
type: 'string',
|
|
1334
|
-
default: ''
|
|
1335
|
-
routing: {
|
|
1336
|
-
send: { type: 'body', property: 'cursor' },
|
|
1337
|
-
},
|
|
1338
|
+
default: ''
|
|
1338
1339
|
},
|
|
1339
1340
|
],
|
|
1340
1341
|
},
|
|
@@ -1354,10 +1355,7 @@ class Whaapy {
|
|
|
1354
1355
|
default: 'create',
|
|
1355
1356
|
displayOptions: {
|
|
1356
1357
|
show: { resource: ['contact'], operation: ['bulk'] },
|
|
1357
|
-
}
|
|
1358
|
-
routing: {
|
|
1359
|
-
send: { type: 'body', property: 'operation' },
|
|
1360
|
-
},
|
|
1358
|
+
}
|
|
1361
1359
|
},
|
|
1362
1360
|
{
|
|
1363
1361
|
displayName: 'Contacts Data',
|
|
@@ -1368,10 +1366,7 @@ class Whaapy {
|
|
|
1368
1366
|
description: 'Array of contacts or contact IDs',
|
|
1369
1367
|
displayOptions: {
|
|
1370
1368
|
show: { resource: ['contact'], operation: ['bulk'] },
|
|
1371
|
-
}
|
|
1372
|
-
routing: {
|
|
1373
|
-
send: { type: 'body', property: 'contacts' },
|
|
1374
|
-
},
|
|
1369
|
+
}
|
|
1375
1370
|
},
|
|
1376
1371
|
{
|
|
1377
1372
|
displayName: 'Operation Data',
|
|
@@ -1381,10 +1376,7 @@ class Whaapy {
|
|
|
1381
1376
|
description: 'Additional data for the operation',
|
|
1382
1377
|
displayOptions: {
|
|
1383
1378
|
show: { resource: ['contact'], operation: ['bulk'] },
|
|
1384
|
-
}
|
|
1385
|
-
routing: {
|
|
1386
|
-
send: { type: 'body', property: 'data' },
|
|
1387
|
-
},
|
|
1379
|
+
}
|
|
1388
1380
|
},
|
|
1389
1381
|
// Contact: Merge - Merge With ID
|
|
1390
1382
|
{
|
|
@@ -1396,10 +1388,7 @@ class Whaapy {
|
|
|
1396
1388
|
description: 'ID of the contact to merge into the primary contact',
|
|
1397
1389
|
displayOptions: {
|
|
1398
1390
|
show: { resource: ['contact'], operation: ['merge'] },
|
|
1399
|
-
}
|
|
1400
|
-
routing: {
|
|
1401
|
-
send: { type: 'body', property: 'mergeWith' },
|
|
1402
|
-
},
|
|
1391
|
+
}
|
|
1403
1392
|
},
|
|
1404
1393
|
// Contact: List - Filters
|
|
1405
1394
|
{
|
|
@@ -1416,38 +1405,26 @@ class Whaapy {
|
|
|
1416
1405
|
displayName: 'Search',
|
|
1417
1406
|
name: 'search',
|
|
1418
1407
|
type: 'string',
|
|
1419
|
-
default: ''
|
|
1420
|
-
routing: {
|
|
1421
|
-
send: { type: 'query', property: 'search' },
|
|
1422
|
-
},
|
|
1408
|
+
default: ''
|
|
1423
1409
|
},
|
|
1424
1410
|
{
|
|
1425
1411
|
displayName: 'Tags',
|
|
1426
1412
|
name: 'tags',
|
|
1427
1413
|
type: 'string',
|
|
1428
1414
|
default: '',
|
|
1429
|
-
description: 'Comma-separated list of tags'
|
|
1430
|
-
routing: {
|
|
1431
|
-
send: { type: 'query', property: 'tags' },
|
|
1432
|
-
},
|
|
1415
|
+
description: 'Comma-separated list of tags'
|
|
1433
1416
|
},
|
|
1434
1417
|
{
|
|
1435
1418
|
displayName: 'Funnel Stage ID',
|
|
1436
1419
|
name: 'funnelStageId',
|
|
1437
1420
|
type: 'string',
|
|
1438
|
-
default: ''
|
|
1439
|
-
routing: {
|
|
1440
|
-
send: { type: 'query', property: 'funnel_stage_id' },
|
|
1441
|
-
},
|
|
1421
|
+
default: ''
|
|
1442
1422
|
},
|
|
1443
1423
|
{
|
|
1444
1424
|
displayName: 'Source',
|
|
1445
1425
|
name: 'source',
|
|
1446
1426
|
type: 'string',
|
|
1447
|
-
default: ''
|
|
1448
|
-
routing: {
|
|
1449
|
-
send: { type: 'query', property: 'source' },
|
|
1450
|
-
},
|
|
1427
|
+
default: ''
|
|
1451
1428
|
},
|
|
1452
1429
|
{
|
|
1453
1430
|
displayName: 'Sort By',
|
|
@@ -1458,10 +1435,7 @@ class Whaapy {
|
|
|
1458
1435
|
{ name: 'Updated At', value: 'updated_at' },
|
|
1459
1436
|
{ name: 'Name', value: 'name' },
|
|
1460
1437
|
],
|
|
1461
|
-
default: 'created_at'
|
|
1462
|
-
routing: {
|
|
1463
|
-
send: { type: 'query', property: 'sort_by' },
|
|
1464
|
-
},
|
|
1438
|
+
default: 'created_at'
|
|
1465
1439
|
},
|
|
1466
1440
|
{
|
|
1467
1441
|
displayName: 'Sort Order',
|
|
@@ -1471,28 +1445,19 @@ class Whaapy {
|
|
|
1471
1445
|
{ name: 'Ascending', value: 'asc' },
|
|
1472
1446
|
{ name: 'Descending', value: 'desc' },
|
|
1473
1447
|
],
|
|
1474
|
-
default: 'desc'
|
|
1475
|
-
routing: {
|
|
1476
|
-
send: { type: 'query', property: 'sort_order' },
|
|
1477
|
-
},
|
|
1448
|
+
default: 'desc'
|
|
1478
1449
|
},
|
|
1479
1450
|
{
|
|
1480
1451
|
displayName: 'Limit',
|
|
1481
1452
|
name: 'limit',
|
|
1482
1453
|
type: 'number',
|
|
1483
|
-
default: 20
|
|
1484
|
-
routing: {
|
|
1485
|
-
send: { type: 'query', property: 'limit' },
|
|
1486
|
-
},
|
|
1454
|
+
default: 20
|
|
1487
1455
|
},
|
|
1488
1456
|
{
|
|
1489
1457
|
displayName: 'Cursor',
|
|
1490
1458
|
name: 'cursor',
|
|
1491
1459
|
type: 'string',
|
|
1492
|
-
default: ''
|
|
1493
|
-
routing: {
|
|
1494
|
-
send: { type: 'query', property: 'cursor' },
|
|
1495
|
-
},
|
|
1460
|
+
default: ''
|
|
1496
1461
|
},
|
|
1497
1462
|
],
|
|
1498
1463
|
},
|
|
@@ -1512,85 +1477,43 @@ class Whaapy {
|
|
|
1512
1477
|
name: 'List Stages',
|
|
1513
1478
|
value: 'listStages',
|
|
1514
1479
|
action: 'List funnel stages',
|
|
1515
|
-
description: 'Get all funnel stages'
|
|
1516
|
-
routing: {
|
|
1517
|
-
request: {
|
|
1518
|
-
method: 'GET',
|
|
1519
|
-
url: '/funnel/v1/stages',
|
|
1520
|
-
},
|
|
1521
|
-
},
|
|
1480
|
+
description: 'Get all funnel stages'
|
|
1522
1481
|
},
|
|
1523
1482
|
{
|
|
1524
1483
|
name: 'Get Stage',
|
|
1525
1484
|
value: 'getStage',
|
|
1526
1485
|
action: 'Get a funnel stage',
|
|
1527
1486
|
description: 'Get a specific funnel stage',
|
|
1528
|
-
routing: {
|
|
1529
|
-
request: {
|
|
1530
|
-
method: 'GET',
|
|
1531
|
-
url: '=/funnel/v1/stages/{{$parameter.stageId}}',
|
|
1532
|
-
},
|
|
1533
|
-
},
|
|
1534
1487
|
},
|
|
1535
1488
|
{
|
|
1536
1489
|
name: 'Create Stage',
|
|
1537
1490
|
value: 'createStage',
|
|
1538
1491
|
action: 'Create a funnel stage',
|
|
1539
|
-
description: 'Create a new funnel stage'
|
|
1540
|
-
routing: {
|
|
1541
|
-
request: {
|
|
1542
|
-
method: 'POST',
|
|
1543
|
-
url: '/funnel/v1/stages',
|
|
1544
|
-
},
|
|
1545
|
-
},
|
|
1492
|
+
description: 'Create a new funnel stage'
|
|
1546
1493
|
},
|
|
1547
1494
|
{
|
|
1548
1495
|
name: 'Update Stage',
|
|
1549
1496
|
value: 'updateStage',
|
|
1550
1497
|
action: 'Update a funnel stage',
|
|
1551
1498
|
description: 'Update an existing funnel stage',
|
|
1552
|
-
routing: {
|
|
1553
|
-
request: {
|
|
1554
|
-
method: 'PATCH',
|
|
1555
|
-
url: '=/funnel/v1/stages/{{$parameter.stageId}}',
|
|
1556
|
-
},
|
|
1557
|
-
},
|
|
1558
1499
|
},
|
|
1559
1500
|
{
|
|
1560
1501
|
name: 'Delete Stage',
|
|
1561
1502
|
value: 'deleteStage',
|
|
1562
1503
|
action: 'Delete a funnel stage',
|
|
1563
1504
|
description: 'Delete a funnel stage',
|
|
1564
|
-
routing: {
|
|
1565
|
-
request: {
|
|
1566
|
-
method: 'DELETE',
|
|
1567
|
-
url: '=/funnel/v1/stages/{{$parameter.stageId}}',
|
|
1568
|
-
},
|
|
1569
|
-
},
|
|
1570
1505
|
},
|
|
1571
1506
|
{
|
|
1572
1507
|
name: 'Reorder Stages',
|
|
1573
1508
|
value: 'reorderStages',
|
|
1574
1509
|
action: 'Reorder funnel stages',
|
|
1575
|
-
description: 'Reorder the funnel stages'
|
|
1576
|
-
routing: {
|
|
1577
|
-
request: {
|
|
1578
|
-
method: 'PATCH',
|
|
1579
|
-
url: '/funnel/v1/stages/reorder',
|
|
1580
|
-
},
|
|
1581
|
-
},
|
|
1510
|
+
description: 'Reorder the funnel stages'
|
|
1582
1511
|
},
|
|
1583
1512
|
{
|
|
1584
1513
|
name: 'Move Contact',
|
|
1585
1514
|
value: 'moveContact',
|
|
1586
1515
|
action: 'Move contact to stage',
|
|
1587
1516
|
description: 'Move a contact to a funnel stage',
|
|
1588
|
-
routing: {
|
|
1589
|
-
request: {
|
|
1590
|
-
method: 'POST',
|
|
1591
|
-
url: '=/funnel/v1/contacts/{{$parameter.contactIdFunnel}}/move',
|
|
1592
|
-
},
|
|
1593
|
-
},
|
|
1594
1517
|
},
|
|
1595
1518
|
],
|
|
1596
1519
|
default: 'listStages',
|
|
@@ -1618,10 +1541,7 @@ class Whaapy {
|
|
|
1618
1541
|
default: '',
|
|
1619
1542
|
displayOptions: {
|
|
1620
1543
|
show: { resource: ['funnel'], operation: ['createStage'] },
|
|
1621
|
-
}
|
|
1622
|
-
routing: {
|
|
1623
|
-
send: { type: 'body', property: 'name' },
|
|
1624
|
-
},
|
|
1544
|
+
}
|
|
1625
1545
|
},
|
|
1626
1546
|
{
|
|
1627
1547
|
displayName: 'Stage Options',
|
|
@@ -1637,29 +1557,20 @@ class Whaapy {
|
|
|
1637
1557
|
displayName: 'Position',
|
|
1638
1558
|
name: 'position',
|
|
1639
1559
|
type: 'number',
|
|
1640
|
-
default: 0
|
|
1641
|
-
routing: {
|
|
1642
|
-
send: { type: 'body', property: 'position' },
|
|
1643
|
-
},
|
|
1560
|
+
default: 0
|
|
1644
1561
|
},
|
|
1645
1562
|
{
|
|
1646
1563
|
displayName: 'Color',
|
|
1647
1564
|
name: 'color',
|
|
1648
1565
|
type: 'string',
|
|
1649
1566
|
default: '#3B82F6',
|
|
1650
|
-
description: 'Hex color code'
|
|
1651
|
-
routing: {
|
|
1652
|
-
send: { type: 'body', property: 'color' },
|
|
1653
|
-
},
|
|
1567
|
+
description: 'Hex color code'
|
|
1654
1568
|
},
|
|
1655
1569
|
{
|
|
1656
1570
|
displayName: 'Description',
|
|
1657
1571
|
name: 'description',
|
|
1658
1572
|
type: 'string',
|
|
1659
|
-
default: ''
|
|
1660
|
-
routing: {
|
|
1661
|
-
send: { type: 'body', property: 'description' },
|
|
1662
|
-
},
|
|
1573
|
+
default: ''
|
|
1663
1574
|
},
|
|
1664
1575
|
],
|
|
1665
1576
|
},
|
|
@@ -1678,37 +1589,25 @@ class Whaapy {
|
|
|
1678
1589
|
displayName: 'Name',
|
|
1679
1590
|
name: 'name',
|
|
1680
1591
|
type: 'string',
|
|
1681
|
-
default: ''
|
|
1682
|
-
routing: {
|
|
1683
|
-
send: { type: 'body', property: 'name' },
|
|
1684
|
-
},
|
|
1592
|
+
default: ''
|
|
1685
1593
|
},
|
|
1686
1594
|
{
|
|
1687
1595
|
displayName: 'Position',
|
|
1688
1596
|
name: 'position',
|
|
1689
1597
|
type: 'number',
|
|
1690
|
-
default: 0
|
|
1691
|
-
routing: {
|
|
1692
|
-
send: { type: 'body', property: 'position' },
|
|
1693
|
-
},
|
|
1598
|
+
default: 0
|
|
1694
1599
|
},
|
|
1695
1600
|
{
|
|
1696
1601
|
displayName: 'Color',
|
|
1697
1602
|
name: 'color',
|
|
1698
1603
|
type: 'string',
|
|
1699
|
-
default: ''
|
|
1700
|
-
routing: {
|
|
1701
|
-
send: { type: 'body', property: 'color' },
|
|
1702
|
-
},
|
|
1604
|
+
default: ''
|
|
1703
1605
|
},
|
|
1704
1606
|
{
|
|
1705
1607
|
displayName: 'Description',
|
|
1706
1608
|
name: 'description',
|
|
1707
1609
|
type: 'string',
|
|
1708
|
-
default: ''
|
|
1709
|
-
routing: {
|
|
1710
|
-
send: { type: 'body', property: 'description' },
|
|
1711
|
-
},
|
|
1610
|
+
default: ''
|
|
1712
1611
|
},
|
|
1713
1612
|
],
|
|
1714
1613
|
},
|
|
@@ -1722,10 +1621,7 @@ class Whaapy {
|
|
|
1722
1621
|
description: 'Array of objects with id and position',
|
|
1723
1622
|
displayOptions: {
|
|
1724
1623
|
show: { resource: ['funnel'], operation: ['reorderStages'] },
|
|
1725
|
-
}
|
|
1726
|
-
routing: {
|
|
1727
|
-
send: { type: 'body', property: 'stages' },
|
|
1728
|
-
},
|
|
1624
|
+
}
|
|
1729
1625
|
},
|
|
1730
1626
|
// Funnel: Move Contact - Fields
|
|
1731
1627
|
{
|
|
@@ -1746,10 +1642,7 @@ class Whaapy {
|
|
|
1746
1642
|
default: '',
|
|
1747
1643
|
displayOptions: {
|
|
1748
1644
|
show: { resource: ['funnel'], operation: ['moveContact'] },
|
|
1749
|
-
}
|
|
1750
|
-
routing: {
|
|
1751
|
-
send: { type: 'body', property: 'stageId' },
|
|
1752
|
-
},
|
|
1645
|
+
}
|
|
1753
1646
|
},
|
|
1754
1647
|
// Funnel: List Stages - Filters
|
|
1755
1648
|
{
|
|
@@ -1766,24 +1659,637 @@ class Whaapy {
|
|
|
1766
1659
|
displayName: 'Limit',
|
|
1767
1660
|
name: 'limit',
|
|
1768
1661
|
type: 'number',
|
|
1769
|
-
default: 20
|
|
1770
|
-
routing: {
|
|
1771
|
-
send: { type: 'query', property: 'limit' },
|
|
1772
|
-
},
|
|
1662
|
+
default: 20
|
|
1773
1663
|
},
|
|
1774
1664
|
{
|
|
1775
1665
|
displayName: 'Offset',
|
|
1776
1666
|
name: 'offset',
|
|
1777
1667
|
type: 'number',
|
|
1778
|
-
default: 0
|
|
1779
|
-
routing: {
|
|
1780
|
-
send: { type: 'query', property: 'offset' },
|
|
1781
|
-
},
|
|
1668
|
+
default: 0
|
|
1782
1669
|
},
|
|
1783
1670
|
],
|
|
1784
1671
|
},
|
|
1785
1672
|
],
|
|
1786
1673
|
};
|
|
1787
1674
|
}
|
|
1675
|
+
async execute() {
|
|
1676
|
+
const items = this.getInputData();
|
|
1677
|
+
const returnData = [];
|
|
1678
|
+
for (let i = 0; i < items.length; i++) {
|
|
1679
|
+
try {
|
|
1680
|
+
const resource = this.getNodeParameter('resource', i);
|
|
1681
|
+
const operation = this.getNodeParameter('operation', i);
|
|
1682
|
+
const credentials = await this.getCredentials('whaapyApi');
|
|
1683
|
+
const baseUrl = credentials.baseUrl;
|
|
1684
|
+
const apiKey = credentials.apiKey;
|
|
1685
|
+
let response;
|
|
1686
|
+
// ===========================================
|
|
1687
|
+
// MESSAGE RESOURCE
|
|
1688
|
+
// ===========================================
|
|
1689
|
+
if (resource === 'message') {
|
|
1690
|
+
if (operation === 'send') {
|
|
1691
|
+
const to = this.getNodeParameter('to', i);
|
|
1692
|
+
const messageType = this.getNodeParameter('messageType', i);
|
|
1693
|
+
const body = { to, type: messageType };
|
|
1694
|
+
// Handle different message types
|
|
1695
|
+
if (messageType === 'text') {
|
|
1696
|
+
body.content = this.getNodeParameter('textContent', i);
|
|
1697
|
+
}
|
|
1698
|
+
else if (['image', 'video', 'audio', 'document', 'sticker'].includes(messageType)) {
|
|
1699
|
+
const mediaUrl = this.getNodeParameter('mediaUrl', i);
|
|
1700
|
+
body[messageType] = { link: mediaUrl };
|
|
1701
|
+
if (['image', 'video', 'document'].includes(messageType)) {
|
|
1702
|
+
const caption = this.getNodeParameter('caption', i, '');
|
|
1703
|
+
if (caption)
|
|
1704
|
+
body[messageType].caption = caption;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
else if (messageType === 'template') {
|
|
1708
|
+
body.templateName = this.getNodeParameter('templateName', i);
|
|
1709
|
+
body.language = this.getNodeParameter('templateLanguage', i);
|
|
1710
|
+
const templateOptions = this.getNodeParameter('templateOptions', i, {});
|
|
1711
|
+
if (templateOptions.parameters) {
|
|
1712
|
+
body.template_parameters = templateOptions.parameters.split(',').map((v) => v.trim());
|
|
1713
|
+
}
|
|
1714
|
+
if (templateOptions.headerMediaType && templateOptions.headerMediaUrl) {
|
|
1715
|
+
body.header_media = {
|
|
1716
|
+
type: templateOptions.headerMediaType,
|
|
1717
|
+
url: templateOptions.headerMediaUrl,
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
else if (messageType === 'interactive') {
|
|
1722
|
+
// Build interactive message from structured fields
|
|
1723
|
+
const useRawJson = this.getNodeParameter('interactiveUseRawJson', i, false);
|
|
1724
|
+
if (useRawJson) {
|
|
1725
|
+
const rawJson = this.getNodeParameter('interactiveRawJson', i, '{}');
|
|
1726
|
+
body.interactive = typeof rawJson === 'string' ? JSON.parse(rawJson) : rawJson;
|
|
1727
|
+
}
|
|
1728
|
+
else {
|
|
1729
|
+
const interactiveType = this.getNodeParameter('interactiveType', i);
|
|
1730
|
+
const bodyText = this.getNodeParameter('interactiveBodyText', i);
|
|
1731
|
+
const headerType = this.getNodeParameter('interactiveHeaderType', i, 'none');
|
|
1732
|
+
const headerText = this.getNodeParameter('interactiveHeaderText', i, '');
|
|
1733
|
+
const headerMediaUrl = this.getNodeParameter('interactiveHeaderMediaUrl', i, '');
|
|
1734
|
+
const footerText = this.getNodeParameter('interactiveFooterText', i, '');
|
|
1735
|
+
// Build buttons array
|
|
1736
|
+
let buttons = [];
|
|
1737
|
+
if (interactiveType === 'button') {
|
|
1738
|
+
const buttonsData = this.getNodeParameter('interactiveButtons', i, { buttonValues: [] });
|
|
1739
|
+
buttons = buttonsData.buttonValues || [];
|
|
1740
|
+
}
|
|
1741
|
+
// Build sections array
|
|
1742
|
+
let sections = [];
|
|
1743
|
+
let listButtonText = '';
|
|
1744
|
+
if (interactiveType === 'list') {
|
|
1745
|
+
listButtonText = this.getNodeParameter('interactiveListButtonText', i, 'Ver Opciones');
|
|
1746
|
+
const sectionsData = this.getNodeParameter('interactiveSections', i, { sectionValues: [] });
|
|
1747
|
+
if (sectionsData.sectionValues) {
|
|
1748
|
+
sections = sectionsData.sectionValues.map((section) => {
|
|
1749
|
+
var _a;
|
|
1750
|
+
return ({
|
|
1751
|
+
title: section.title,
|
|
1752
|
+
rows: ((_a = section.rows) === null || _a === void 0 ? void 0 : _a.rowValues) || [],
|
|
1753
|
+
});
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
body.interactive = buildInteractivePayload({
|
|
1758
|
+
interactiveType,
|
|
1759
|
+
bodyText,
|
|
1760
|
+
headerType,
|
|
1761
|
+
headerText,
|
|
1762
|
+
headerMediaUrl,
|
|
1763
|
+
footerText,
|
|
1764
|
+
buttons,
|
|
1765
|
+
listButtonText,
|
|
1766
|
+
sections,
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
else if (messageType === 'location') {
|
|
1771
|
+
body.location = {
|
|
1772
|
+
latitude: this.getNodeParameter('latitude', i),
|
|
1773
|
+
longitude: this.getNodeParameter('longitude', i),
|
|
1774
|
+
name: this.getNodeParameter('locationName', i, '') || undefined,
|
|
1775
|
+
};
|
|
1776
|
+
}
|
|
1777
|
+
else if (messageType === 'contacts') {
|
|
1778
|
+
const contactsData = this.getNodeParameter('contactsData', i);
|
|
1779
|
+
body.contacts = typeof contactsData === 'string' ? JSON.parse(contactsData) : contactsData;
|
|
1780
|
+
}
|
|
1781
|
+
else if (messageType === 'reaction') {
|
|
1782
|
+
body.reaction = {
|
|
1783
|
+
message_id: this.getNodeParameter('reactionMessageId', i),
|
|
1784
|
+
emoji: this.getNodeParameter('reactionEmoji', i),
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
// Add additional fields
|
|
1788
|
+
const additionalFields = this.getNodeParameter('additionalFields', i, {});
|
|
1789
|
+
if (additionalFields.pauseAi) {
|
|
1790
|
+
body.ai = body.ai || {};
|
|
1791
|
+
body.ai.pause = additionalFields.pauseAi;
|
|
1792
|
+
}
|
|
1793
|
+
if (additionalFields.pauseDuration) {
|
|
1794
|
+
body.ai = body.ai || {};
|
|
1795
|
+
body.ai.pauseDuration = additionalFields.pauseDuration;
|
|
1796
|
+
}
|
|
1797
|
+
if (additionalFields.disableAi) {
|
|
1798
|
+
body.ai = body.ai || {};
|
|
1799
|
+
body.ai.disable = additionalFields.disableAi;
|
|
1800
|
+
}
|
|
1801
|
+
if (additionalFields.replyTo) {
|
|
1802
|
+
body.context = { message_id: additionalFields.replyTo };
|
|
1803
|
+
}
|
|
1804
|
+
if (additionalFields.createConversation !== undefined) {
|
|
1805
|
+
body.createConversation = additionalFields.createConversation;
|
|
1806
|
+
}
|
|
1807
|
+
if (additionalFields.metadata) {
|
|
1808
|
+
body.metadata = typeof additionalFields.metadata === 'string'
|
|
1809
|
+
? JSON.parse(additionalFields.metadata)
|
|
1810
|
+
: additionalFields.metadata;
|
|
1811
|
+
}
|
|
1812
|
+
response = await this.helpers.request({
|
|
1813
|
+
method: 'POST',
|
|
1814
|
+
url: `${baseUrl}/messages/v1`,
|
|
1815
|
+
headers: {
|
|
1816
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
1817
|
+
'Content-Type': 'application/json',
|
|
1818
|
+
},
|
|
1819
|
+
body,
|
|
1820
|
+
json: true,
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
else if (operation === 'retry') {
|
|
1824
|
+
const messageId = this.getNodeParameter('messageId', i);
|
|
1825
|
+
response = await this.helpers.request({
|
|
1826
|
+
method: 'POST',
|
|
1827
|
+
url: `${baseUrl}/messages/v1/${messageId}/retry`,
|
|
1828
|
+
headers: {
|
|
1829
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
1830
|
+
'Content-Type': 'application/json',
|
|
1831
|
+
},
|
|
1832
|
+
json: true,
|
|
1833
|
+
});
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
// ===========================================
|
|
1837
|
+
// CONVERSATION RESOURCE
|
|
1838
|
+
// ===========================================
|
|
1839
|
+
else if (resource === 'conversation') {
|
|
1840
|
+
if (operation === 'list') {
|
|
1841
|
+
const filters = this.getNodeParameter('conversationFilters', i, {});
|
|
1842
|
+
const qs = {};
|
|
1843
|
+
if (filters.search)
|
|
1844
|
+
qs.search = filters.search;
|
|
1845
|
+
if (filters.status && filters.status !== 'all')
|
|
1846
|
+
qs.status = filters.status;
|
|
1847
|
+
if (filters.limit)
|
|
1848
|
+
qs.limit = filters.limit;
|
|
1849
|
+
if (filters.offset)
|
|
1850
|
+
qs.offset = filters.offset;
|
|
1851
|
+
response = await this.helpers.request({
|
|
1852
|
+
method: 'GET',
|
|
1853
|
+
url: `${baseUrl}/conversations/v1`,
|
|
1854
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1855
|
+
qs,
|
|
1856
|
+
json: true,
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
else if (operation === 'get') {
|
|
1860
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1861
|
+
response = await this.helpers.request({
|
|
1862
|
+
method: 'GET',
|
|
1863
|
+
url: `${baseUrl}/conversations/v1/${conversationId}`,
|
|
1864
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1865
|
+
json: true,
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1868
|
+
else if (operation === 'getByPhone') {
|
|
1869
|
+
const phoneNumber = this.getNodeParameter('phoneNumber', i);
|
|
1870
|
+
response = await this.helpers.request({
|
|
1871
|
+
method: 'GET',
|
|
1872
|
+
url: `${baseUrl}/conversations/v1/by-phone/${encodeURIComponent(phoneNumber)}`,
|
|
1873
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1874
|
+
json: true,
|
|
1875
|
+
});
|
|
1876
|
+
}
|
|
1877
|
+
else if (operation === 'getMessages') {
|
|
1878
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1879
|
+
const options = this.getNodeParameter('messagesOptions', i, {});
|
|
1880
|
+
const qs = {};
|
|
1881
|
+
if (options.limit)
|
|
1882
|
+
qs.limit = options.limit;
|
|
1883
|
+
if (options.cursor)
|
|
1884
|
+
qs.cursor = options.cursor;
|
|
1885
|
+
response = await this.helpers.request({
|
|
1886
|
+
method: 'GET',
|
|
1887
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/messages`,
|
|
1888
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1889
|
+
qs,
|
|
1890
|
+
json: true,
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
else if (operation === 'close') {
|
|
1894
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1895
|
+
response = await this.helpers.request({
|
|
1896
|
+
method: 'POST',
|
|
1897
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/close`,
|
|
1898
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1899
|
+
json: true,
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
else if (operation === 'archive') {
|
|
1903
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1904
|
+
response = await this.helpers.request({
|
|
1905
|
+
method: 'POST',
|
|
1906
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/archive`,
|
|
1907
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1908
|
+
json: true,
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
else if (operation === 'markRead') {
|
|
1912
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1913
|
+
response = await this.helpers.request({
|
|
1914
|
+
method: 'PATCH',
|
|
1915
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/mark-read`,
|
|
1916
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1917
|
+
json: true,
|
|
1918
|
+
});
|
|
1919
|
+
}
|
|
1920
|
+
else if (operation === 'setAi') {
|
|
1921
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1922
|
+
const aiEnabled = this.getNodeParameter('aiEnabled', i);
|
|
1923
|
+
response = await this.helpers.request({
|
|
1924
|
+
method: 'PATCH',
|
|
1925
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/ai`,
|
|
1926
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
1927
|
+
body: { aiEnabled },
|
|
1928
|
+
json: true,
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
else if (operation === 'pauseAi') {
|
|
1932
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1933
|
+
const duration = this.getNodeParameter('pauseDurationConv', i);
|
|
1934
|
+
response = await this.helpers.request({
|
|
1935
|
+
method: 'POST',
|
|
1936
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/ai/pause`,
|
|
1937
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
1938
|
+
body: { duration },
|
|
1939
|
+
json: true,
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
else if (operation === 'aiSuggest') {
|
|
1943
|
+
const conversationId = this.getNodeParameter('conversationId', i);
|
|
1944
|
+
response = await this.helpers.request({
|
|
1945
|
+
method: 'POST',
|
|
1946
|
+
url: `${baseUrl}/conversations/v1/${conversationId}/ai-suggest`,
|
|
1947
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1948
|
+
json: true,
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
// ===========================================
|
|
1953
|
+
// AGENT RESOURCE
|
|
1954
|
+
// ===========================================
|
|
1955
|
+
else if (resource === 'agent') {
|
|
1956
|
+
if (operation === 'toggle') {
|
|
1957
|
+
const enabled = this.getNodeParameter('agentEnabled', i);
|
|
1958
|
+
response = await this.helpers.request({
|
|
1959
|
+
method: 'POST',
|
|
1960
|
+
url: `${baseUrl}/agent/v1/toggle`,
|
|
1961
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
1962
|
+
body: { enabled },
|
|
1963
|
+
json: true,
|
|
1964
|
+
});
|
|
1965
|
+
}
|
|
1966
|
+
else if (operation === 'pause') {
|
|
1967
|
+
const duration = this.getNodeParameter('agentPauseDuration', i);
|
|
1968
|
+
response = await this.helpers.request({
|
|
1969
|
+
method: 'POST',
|
|
1970
|
+
url: `${baseUrl}/agent/v1/pause`,
|
|
1971
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
1972
|
+
body: { duration },
|
|
1973
|
+
json: true,
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
// ===========================================
|
|
1978
|
+
// TEMPLATE RESOURCE
|
|
1979
|
+
// ===========================================
|
|
1980
|
+
else if (resource === 'template') {
|
|
1981
|
+
if (operation === 'list') {
|
|
1982
|
+
const filters = this.getNodeParameter('templateFilters', i, {});
|
|
1983
|
+
const qs = {};
|
|
1984
|
+
if (filters.status)
|
|
1985
|
+
qs.status = filters.status;
|
|
1986
|
+
if (filters.limit)
|
|
1987
|
+
qs.limit = filters.limit;
|
|
1988
|
+
if (filters.offset)
|
|
1989
|
+
qs.offset = filters.offset;
|
|
1990
|
+
response = await this.helpers.request({
|
|
1991
|
+
method: 'GET',
|
|
1992
|
+
url: `${baseUrl}/templates/v1`,
|
|
1993
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
1994
|
+
qs,
|
|
1995
|
+
json: true,
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
else if (operation === 'get') {
|
|
1999
|
+
const templateId = this.getNodeParameter('templateId', i);
|
|
2000
|
+
response = await this.helpers.request({
|
|
2001
|
+
method: 'GET',
|
|
2002
|
+
url: `${baseUrl}/templates/v1/${templateId}`,
|
|
2003
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2004
|
+
json: true,
|
|
2005
|
+
});
|
|
2006
|
+
}
|
|
2007
|
+
else if (operation === 'getVariables') {
|
|
2008
|
+
response = await this.helpers.request({
|
|
2009
|
+
method: 'GET',
|
|
2010
|
+
url: `${baseUrl}/templates/v1/variables`,
|
|
2011
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2012
|
+
json: true,
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
else if (operation === 'sync') {
|
|
2016
|
+
response = await this.helpers.request({
|
|
2017
|
+
method: 'POST',
|
|
2018
|
+
url: `${baseUrl}/templates/v1/sync`,
|
|
2019
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2020
|
+
json: true,
|
|
2021
|
+
});
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
// ===========================================
|
|
2025
|
+
// MEDIA RESOURCE
|
|
2026
|
+
// ===========================================
|
|
2027
|
+
else if (resource === 'media') {
|
|
2028
|
+
if (operation === 'upload') {
|
|
2029
|
+
// Media upload requires special handling with binary data
|
|
2030
|
+
const mediaType = this.getNodeParameter('mediaType', i);
|
|
2031
|
+
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i);
|
|
2032
|
+
// For now, just return an error - binary upload needs special handling
|
|
2033
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Media upload from n8n requires binary data handling. Use the HTTP Request node with binary data or upload via URL.', { itemIndex: i });
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
// ===========================================
|
|
2037
|
+
// CONTACT RESOURCE
|
|
2038
|
+
// ===========================================
|
|
2039
|
+
else if (resource === 'contact') {
|
|
2040
|
+
if (operation === 'list') {
|
|
2041
|
+
const filters = this.getNodeParameter('contactFilters', i, {});
|
|
2042
|
+
const qs = {};
|
|
2043
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
2044
|
+
if (value !== undefined && value !== '') {
|
|
2045
|
+
qs[key === 'sortBy' ? 'sort_by' : key === 'sortOrder' ? 'sort_order' : key === 'funnelStageId' ? 'funnel_stage_id' : key] = value;
|
|
2046
|
+
}
|
|
2047
|
+
});
|
|
2048
|
+
response = await this.helpers.request({
|
|
2049
|
+
method: 'GET',
|
|
2050
|
+
url: `${baseUrl}/contacts/v1`,
|
|
2051
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2052
|
+
qs,
|
|
2053
|
+
json: true,
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2056
|
+
else if (operation === 'get') {
|
|
2057
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
2058
|
+
response = await this.helpers.request({
|
|
2059
|
+
method: 'GET',
|
|
2060
|
+
url: `${baseUrl}/contacts/v1/${contactId}`,
|
|
2061
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2062
|
+
json: true,
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
else if (operation === 'create') {
|
|
2066
|
+
const name = this.getNodeParameter('contactName', i);
|
|
2067
|
+
const phoneNumber = this.getNodeParameter('contactPhone', i);
|
|
2068
|
+
const additional = this.getNodeParameter('contactAdditional', i, {});
|
|
2069
|
+
const body = { name, phoneNumber };
|
|
2070
|
+
if (additional.email)
|
|
2071
|
+
body.email = additional.email;
|
|
2072
|
+
if (additional.tags)
|
|
2073
|
+
body.tags = additional.tags;
|
|
2074
|
+
if (additional.customFields) {
|
|
2075
|
+
body.customFields = typeof additional.customFields === 'string'
|
|
2076
|
+
? JSON.parse(additional.customFields)
|
|
2077
|
+
: additional.customFields;
|
|
2078
|
+
}
|
|
2079
|
+
if (additional.metadata) {
|
|
2080
|
+
body.metadata = typeof additional.metadata === 'string'
|
|
2081
|
+
? JSON.parse(additional.metadata)
|
|
2082
|
+
: additional.metadata;
|
|
2083
|
+
}
|
|
2084
|
+
response = await this.helpers.request({
|
|
2085
|
+
method: 'POST',
|
|
2086
|
+
url: `${baseUrl}/contacts/v1`,
|
|
2087
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2088
|
+
body,
|
|
2089
|
+
json: true,
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
else if (operation === 'update') {
|
|
2093
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
2094
|
+
const updateFields = this.getNodeParameter('contactUpdateFields', i, {});
|
|
2095
|
+
const body = {};
|
|
2096
|
+
Object.entries(updateFields).forEach(([key, value]) => {
|
|
2097
|
+
if (value !== undefined && value !== '') {
|
|
2098
|
+
if (key === 'customFields') {
|
|
2099
|
+
body[key] = typeof value === 'string' ? JSON.parse(value) : value;
|
|
2100
|
+
}
|
|
2101
|
+
else {
|
|
2102
|
+
body[key] = value;
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
});
|
|
2106
|
+
response = await this.helpers.request({
|
|
2107
|
+
method: 'PATCH',
|
|
2108
|
+
url: `${baseUrl}/contacts/v1/${contactId}`,
|
|
2109
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2110
|
+
body,
|
|
2111
|
+
json: true,
|
|
2112
|
+
});
|
|
2113
|
+
}
|
|
2114
|
+
else if (operation === 'delete') {
|
|
2115
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
2116
|
+
response = await this.helpers.request({
|
|
2117
|
+
method: 'DELETE',
|
|
2118
|
+
url: `${baseUrl}/contacts/v1/${contactId}`,
|
|
2119
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2120
|
+
json: true,
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
else if (operation === 'search') {
|
|
2124
|
+
const query = this.getNodeParameter('searchQuery', i);
|
|
2125
|
+
const options = this.getNodeParameter('searchOptions', i, {});
|
|
2126
|
+
const body = { query };
|
|
2127
|
+
if (options.filters) {
|
|
2128
|
+
body.filters = typeof options.filters === 'string' ? JSON.parse(options.filters) : options.filters;
|
|
2129
|
+
}
|
|
2130
|
+
if (options.limit)
|
|
2131
|
+
body.limit = options.limit;
|
|
2132
|
+
if (options.cursor)
|
|
2133
|
+
body.cursor = options.cursor;
|
|
2134
|
+
response = await this.helpers.request({
|
|
2135
|
+
method: 'POST',
|
|
2136
|
+
url: `${baseUrl}/contacts/v1/search`,
|
|
2137
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2138
|
+
body,
|
|
2139
|
+
json: true,
|
|
2140
|
+
});
|
|
2141
|
+
}
|
|
2142
|
+
else if (operation === 'bulk') {
|
|
2143
|
+
const bulkOperation = this.getNodeParameter('bulkOperation', i);
|
|
2144
|
+
const contacts = this.getNodeParameter('bulkContacts', i);
|
|
2145
|
+
const data = this.getNodeParameter('bulkData', i, '{}');
|
|
2146
|
+
response = await this.helpers.request({
|
|
2147
|
+
method: 'POST',
|
|
2148
|
+
url: `${baseUrl}/contacts/v1/bulk`,
|
|
2149
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2150
|
+
body: {
|
|
2151
|
+
operation: bulkOperation,
|
|
2152
|
+
contacts: typeof contacts === 'string' ? JSON.parse(contacts) : contacts,
|
|
2153
|
+
data: typeof data === 'string' ? JSON.parse(data) : data,
|
|
2154
|
+
},
|
|
2155
|
+
json: true,
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
else if (operation === 'merge') {
|
|
2159
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
2160
|
+
const mergeWith = this.getNodeParameter('mergeWithId', i);
|
|
2161
|
+
response = await this.helpers.request({
|
|
2162
|
+
method: 'POST',
|
|
2163
|
+
url: `${baseUrl}/contacts/v1/${contactId}/merge`,
|
|
2164
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2165
|
+
body: { mergeWith },
|
|
2166
|
+
json: true,
|
|
2167
|
+
});
|
|
2168
|
+
}
|
|
2169
|
+
else if (operation === 'getTags') {
|
|
2170
|
+
response = await this.helpers.request({
|
|
2171
|
+
method: 'GET',
|
|
2172
|
+
url: `${baseUrl}/contacts/v1/tags`,
|
|
2173
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2174
|
+
json: true,
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
else if (operation === 'getFields') {
|
|
2178
|
+
response = await this.helpers.request({
|
|
2179
|
+
method: 'GET',
|
|
2180
|
+
url: `${baseUrl}/contacts/v1/fields`,
|
|
2181
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2182
|
+
json: true,
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
// ===========================================
|
|
2187
|
+
// FUNNEL RESOURCE
|
|
2188
|
+
// ===========================================
|
|
2189
|
+
else if (resource === 'funnel') {
|
|
2190
|
+
if (operation === 'listStages') {
|
|
2191
|
+
const options = this.getNodeParameter('stageListOptions', i, {});
|
|
2192
|
+
const qs = {};
|
|
2193
|
+
if (options.limit)
|
|
2194
|
+
qs.limit = options.limit;
|
|
2195
|
+
if (options.offset)
|
|
2196
|
+
qs.offset = options.offset;
|
|
2197
|
+
response = await this.helpers.request({
|
|
2198
|
+
method: 'GET',
|
|
2199
|
+
url: `${baseUrl}/funnel/v1/stages`,
|
|
2200
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2201
|
+
qs,
|
|
2202
|
+
json: true,
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
else if (operation === 'getStage') {
|
|
2206
|
+
const stageId = this.getNodeParameter('stageId', i);
|
|
2207
|
+
response = await this.helpers.request({
|
|
2208
|
+
method: 'GET',
|
|
2209
|
+
url: `${baseUrl}/funnel/v1/stages/${stageId}`,
|
|
2210
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2211
|
+
json: true,
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2214
|
+
else if (operation === 'createStage') {
|
|
2215
|
+
const name = this.getNodeParameter('stageName', i);
|
|
2216
|
+
const options = this.getNodeParameter('stageOptions', i, {});
|
|
2217
|
+
const body = { name };
|
|
2218
|
+
if (options.position !== undefined)
|
|
2219
|
+
body.position = options.position;
|
|
2220
|
+
if (options.color)
|
|
2221
|
+
body.color = options.color;
|
|
2222
|
+
if (options.description)
|
|
2223
|
+
body.description = options.description;
|
|
2224
|
+
response = await this.helpers.request({
|
|
2225
|
+
method: 'POST',
|
|
2226
|
+
url: `${baseUrl}/funnel/v1/stages`,
|
|
2227
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2228
|
+
body,
|
|
2229
|
+
json: true,
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
else if (operation === 'updateStage') {
|
|
2233
|
+
const stageId = this.getNodeParameter('stageId', i);
|
|
2234
|
+
const updateFields = this.getNodeParameter('stageUpdateFields', i, {});
|
|
2235
|
+
const body = {};
|
|
2236
|
+
Object.entries(updateFields).forEach(([key, value]) => {
|
|
2237
|
+
if (value !== undefined && value !== '') {
|
|
2238
|
+
body[key] = value;
|
|
2239
|
+
}
|
|
2240
|
+
});
|
|
2241
|
+
response = await this.helpers.request({
|
|
2242
|
+
method: 'PATCH',
|
|
2243
|
+
url: `${baseUrl}/funnel/v1/stages/${stageId}`,
|
|
2244
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2245
|
+
body,
|
|
2246
|
+
json: true,
|
|
2247
|
+
});
|
|
2248
|
+
}
|
|
2249
|
+
else if (operation === 'deleteStage') {
|
|
2250
|
+
const stageId = this.getNodeParameter('stageId', i);
|
|
2251
|
+
response = await this.helpers.request({
|
|
2252
|
+
method: 'DELETE',
|
|
2253
|
+
url: `${baseUrl}/funnel/v1/stages/${stageId}`,
|
|
2254
|
+
headers: { 'Authorization': `Bearer ${apiKey}` },
|
|
2255
|
+
json: true,
|
|
2256
|
+
});
|
|
2257
|
+
}
|
|
2258
|
+
else if (operation === 'reorderStages') {
|
|
2259
|
+
const stages = this.getNodeParameter('stagesOrder', i);
|
|
2260
|
+
response = await this.helpers.request({
|
|
2261
|
+
method: 'PATCH',
|
|
2262
|
+
url: `${baseUrl}/funnel/v1/stages/reorder`,
|
|
2263
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2264
|
+
body: { stages: typeof stages === 'string' ? JSON.parse(stages) : stages },
|
|
2265
|
+
json: true,
|
|
2266
|
+
});
|
|
2267
|
+
}
|
|
2268
|
+
else if (operation === 'moveContact') {
|
|
2269
|
+
const contactId = this.getNodeParameter('contactIdFunnel', i);
|
|
2270
|
+
const stageId = this.getNodeParameter('targetStageId', i);
|
|
2271
|
+
response = await this.helpers.request({
|
|
2272
|
+
method: 'POST',
|
|
2273
|
+
url: `${baseUrl}/funnel/v1/contacts/${contactId}/move`,
|
|
2274
|
+
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
|
|
2275
|
+
body: { stageId },
|
|
2276
|
+
json: true,
|
|
2277
|
+
});
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
if (response) {
|
|
2281
|
+
returnData.push({ json: response });
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
catch (error) {
|
|
2285
|
+
if (this.continueOnFail()) {
|
|
2286
|
+
returnData.push({ json: { error: error.message } });
|
|
2287
|
+
continue;
|
|
2288
|
+
}
|
|
2289
|
+
throw error;
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
return [returnData];
|
|
2293
|
+
}
|
|
1788
2294
|
}
|
|
1789
2295
|
exports.Whaapy = Whaapy;
|