n8n-nodes-manfuservers-wasap-api 1.1.0 → 1.1.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.
- package/CHANGELOG.md +4 -1
- package/README.md +1 -1
- package/dist/nodes/ManfuserversWasap/ManfuserversWasapTrigger.node.d.ts +6 -1
- package/dist/nodes/ManfuserversWasap/ManfuserversWasapTrigger.node.js +46 -12
- package/package.json +2 -3
- package/dist/nodes/ManfuserversWasap/ManfuserversWasapChatTrigger.node.d.ts +0 -17
- package/dist/nodes/ManfuserversWasap/ManfuserversWasapChatTrigger.node.js +0 -111
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog — n8n-nodes-manfuservers-wasap-api
|
|
2
2
|
|
|
3
|
+
## 1.1.1 — un solo trigger
|
|
4
|
+
Sustituye a la 1.1.0 publicada, que tenía dos triggers. El trigger único cubre todos los chats o un chat concreto, con sentido de mensaje (recibidos, enviados o ambos).
|
|
5
|
+
|
|
3
6
|
## 1.0.1 — URL por defecto
|
|
4
7
|
- La credencial Manfuservers Wasap API trae por defecto https://manfuservers.com:9000.
|
|
5
8
|
|
|
@@ -7,7 +10,7 @@
|
|
|
7
10
|
Sustituye al paquete `n8n-nodes-manfuservers-wasap-api` (versión 1.0.0), que queda pendiente de deprecar.
|
|
8
11
|
- Credencial **Manfuservers Wasap API**: URL del servidor + API key de cliente, con prueba de conexión.
|
|
9
12
|
- Nodo **Manfuservers Wasap**: texto, respuesta, imagen, vídeo, audio, nota de voz, documento, descarga multimedia, contactos, grupos, estado de sesión y mensajes.
|
|
10
|
-
- Nodo **Manfuservers Wasap Trigger
|
|
13
|
+
- Nodo **Manfuservers Wasap Trigger** (único trigger): todos los chats o un chat concreto; recibidos, enviados desde el teléfono o ambos. Mensajes, imagen, audio, nota de voz, vídeo, documento, grupos y estado de sesión mediante webhook firmado (HMAC-SHA256). Entrega al menos una vez: deduplicar por `messageId`.
|
|
11
14
|
- Remitente con nombre y número cuando están disponibles.
|
|
12
15
|
- Protección de la cuenta incluida en el servidor (espaciado, escritura simulada, topes por hora y día).
|
|
13
16
|
- Icono propio de Manfuservers.
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
## Nodos
|
|
16
16
|
- **Manfuservers Wasap**: enviar texto, responder, enviar imagen/vídeo/audio/nota de voz/documento, descargar multimedia, buscar y obtener contactos, listar grupos, estado de la sesión y obtener mensajes.
|
|
17
|
-
- **Manfuservers Wasap Trigger**: recibe mensajes
|
|
17
|
+
- **Manfuservers Wasap Trigger**: recibe mensajes. Elige *Todos los chats* o *Un chat concreto* (contacto, grupo o número), y el sentido: solo recibidos, solo los que envías tú (también desde tu teléfono), o todos.
|
|
18
18
|
|
|
19
19
|
Cada evento de entrada incluye el nombre del remitente y su número cuando WhatsApp lo permite.
|
|
20
20
|
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type { INodeType, INodeTypeDescription, IHookFunctions, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
|
|
1
|
+
import type { INodeType, INodeTypeDescription, IHookFunctions, IWebhookFunctions, IWebhookResponseData, ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';
|
|
2
2
|
export declare class ManfuserversWasapTrigger implements INodeType {
|
|
3
3
|
description: INodeTypeDescription;
|
|
4
|
+
methods: {
|
|
5
|
+
listSearch: {
|
|
6
|
+
searchChats(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
4
9
|
webhookMethods: {
|
|
5
10
|
default: {
|
|
6
11
|
checkExists(this: IHookFunctions): Promise<boolean>;
|
|
@@ -2,24 +2,47 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ManfuserversWasapTrigger = void 0;
|
|
4
4
|
const helpers_1 = require("./helpers");
|
|
5
|
+
// Un único trigger: todos los chats o un chat concreto; recibidos, enviados desde tu teléfono o ambos.
|
|
5
6
|
class ManfuserversWasapTrigger {
|
|
6
7
|
description = {
|
|
7
8
|
displayName: 'Manfuservers Wasap Trigger', name: 'manfuserversWasapTrigger', icon: 'file:manfuservers-wasap.svg', group: ['trigger'], version: 1,
|
|
8
|
-
description: 'Recibe mensajes
|
|
9
|
+
description: 'Recibe mensajes de todos tus chats o de uno concreto, también los que escribes desde tu teléfono',
|
|
9
10
|
defaults: { name: 'Manfuservers Wasap Trigger' }, inputs: [], outputs: ['main'],
|
|
10
11
|
credentials: [{ name: 'manfuserversWasapApi', required: true }],
|
|
11
12
|
webhooks: [{ name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'wasap' }],
|
|
12
13
|
properties: [
|
|
14
|
+
{ displayName: 'Escuchar', name: 'scope', type: 'options', default: 'all', options: [
|
|
15
|
+
{ name: 'Todos los chats', value: 'all' },
|
|
16
|
+
{ name: 'Un chat concreto', value: 'chat' }
|
|
17
|
+
] },
|
|
18
|
+
{ displayName: 'Tipo de chat', name: 'chatType', type: 'options', default: 'contact', options: [
|
|
19
|
+
{ name: 'Contacto', value: 'contact' }, { name: 'Grupo', value: 'group' }, { name: 'Número internacional', value: 'phone' }
|
|
20
|
+
],
|
|
21
|
+
displayOptions: { show: { scope: ['chat'] } } },
|
|
22
|
+
{ displayName: 'Chat', name: 'chat', type: 'resourceLocator', default: { mode: 'list', value: '' }, required: true,
|
|
23
|
+
modes: [{ displayName: 'Buscar por nombre o número', name: 'list', type: 'list', typeOptions: { searchListMethod: 'searchChats', searchable: true } }],
|
|
24
|
+
displayOptions: { show: { scope: ['chat'], chatType: ['contact', 'group'] } } },
|
|
25
|
+
{ displayName: 'Número internacional', name: 'phone', type: 'string', default: '', placeholder: '+34600000000', required: true,
|
|
26
|
+
description: 'Incluye el país. El servidor verifica el número antes de escuchar el chat', displayOptions: { show: { scope: ['chat'], chatType: ['phone'] } } },
|
|
27
|
+
{ displayName: 'Mensajes', name: 'direction', type: 'options', default: 'in', options: [
|
|
28
|
+
{ name: 'Solo los que recibo', value: 'in' },
|
|
29
|
+
{ name: 'Solo los que envío yo (desde mi teléfono)', value: 'out' },
|
|
30
|
+
{ name: 'Todos (recibidos y enviados)', value: 'all' }
|
|
31
|
+
],
|
|
32
|
+
description: 'Los enviados incluyen los que escribes desde tu teléfono' },
|
|
13
33
|
{ displayName: 'Eventos', name: 'events', type: 'multiOptions', required: true, default: ['message'], options: [
|
|
14
34
|
{ name: 'Cualquier mensaje', value: 'message' }, { name: 'Imagen', value: 'image' }, { name: 'Audio', value: 'audio' },
|
|
15
35
|
{ name: 'Nota de voz', value: 'voice' }, { name: 'Vídeo', value: 'video' }, { name: 'Documento', value: 'document' },
|
|
16
|
-
{ name: 'Cualquier multimedia', value: 'media' }, { name: 'Mensaje en grupo', value: 'group' }, { name: 'Estado de sesión', value: 'session.status' }
|
|
36
|
+
{ name: 'Cualquier multimedia', value: 'media' }, { name: 'Mensaje en grupo', value: 'group' }, { name: 'Estado de sesión (solo todos los chats)', value: 'session.status' }
|
|
17
37
|
] },
|
|
18
|
-
{ displayName: '
|
|
19
|
-
{ displayName: 'Incluir mensajes propios', name: 'includeOwn', type: 'boolean', default: false, description: 'Puede provocar bucles de respuestas. Desactivado por defecto' },
|
|
20
|
-
{ displayName: 'El administrador debe conectar los webhooks nativos y permitir el origen URL de n8n. Activar este workflow registra solo su suscripción; no reemplaza las demás.', name: 'notice', type: 'notice', default: '' },
|
|
38
|
+
{ displayName: 'Datos raw saneados', name: 'raw', type: 'boolean', default: false, description: 'Requiere permiso raw de la clave. Añade datos técnicos saneados' },
|
|
21
39
|
],
|
|
22
40
|
};
|
|
41
|
+
methods = { listSearch: { async searchChats(filter, paginationToken) {
|
|
42
|
+
const type = this.getNodeParameter('chatType');
|
|
43
|
+
const result = await (0, helpers_1.api)(this, 'GET', `/v1/${type === 'group' ? 'groups' : 'contacts'}?search=${encodeURIComponent(filter || '')}&limit=50&offset=${Number(paginationToken || 0)}`);
|
|
44
|
+
return { results: result.items.map((r) => ({ name: r.label, value: r.id })), ...(result.nextOffset !== null ? { paginationToken: String(result.nextOffset) } : {}) };
|
|
45
|
+
} } };
|
|
23
46
|
webhookMethods = { default: {
|
|
24
47
|
async checkExists() {
|
|
25
48
|
const data = this.getWorkflowStaticData('node');
|
|
@@ -36,11 +59,26 @@ class ManfuserversWasapTrigger {
|
|
|
36
59
|
const callback = this.getNodeWebhookUrl('default');
|
|
37
60
|
if (!callback)
|
|
38
61
|
throw new Error('Guarda el workflow para obtener su URL de webhook');
|
|
62
|
+
let chatId = null;
|
|
63
|
+
if (this.getNodeParameter('scope') === 'chat') {
|
|
64
|
+
const type = this.getNodeParameter('chatType');
|
|
65
|
+
if (type === 'phone') {
|
|
66
|
+
const verified = await (0, helpers_1.api)(this, 'POST', '/v1/resolve-number', { phone: (0, helpers_1.manualPhone)(this.getNodeParameter('phone')) });
|
|
67
|
+
chatId = verified.chatId;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
chatId = this.getNodeParameter('chat').value;
|
|
71
|
+
}
|
|
72
|
+
if (!chatId)
|
|
73
|
+
throw new Error('Selecciona el chat que quieres escuchar');
|
|
74
|
+
}
|
|
75
|
+
const direction = this.getNodeParameter('direction');
|
|
39
76
|
const credentials = await this.getCredentials('manfuserversWasapApi');
|
|
40
77
|
const secret = (0, helpers_1.hookSecret)(String(credentials.apiKey), String(this.getWorkflow().id || 'new'), this.getNode().id);
|
|
41
78
|
const result = await (0, helpers_1.api)(this, 'POST', '/v1/subscriptions', {
|
|
42
79
|
workflow: String(this.getWorkflow().id || 'new') + ':' + this.getNode().id, callback, secret,
|
|
43
|
-
events: this.getNodeParameter('events'), raw: this.getNodeParameter('raw'),
|
|
80
|
+
events: this.getNodeParameter('events'), raw: this.getNodeParameter('raw'),
|
|
81
|
+
includeOwn: direction !== 'in', chatId, direction,
|
|
44
82
|
});
|
|
45
83
|
this.getWorkflowStaticData('node').subscriptionId = result.id;
|
|
46
84
|
return true;
|
|
@@ -52,7 +90,7 @@ class ManfuserversWasapTrigger {
|
|
|
52
90
|
await (0, helpers_1.api)(this, 'DELETE', '/v1/subscriptions/' + data.subscriptionId);
|
|
53
91
|
}
|
|
54
92
|
catch {
|
|
55
|
-
//
|
|
93
|
+
// Una clave revocada no puede borrar; el servidor ya deja de entregar eventos.
|
|
56
94
|
}
|
|
57
95
|
}
|
|
58
96
|
delete data.subscriptionId;
|
|
@@ -68,10 +106,6 @@ class ManfuserversWasapTrigger {
|
|
|
68
106
|
const signature = String(request.headers['x-manfuservers-signature'] || '');
|
|
69
107
|
const body = this.getBodyData();
|
|
70
108
|
const message = (0, helpers_1.decodeEnvelope)(body, signature, secret);
|
|
71
|
-
if (message.fromMe && !this.getNodeParameter('includeOwn')) {
|
|
72
|
-
response.status(200).json({ accepted: true, filtered: true });
|
|
73
|
-
return { noWebhookResponse: true };
|
|
74
|
-
}
|
|
75
109
|
const state = this.getWorkflowStaticData('node');
|
|
76
110
|
const previous = Array.isArray(state.deliveryIds) ? state.deliveryIds : [];
|
|
77
111
|
if (previous.includes(String(body.deliveryId))) {
|
|
@@ -83,7 +117,7 @@ class ManfuserversWasapTrigger {
|
|
|
83
117
|
return { noWebhookResponse: true, workflowData: [this.helpers.returnJsonArray(message)] };
|
|
84
118
|
}
|
|
85
119
|
catch {
|
|
86
|
-
response.status(401).json({ error: 'Firma o evento
|
|
120
|
+
response.status(401).json({ error: 'Firma o evento no válido' });
|
|
87
121
|
return { noWebhookResponse: true };
|
|
88
122
|
}
|
|
89
123
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-manfuservers-wasap-api",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Manfuservers Wasap: WhatsApp para n8n: mensajes, multimedia, contactos, grupos, eventos y escucha de chats",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -32,8 +32,7 @@
|
|
|
32
32
|
],
|
|
33
33
|
"nodes": [
|
|
34
34
|
"dist/nodes/ManfuserversWasap/ManfuserversWasap.node.js",
|
|
35
|
-
"dist/nodes/ManfuserversWasap/ManfuserversWasapTrigger.node.js"
|
|
36
|
-
"dist/nodes/ManfuserversWasap/ManfuserversWasapChatTrigger.node.js"
|
|
35
|
+
"dist/nodes/ManfuserversWasap/ManfuserversWasapTrigger.node.js"
|
|
37
36
|
]
|
|
38
37
|
},
|
|
39
38
|
"devDependencies": {
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { INodeType, INodeTypeDescription, IHookFunctions, IWebhookFunctions, IWebhookResponseData, ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';
|
|
2
|
-
export declare class ManfuserversWasapChatTrigger implements INodeType {
|
|
3
|
-
description: INodeTypeDescription;
|
|
4
|
-
methods: {
|
|
5
|
-
listSearch: {
|
|
6
|
-
searchChats(this: ILoadOptionsFunctions, filter?: string, paginationToken?: string): Promise<INodeListSearchResult>;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
webhookMethods: {
|
|
10
|
-
default: {
|
|
11
|
-
checkExists(this: IHookFunctions): Promise<boolean>;
|
|
12
|
-
create(this: IHookFunctions): Promise<boolean>;
|
|
13
|
-
delete(this: IHookFunctions): Promise<boolean>;
|
|
14
|
-
};
|
|
15
|
-
};
|
|
16
|
-
webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
|
|
17
|
-
}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ManfuserversWasapChatTrigger = void 0;
|
|
4
|
-
const helpers_1 = require("./helpers");
|
|
5
|
-
// Dispara con cada mensaje nuevo de UN chat: recibido o enviado desde tu teléfono.
|
|
6
|
-
class ManfuserversWasapChatTrigger {
|
|
7
|
-
description = {
|
|
8
|
-
displayName: 'Manfuservers Wasap: Mensaje en chat', name: 'manfuserversWasapChatTrigger', icon: 'file:manfuservers-wasap.svg', group: ['trigger'], version: 1,
|
|
9
|
-
description: 'Se dispara con cada mensaje nuevo de un chat concreto, también los que escribes desde tu teléfono',
|
|
10
|
-
defaults: { name: 'Mensaje en chat' }, inputs: [], outputs: ['main'],
|
|
11
|
-
credentials: [{ name: 'manfuserversWasapApi', required: true }],
|
|
12
|
-
webhooks: [{ name: 'default', httpMethod: 'POST', responseMode: 'onReceived', path: 'wasap-chat' }],
|
|
13
|
-
properties: [
|
|
14
|
-
{ displayName: 'Tipo de chat', name: 'chatType', type: 'options', default: 'contact', options: [
|
|
15
|
-
{ name: 'Contacto', value: 'contact' }, { name: 'Grupo', value: 'group' }, { name: 'Número internacional', value: 'phone' }
|
|
16
|
-
] },
|
|
17
|
-
{ displayName: 'Chat', name: 'chat', type: 'resourceLocator', default: { mode: 'list', value: '' }, required: true,
|
|
18
|
-
modes: [{ displayName: 'Buscar por nombre o número', name: 'list', type: 'list', typeOptions: { searchListMethod: 'searchChats', searchable: true } }],
|
|
19
|
-
displayOptions: { show: { chatType: ['contact', 'group'] } } },
|
|
20
|
-
{ displayName: 'Número internacional', name: 'phone', type: 'string', default: '', placeholder: '+34600000000', required: true,
|
|
21
|
-
description: 'Incluye el país. El servidor verifica el número antes de escuchar el chat', displayOptions: { show: { chatType: ['phone'] } } },
|
|
22
|
-
{ displayName: 'Mensajes a escuchar', name: 'direction', type: 'options', default: 'all', options: [
|
|
23
|
-
{ name: 'Todos (recibidos y enviados)', value: 'all' },
|
|
24
|
-
{ name: 'Solo los que envío yo (desde mi teléfono)', value: 'out' },
|
|
25
|
-
{ name: 'Solo los que recibo', value: 'in' }
|
|
26
|
-
] },
|
|
27
|
-
{ displayName: 'Datos raw saneados', name: 'raw', type: 'boolean', default: false, description: 'Requiere permiso raw de la clave. Añade datos técnicos saneados' },
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
methods = { listSearch: { async searchChats(filter, paginationToken) {
|
|
31
|
-
const type = this.getNodeParameter('chatType');
|
|
32
|
-
const result = await (0, helpers_1.api)(this, 'GET', `/v1/${type === 'group' ? 'groups' : 'contacts'}?search=${encodeURIComponent(filter || '')}&limit=50&offset=${Number(paginationToken || 0)}`);
|
|
33
|
-
return { results: result.items.map((r) => ({ name: r.label, value: r.id })), ...(result.nextOffset !== null ? { paginationToken: String(result.nextOffset) } : {}) };
|
|
34
|
-
} } };
|
|
35
|
-
webhookMethods = { default: {
|
|
36
|
-
async checkExists() {
|
|
37
|
-
const data = this.getWorkflowStaticData('node');
|
|
38
|
-
if (!data.subscriptionId)
|
|
39
|
-
return false;
|
|
40
|
-
try {
|
|
41
|
-
return (await (0, helpers_1.api)(this, 'GET', '/v1/subscriptions/' + data.subscriptionId)).active === true;
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
async create() {
|
|
48
|
-
const callback = this.getNodeWebhookUrl('default');
|
|
49
|
-
if (!callback)
|
|
50
|
-
throw new Error('Guarda el workflow para obtener su URL de webhook');
|
|
51
|
-
const type = this.getNodeParameter('chatType');
|
|
52
|
-
let chat;
|
|
53
|
-
if (type === 'phone') {
|
|
54
|
-
const verified = await (0, helpers_1.api)(this, 'POST', '/v1/resolve-number', { phone: (0, helpers_1.manualPhone)(this.getNodeParameter('phone')) });
|
|
55
|
-
chat = verified.chatId;
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
chat = this.getNodeParameter('chat').value;
|
|
59
|
-
}
|
|
60
|
-
if (!chat)
|
|
61
|
-
throw new Error('Selecciona el chat que quieres escuchar');
|
|
62
|
-
const credentials = await this.getCredentials('manfuserversWasapApi');
|
|
63
|
-
const secret = (0, helpers_1.hookSecret)(String(credentials.apiKey), String(this.getWorkflow().id || 'new'), this.getNode().id);
|
|
64
|
-
const result = await (0, helpers_1.api)(this, 'POST', '/v1/subscriptions', {
|
|
65
|
-
workflow: String(this.getWorkflow().id || 'new') + ':' + this.getNode().id, callback, secret,
|
|
66
|
-
events: ['message'], raw: this.getNodeParameter('raw'), includeOwn: true,
|
|
67
|
-
chatId: chat, direction: this.getNodeParameter('direction'),
|
|
68
|
-
});
|
|
69
|
-
this.getWorkflowStaticData('node').subscriptionId = result.id;
|
|
70
|
-
return true;
|
|
71
|
-
},
|
|
72
|
-
async delete() {
|
|
73
|
-
const data = this.getWorkflowStaticData('node');
|
|
74
|
-
if (data.subscriptionId) {
|
|
75
|
-
try {
|
|
76
|
-
await (0, helpers_1.api)(this, 'DELETE', '/v1/subscriptions/' + data.subscriptionId);
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
// Una clave revocada no puede borrar; el servidor ya deja de entregar eventos.
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
delete data.subscriptionId;
|
|
83
|
-
return true;
|
|
84
|
-
},
|
|
85
|
-
} };
|
|
86
|
-
async webhook() {
|
|
87
|
-
const response = this.getResponseObject();
|
|
88
|
-
try {
|
|
89
|
-
const credentials = await this.getCredentials('manfuserversWasapApi');
|
|
90
|
-
const secret = (0, helpers_1.hookSecret)(String(credentials.apiKey), String(this.getWorkflow().id || 'new'), this.getNode().id);
|
|
91
|
-
const request = this.getRequestObject();
|
|
92
|
-
const signature = String(request.headers['x-manfuservers-signature'] || '');
|
|
93
|
-
const body = this.getBodyData();
|
|
94
|
-
const message = (0, helpers_1.decodeEnvelope)(body, signature, secret);
|
|
95
|
-
const state = this.getWorkflowStaticData('node');
|
|
96
|
-
const previous = Array.isArray(state.deliveryIds) ? state.deliveryIds : [];
|
|
97
|
-
if (previous.includes(String(body.deliveryId))) {
|
|
98
|
-
response.status(200).json({ accepted: true, duplicate: true });
|
|
99
|
-
return { noWebhookResponse: true };
|
|
100
|
-
}
|
|
101
|
-
state.deliveryIds = [...previous, String(body.deliveryId)].slice(-500);
|
|
102
|
-
response.status(200).json({ accepted: true });
|
|
103
|
-
return { noWebhookResponse: true, workflowData: [this.helpers.returnJsonArray(message)] };
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
response.status(401).json({ error: 'Firma o evento no válido' });
|
|
107
|
-
return { noWebhookResponse: true };
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
exports.ManfuserversWasapChatTrigger = ManfuserversWasapChatTrigger;
|