n8n-nodes-wuzapi
Version:
n8n community nodes for Wuzapi - WhatsApp Multi-Device REST API
353 lines • 12.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSendAndWaitProperties = getSendAndWaitProperties;
exports.sendAndWaitWebhook = sendAndWaitWebhook;
exports.getSendAndWaitConfig = getSendAndWaitConfig;
exports.createWhatsAppMessage = createWhatsAppMessage;
const isbotUtils_1 = require("../../isbotUtils");
const n8n_workflow_1 = require("n8n-workflow");
const descriptions_1 = require("./descriptions");
const message_templates_1 = require("./message-templates");
const utils_1 = require("../../../nodes/Form/utils");
const utilities_1 = require("../../utilities");
const INPUT_FIELD_IDENTIFIER = 'field-0';
const limitWaitTimeOption = {
displayName: 'Limit Wait Time',
name: 'limitWaitTime',
type: 'fixedCollection',
description: 'Whether the workflow will automatically resume execution after the specified limit type',
default: { values: { limitType: 'afterTimeInterval', resumeAmount: 45, resumeUnit: 'minutes' } },
options: [
{
displayName: 'Values',
name: 'values',
values: descriptions_1.limitWaitTimeProperties,
},
],
};
const appendAttributionOption = {
displayName: 'Append n8n Attribution',
name: 'appendAttribution',
type: 'boolean',
default: true,
description: 'Whether to include the phrase "This message was sent automatically with n8n" to the end of the message',
};
// Operation Properties ----------------------------------------------------------
function getSendAndWaitProperties(targetProperties, resource = 'sendAndWait', additionalProperties = [], options) {
const approvalOptionsValues = [
{
displayName: 'Type of Approval',
name: 'approvalType',
type: 'options',
placeholder: 'Add option',
default: 'single',
options: [
{
name: 'Approve Only',
value: 'single',
},
{
name: 'Approve and Disapprove',
value: 'double',
},
],
},
{
displayName: 'Approve Button Label',
name: 'approveLabel',
type: 'string',
default: options?.defaultApproveLabel || 'Approve',
displayOptions: {
show: {
approvalType: ['single', 'double'],
},
},
},
{
displayName: 'Disapprove Button Label',
name: 'disapproveLabel',
type: 'string',
default: options?.defaultDisapproveLabel || 'Decline',
displayOptions: {
show: {
approvalType: ['double'],
},
},
},
];
const sendAndWait = [
...targetProperties,
{
displayName: 'Phone Number',
name: 'phone',
type: 'string',
default: '',
placeholder: 'e.g. 5491155553934',
description: 'Phone number to send the message to',
required: true,
},
{
displayName: 'Message',
name: 'message',
type: 'string',
default: '',
required: true,
typeOptions: {
rows: 4,
},
},
{
displayName: 'Response Type',
name: 'responseType',
type: 'options',
default: 'approval',
options: [
{
name: 'Approval',
value: 'approval',
description: 'User can approve/disapprove via buttons in WhatsApp',
},
{
name: 'Free Text',
value: 'freeText',
description: 'User can submit a response via a form',
},
{
name: 'Custom Form',
value: 'customForm',
description: 'User can submit a response via a custom form',
},
],
},
{
displayName: 'Approval Options',
name: 'approvalOptions',
type: 'fixedCollection',
placeholder: 'Add option',
default: {},
options: [
{
displayName: 'Values',
name: 'values',
values: approvalOptionsValues,
},
],
displayOptions: {
show: {
responseType: ['approval'],
},
},
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add option',
default: {},
options: [limitWaitTimeOption, appendAttributionOption],
displayOptions: {
show: {
responseType: ['approval'],
},
},
},
{
displayName: 'Options',
name: 'options',
type: 'collection',
placeholder: 'Add option',
default: {},
options: [
{
displayName: 'Message Button Label',
name: 'messageButtonLabel',
type: 'string',
default: 'Respond',
},
{
displayName: 'Response Form Title',
name: 'responseFormTitle',
description: 'Title of the form that the user can access to provide their response',
type: 'string',
default: '',
},
{
displayName: 'Response Form Description',
name: 'responseFormDescription',
description: 'Description of the form that the user can access to provide their response',
type: 'string',
default: '',
},
{
displayName: 'Response Form Button Label',
name: 'responseFormButtonLabel',
type: 'string',
default: 'Submit',
},
limitWaitTimeOption,
appendAttributionOption,
],
displayOptions: {
show: {
responseType: ['freeText', 'customForm'],
},
},
},
...additionalProperties,
];
return (0, n8n_workflow_1.updateDisplayOptions)({
show: {
resource: [resource],
operation: [n8n_workflow_1.SEND_AND_WAIT_OPERATION],
},
}, sendAndWait);
}
// Webhook Function --------------------------------------------------------------
const getFormResponseCustomizations = (context) => {
const message = context.getNodeParameter('message', '');
const options = context.getNodeParameter('options', {});
let formTitle = '';
if (options.responseFormTitle) {
formTitle = options.responseFormTitle;
}
let formDescription = message;
if (options.responseFormDescription) {
formDescription = options.responseFormDescription;
}
formDescription = formDescription.replace(/\\n/g, '\n').replace(/<br>/g, '\n');
let buttonLabel = 'Submit';
if (options.responseFormButtonLabel) {
buttonLabel = options.responseFormButtonLabel;
}
return {
formTitle,
formDescription,
buttonLabel,
};
};
async function sendAndWaitWebhook() {
const method = this.getRequestObject().method;
const res = this.getResponseObject();
const req = this.getRequestObject();
const responseType = this.getNodeParameter('responseType', 'approval');
if (responseType === 'approval' && (0, isbotUtils_1.isBot)(req.headers['user-agent'])) {
res.send('');
return { noWebhookResponse: true };
}
if (responseType === 'freeText') {
if (method === 'GET') {
const { formTitle, formDescription, buttonLabel } = getFormResponseCustomizations(this);
const data = (0, utils_1.prepareFormData)({
formTitle,
formDescription,
formSubmittedHeader: 'Got it, thanks',
formSubmittedText: 'This page can be closed now',
buttonLabel,
redirectUrl: undefined,
formFields: [
{
fieldLabel: 'Response',
fieldType: 'textarea',
requiredField: true,
},
],
testRun: false,
query: {},
});
res.render('form-trigger', data);
return {
noWebhookResponse: true,
};
}
if (method === 'POST') {
const data = this.getBodyData().data;
return {
webhookResponse: message_templates_1.ACTION_RECORDED_PAGE,
workflowData: [[{ json: { data: { text: data[INPUT_FIELD_IDENTIFIER] } } }]],
};
}
}
if (responseType === 'customForm') {
// Handle custom form responses
// This would need to be implemented based on Wuzapi's webhook handling
}
const query = req.query;
const approved = query.approved === 'true';
return {
webhookResponse: message_templates_1.ACTION_RECORDED_PAGE,
workflowData: [[{ json: { data: { approved } } }]],
};
}
// Send and Wait Config -----------------------------------------------------------
function getSendAndWaitConfig(context) {
const message = (0, utilities_1.escapeHtml)(context.getNodeParameter('message', 0, '').trim())
.replace(/\\n/g, '\n')
.replace(/<br>/g, '\n');
const resumeUrl = context.evaluateExpression('{{ $execution?.resumeUrl }}', 0);
const nodeId = context.evaluateExpression('{{ $nodeId }}', 0);
const approvalOptions = context.getNodeParameter('approvalOptions.values', 0, {});
const options = context.getNodeParameter('options', 0, {});
const config = {
title: 'Approval Required',
message,
url: `${resumeUrl}/${nodeId}`,
options: [],
appendAttribution: options?.appendAttribution,
};
const responseType = context.getNodeParameter('responseType', 0, 'approval');
if (responseType === 'freeText' || responseType === 'customForm') {
const label = context.getNodeParameter('options.messageButtonLabel', 0, 'Respond');
config.options.push({
label,
value: 'true',
style: 'primary',
});
}
else if (approvalOptions.approvalType === 'double') {
const approveLabel = (0, utilities_1.escapeHtml)(approvalOptions.approveLabel || 'Approve');
const disapproveLabel = (0, utilities_1.escapeHtml)(approvalOptions.disapproveLabel || 'Disapprove');
config.options.push({
label: disapproveLabel,
value: 'false',
style: 'secondary',
});
config.options.push({
label: approveLabel,
value: 'true',
style: 'primary',
});
}
else {
const label = (0, utilities_1.escapeHtml)(approvalOptions.approveLabel || 'Approve');
config.options.push({
label,
value: 'true',
style: 'primary',
});
}
return config;
}
function createWhatsAppMessage(context, phone, instanceId) {
const config = getSendAndWaitConfig(context);
const responseType = context.getNodeParameter('responseType', 0, 'approval');
if (responseType === 'approval') {
// For approval type, we'll use template message with buttons
const { content, footer, buttons } = (0, message_templates_1.createWhatsAppTemplateMessage)(config.message, config.options, config.appendAttribution !== false ? instanceId : undefined);
return {
phone,
body: content,
buttons,
};
}
else {
// For other types, we'll use a simple text message with the webhook URL
const messageText = config.appendAttribution !== false
? `${config.message}\n\nClick here to respond: ${config.url}\n\nThis message was sent automatically with n8n`
: `${config.message}\n\nClick here to respond: ${config.url}`;
return {
phone,
body: messageText,
};
}
}
//# sourceMappingURL=utils.js.map