@webzzconnect/n8n-nodes-webzzconnect 0.0.0-stage → 0.5.0
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/LICENSE +21 -0
- package/README.md +141 -2
- package/dist/credentials/WebzzConnectApi.credentials.d.ts +10 -0
- package/dist/credentials/WebzzConnectApi.credentials.js +52 -0
- package/dist/credentials/WebzzConnectApi.credentials.js.map +1 -0
- package/dist/credentials/WebzzConnectOAuth2Api.credentials.d.ts +9 -0
- package/dist/credentials/WebzzConnectOAuth2Api.credentials.js +82 -0
- package/dist/credentials/WebzzConnectOAuth2Api.credentials.js.map +1 -0
- package/dist/nodes/WebzzConnect/GenericFunctions.d.ts +54 -0
- package/dist/nodes/WebzzConnect/GenericFunctions.js +295 -0
- package/dist/nodes/WebzzConnect/GenericFunctions.js.map +1 -0
- package/dist/nodes/WebzzConnect/WebzzConnect.node.d.ts +20 -0
- package/dist/nodes/WebzzConnect/WebzzConnect.node.js +845 -0
- package/dist/nodes/WebzzConnect/WebzzConnect.node.js.map +1 -0
- package/dist/nodes/WebzzConnect/WebzzConnect.node.json +12 -0
- package/dist/nodes/WebzzConnect/descriptions/ConnectionDescription.d.ts +2 -0
- package/dist/nodes/WebzzConnect/descriptions/ConnectionDescription.js +22 -0
- package/dist/nodes/WebzzConnect/descriptions/ConnectionDescription.js.map +1 -0
- package/dist/nodes/WebzzConnect/descriptions/ContactDescription.d.ts +3 -0
- package/dist/nodes/WebzzConnect/descriptions/ContactDescription.js +185 -0
- package/dist/nodes/WebzzConnect/descriptions/ContactDescription.js.map +1 -0
- package/dist/nodes/WebzzConnect/descriptions/ConversationDescription.d.ts +4 -0
- package/dist/nodes/WebzzConnect/descriptions/ConversationDescription.js +522 -0
- package/dist/nodes/WebzzConnect/descriptions/ConversationDescription.js.map +1 -0
- package/dist/nodes/WebzzConnect/descriptions/DealDescription.d.ts +3 -0
- package/dist/nodes/WebzzConnect/descriptions/DealDescription.js +282 -0
- package/dist/nodes/WebzzConnect/descriptions/DealDescription.js.map +1 -0
- package/dist/nodes/WebzzConnect/descriptions/WhatsAppTemplateDescription.d.ts +3 -0
- package/dist/nodes/WebzzConnect/descriptions/WhatsAppTemplateDescription.js +106 -0
- package/dist/nodes/WebzzConnect/descriptions/WhatsAppTemplateDescription.js.map +1 -0
- package/dist/nodes/WebzzConnect/webzzconnect.dark.svg +19 -0
- package/dist/nodes/WebzzConnect/webzzconnect.svg +19 -0
- package/dist/nodes/WebzzConnectTrigger/WebzzConnectTrigger.node.d.ts +18 -0
- package/dist/nodes/WebzzConnectTrigger/WebzzConnectTrigger.node.js +321 -0
- package/dist/nodes/WebzzConnectTrigger/WebzzConnectTrigger.node.js.map +1 -0
- package/dist/nodes/WebzzConnectTrigger/WebzzConnectTrigger.node.json +12 -0
- package/dist/nodes/WebzzConnectTrigger/webzzconnect.dark.svg +19 -0
- package/dist/nodes/WebzzConnectTrigger/webzzconnect.svg +19 -0
- package/dist/package.json +64 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +62 -4
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebzzConnect = void 0;
|
|
4
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
5
|
+
const ContactDescription_1 = require("./descriptions/ContactDescription");
|
|
6
|
+
const ConversationDescription_1 = require("./descriptions/ConversationDescription");
|
|
7
|
+
const DealDescription_1 = require("./descriptions/DealDescription");
|
|
8
|
+
const WhatsAppTemplateDescription_1 = require("./descriptions/WhatsAppTemplateDescription");
|
|
9
|
+
const ConnectionDescription_1 = require("./descriptions/ConnectionDescription");
|
|
10
|
+
const GenericFunctions_1 = require("./GenericFunctions");
|
|
11
|
+
function compact(values) {
|
|
12
|
+
const out = {};
|
|
13
|
+
for (const [key, value] of Object.entries(values)) {
|
|
14
|
+
if (value === undefined || value === null || value === '')
|
|
15
|
+
continue;
|
|
16
|
+
out[key] = value;
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function contactBody(fields) {
|
|
21
|
+
const body = compact({
|
|
22
|
+
name: fields.name,
|
|
23
|
+
email: fields.email,
|
|
24
|
+
phone_number: fields.phoneNumber,
|
|
25
|
+
identifier: fields.identifier,
|
|
26
|
+
});
|
|
27
|
+
const additional = compact({
|
|
28
|
+
city: fields.city,
|
|
29
|
+
company_name: fields.companyName,
|
|
30
|
+
country: fields.country,
|
|
31
|
+
});
|
|
32
|
+
if (Object.keys(additional).length > 0)
|
|
33
|
+
body.additional_attributes = additional;
|
|
34
|
+
const custom = (0, GenericFunctions_1.pairsToObject)(fields.customAttributes);
|
|
35
|
+
if (Object.keys(custom).length > 0)
|
|
36
|
+
body.custom_attributes = custom;
|
|
37
|
+
return body;
|
|
38
|
+
}
|
|
39
|
+
function dealBody(fields) {
|
|
40
|
+
const body = compact({
|
|
41
|
+
title: fields.title,
|
|
42
|
+
value: fields.value === 0 ? 0 : fields.value,
|
|
43
|
+
currency: fields.currency,
|
|
44
|
+
owner_id: fields.ownerId,
|
|
45
|
+
expected_close_at: fields.expectedCloseAt,
|
|
46
|
+
});
|
|
47
|
+
const custom = (0, GenericFunctions_1.pairsToObject)(fields.customAttributes);
|
|
48
|
+
if (Object.keys(custom).length > 0)
|
|
49
|
+
body.custom_attributes = custom;
|
|
50
|
+
return body;
|
|
51
|
+
}
|
|
52
|
+
async function findContact(email, phone) {
|
|
53
|
+
const search = async (q) => {
|
|
54
|
+
const response = await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/contacts/search', { qs: { q } });
|
|
55
|
+
return (0, GenericFunctions_1.asArray)(response);
|
|
56
|
+
};
|
|
57
|
+
if (email) {
|
|
58
|
+
const match = (await search(email)).find((contact) => { var _a; return String((_a = contact.email) !== null && _a !== void 0 ? _a : '').toLowerCase() === email.toLowerCase(); });
|
|
59
|
+
if (match)
|
|
60
|
+
return match;
|
|
61
|
+
}
|
|
62
|
+
if (phone) {
|
|
63
|
+
const national = (0, GenericFunctions_1.digitsOnly)(phone).replace(/^0+/, '');
|
|
64
|
+
const queries = [...new Set([phone, national].filter((q) => q.length > 0))];
|
|
65
|
+
for (const q of queries) {
|
|
66
|
+
const match = (await search(q)).find((contact) => { var _a; return (0, GenericFunctions_1.phonesMatch)(String((_a = contact.phone_number) !== null && _a !== void 0 ? _a : ''), phone); });
|
|
67
|
+
if (match)
|
|
68
|
+
return match;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
async function createOrUpdateContact(i) {
|
|
74
|
+
const email = this.getNodeParameter('email', i, '').trim();
|
|
75
|
+
const phone = this.getNodeParameter('phoneNumber', i, '').trim();
|
|
76
|
+
if (!email && !phone) {
|
|
77
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Provide an email or a phone number to find the contact', { itemIndex: i });
|
|
78
|
+
}
|
|
79
|
+
const fields = {
|
|
80
|
+
name: this.getNodeParameter('name', i, ''),
|
|
81
|
+
email,
|
|
82
|
+
phoneNumber: phone,
|
|
83
|
+
...this.getNodeParameter('additionalFields', i, {}),
|
|
84
|
+
};
|
|
85
|
+
const body = contactBody(fields);
|
|
86
|
+
const update = async (match) => {
|
|
87
|
+
var _a;
|
|
88
|
+
const patch = { ...body };
|
|
89
|
+
if (phone && (0, GenericFunctions_1.phonesMatch)(String((_a = match.phone_number) !== null && _a !== void 0 ? _a : ''), phone))
|
|
90
|
+
delete patch.phone_number;
|
|
91
|
+
return (0, GenericFunctions_1.unwrapContact)(await GenericFunctions_1.wzApiRequest.call(this, 'PATCH', `/contacts/${GenericFunctions_1.pathId.call(this, match.id)}`, {
|
|
92
|
+
body: patch,
|
|
93
|
+
}));
|
|
94
|
+
};
|
|
95
|
+
const existing = await findContact.call(this, email, phone);
|
|
96
|
+
if (existing)
|
|
97
|
+
return await update(existing);
|
|
98
|
+
try {
|
|
99
|
+
const created = await GenericFunctions_1.wzRawRequest.call(this, 'POST', '/contacts', { body });
|
|
100
|
+
return (0, GenericFunctions_1.unwrapContact)(created);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if ((0, GenericFunctions_1.readErrorInfo)(error).status === 422) {
|
|
104
|
+
const retry = await findContact.call(this, email, phone);
|
|
105
|
+
if (retry)
|
|
106
|
+
return await update(retry);
|
|
107
|
+
if ((await GenericFunctions_1.getConnectionInfo.call(this)).kind === 'agent') {
|
|
108
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), GenericFunctions_1.COPY.contactNotVisible);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return GenericFunctions_1.handleApiError.call(this, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function fetchInboxes() {
|
|
115
|
+
return (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/inboxes'));
|
|
116
|
+
}
|
|
117
|
+
async function readBack(id) {
|
|
118
|
+
try {
|
|
119
|
+
return (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzRawRequest.call(this, 'GET', `/conversations/${id}`));
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if ((0, GenericFunctions_1.readErrorInfo)(error).status === 404)
|
|
123
|
+
return undefined;
|
|
124
|
+
return GenericFunctions_1.handleApiError.call(this, error);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function assignConversation(i) {
|
|
128
|
+
var _a, _b, _c, _d, _e;
|
|
129
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
130
|
+
const assignee = GenericFunctions_1.parseAssignee.call(this, this.getNodeParameter('agentId', i, ''));
|
|
131
|
+
const teamId = String((_a = this.getNodeParameter('teamId', i, '')) !== null && _a !== void 0 ? _a : '').trim();
|
|
132
|
+
const note = String((_b = this.getNodeParameter('handoffNote', i, '')) !== null && _b !== void 0 ? _b : '');
|
|
133
|
+
if (!assignee && !teamId) {
|
|
134
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), GenericFunctions_1.COPY.assignNoTarget, { itemIndex: i });
|
|
135
|
+
}
|
|
136
|
+
if (assignee && teamId) {
|
|
137
|
+
const { kind } = await GenericFunctions_1.getConnectionInfo.call(this);
|
|
138
|
+
if (!kind) {
|
|
139
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), GenericFunctions_1.COPY.connectionKindUnknown, { itemIndex: i });
|
|
140
|
+
}
|
|
141
|
+
if (kind === 'agent') {
|
|
142
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), GenericFunctions_1.COPY.handoffOneTarget, { itemIndex: i });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
let team;
|
|
146
|
+
if (teamId) {
|
|
147
|
+
const body = { team_id: Number(GenericFunctions_1.pathId.call(this, teamId)) };
|
|
148
|
+
if (note)
|
|
149
|
+
body.handoff_note = note;
|
|
150
|
+
team = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/assignments`, { body }));
|
|
151
|
+
if (team.id === undefined) {
|
|
152
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Team ${teamId} was not assigned. Check that the team exists.`, { itemIndex: i });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
let assigned = {};
|
|
156
|
+
if (assignee) {
|
|
157
|
+
const body = { assignee_id: assignee.id, assignee_type: assignee.type };
|
|
158
|
+
if (note)
|
|
159
|
+
body.handoff_note = note;
|
|
160
|
+
assigned = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/assignments`, { body }));
|
|
161
|
+
}
|
|
162
|
+
const conversation = await readBack.call(this, id);
|
|
163
|
+
if (conversation)
|
|
164
|
+
return conversation;
|
|
165
|
+
return {
|
|
166
|
+
id: Number(id),
|
|
167
|
+
...(assignee && {
|
|
168
|
+
assignee: {
|
|
169
|
+
id: Number(assignee.id),
|
|
170
|
+
name: (_d = (_c = assigned.available_name) !== null && _c !== void 0 ? _c : assigned.name) !== null && _d !== void 0 ? _d : null,
|
|
171
|
+
type: assignee.type,
|
|
172
|
+
},
|
|
173
|
+
}),
|
|
174
|
+
...(team && { team: { id: team.id, name: (_e = team.name) !== null && _e !== void 0 ? _e : null } }),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async function unassignConversation(i) {
|
|
178
|
+
var _a, _b;
|
|
179
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
180
|
+
const from = this.getNodeParameter('unassignFrom', i, 'agent');
|
|
181
|
+
const note = String((_a = this.getNodeParameter('handoffNote', i, '')) !== null && _a !== void 0 ? _a : '');
|
|
182
|
+
if (from === 'team' || from === 'both') {
|
|
183
|
+
const body = { team_id: null };
|
|
184
|
+
if (note && from === 'team')
|
|
185
|
+
body.handoff_note = note;
|
|
186
|
+
await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/assignments`, { body });
|
|
187
|
+
}
|
|
188
|
+
if (from === 'agent' || from === 'both') {
|
|
189
|
+
const body = { assignee_id: null };
|
|
190
|
+
if (note)
|
|
191
|
+
body.handoff_note = note;
|
|
192
|
+
await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/assignments`, { body });
|
|
193
|
+
}
|
|
194
|
+
return (_b = (await readBack.call(this, id))) !== null && _b !== void 0 ? _b : { id: Number(id), assignee: null };
|
|
195
|
+
}
|
|
196
|
+
async function updateConversationStatus(i) {
|
|
197
|
+
var _a, _b;
|
|
198
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
199
|
+
const status = this.getNodeParameter('status', i);
|
|
200
|
+
const body = { status };
|
|
201
|
+
const snoozeUntil = status === 'snoozed' ? this.getNodeParameter('snoozeUntil', i, '') : '';
|
|
202
|
+
if (snoozeUntil !== '' && snoozeUntil !== undefined && snoozeUntil !== null) {
|
|
203
|
+
const millis = new Date(String(snoozeUntil)).getTime();
|
|
204
|
+
if (Number.isNaN(millis)) {
|
|
205
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `"${String(snoozeUntil)}" is not a valid date`, {
|
|
206
|
+
itemIndex: i,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
body.snoozed_until = Math.floor(millis / 1000);
|
|
210
|
+
}
|
|
211
|
+
const written = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/toggle_status`, { body }));
|
|
212
|
+
return ((_a = (await readBack.call(this, id))) !== null && _a !== void 0 ? _a : {
|
|
213
|
+
id: Number(id),
|
|
214
|
+
status: (_b = (0, GenericFunctions_1.asObject)(written.payload).current_status) !== null && _b !== void 0 ? _b : status,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const HTTP_URL = /^https?:\/\//i;
|
|
218
|
+
async function uploadByUrl(url, i) {
|
|
219
|
+
const upload = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', '/upload', { body: { external_url: url } }));
|
|
220
|
+
if (!upload.blob_id) {
|
|
221
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'WebzzConnect did not return the uploaded file', {
|
|
222
|
+
itemIndex: i,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return String(upload.blob_id);
|
|
226
|
+
}
|
|
227
|
+
function interactiveItems(collection, withListFields) {
|
|
228
|
+
var _a;
|
|
229
|
+
const entries = (_a = collection === null || collection === void 0 ? void 0 : collection.values) !== null && _a !== void 0 ? _a : [];
|
|
230
|
+
return entries.map((entry) => {
|
|
231
|
+
var _a, _b;
|
|
232
|
+
const title = String((_a = entry.title) !== null && _a !== void 0 ? _a : '');
|
|
233
|
+
const value = String((_b = entry.value) !== null && _b !== void 0 ? _b : '');
|
|
234
|
+
const item = { title, value: value || title };
|
|
235
|
+
if (withListFields) {
|
|
236
|
+
if (entry.description)
|
|
237
|
+
item.description = String(entry.description);
|
|
238
|
+
if (entry.section)
|
|
239
|
+
item.section = String(entry.section);
|
|
240
|
+
}
|
|
241
|
+
return item;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
function interactiveAttributes(i, type) {
|
|
245
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
246
|
+
let items;
|
|
247
|
+
if (type === 'button') {
|
|
248
|
+
items = interactiveItems(this.getNodeParameter('buttons', i, {}), false);
|
|
249
|
+
}
|
|
250
|
+
else if (type === 'list') {
|
|
251
|
+
items = interactiveItems(this.getNodeParameter('rows', i, {}), true);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
items = [
|
|
255
|
+
{
|
|
256
|
+
title: String((_a = this.getNodeParameter('ctaText', i, '')) !== null && _a !== void 0 ? _a : ''),
|
|
257
|
+
value: String((_b = this.getNodeParameter('ctaUrl', i, '')) !== null && _b !== void 0 ? _b : '').trim(),
|
|
258
|
+
},
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
const interactive = { type };
|
|
262
|
+
const options = this.getNodeParameter('interactiveOptions', i, {});
|
|
263
|
+
const headerType = String((_c = options.headerType) !== null && _c !== void 0 ? _c : 'none');
|
|
264
|
+
let mediaUrl;
|
|
265
|
+
if ((headerType === 'none' || headerType === 'text') &&
|
|
266
|
+
String((_d = options.headerMediaUrl) !== null && _d !== void 0 ? _d : '').trim()) {
|
|
267
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Choose Header Type Image, Video or Document to use Header Media URL', { itemIndex: i });
|
|
268
|
+
}
|
|
269
|
+
if (headerType === 'text') {
|
|
270
|
+
interactive.header = { type: 'text', text: String((_e = options.headerText) !== null && _e !== void 0 ? _e : '') };
|
|
271
|
+
}
|
|
272
|
+
else if (headerType !== 'none') {
|
|
273
|
+
if (type === 'list') {
|
|
274
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'A list can only have a text header. Choose Header Type Text or None.', { itemIndex: i });
|
|
275
|
+
}
|
|
276
|
+
mediaUrl = String((_f = options.headerMediaUrl) !== null && _f !== void 0 ? _f : '').trim();
|
|
277
|
+
if (!HTTP_URL.test(mediaUrl)) {
|
|
278
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Enter a Header Media URL starting with http:// or https:// for the ${headerType} header`, { itemIndex: i });
|
|
279
|
+
}
|
|
280
|
+
interactive.header = { type: headerType };
|
|
281
|
+
}
|
|
282
|
+
const footer = String((_g = options.footer) !== null && _g !== void 0 ? _g : '');
|
|
283
|
+
if (footer)
|
|
284
|
+
interactive.footer = { text: footer };
|
|
285
|
+
if (type === 'list') {
|
|
286
|
+
const menu = String((_h = this.getNodeParameter('listButton', i, '')) !== null && _h !== void 0 ? _h : '');
|
|
287
|
+
if (menu)
|
|
288
|
+
interactive.button = menu;
|
|
289
|
+
}
|
|
290
|
+
return { attributes: { items, interactive }, mediaUrl };
|
|
291
|
+
}
|
|
292
|
+
async function sendConversationMessage(i) {
|
|
293
|
+
var _a, _b;
|
|
294
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
295
|
+
const type = this.getNodeParameter('messageType', i, 'text');
|
|
296
|
+
const content = String((_a = this.getNodeParameter('content', i, '')) !== null && _a !== void 0 ? _a : '');
|
|
297
|
+
const body = { message_type: 'outgoing' };
|
|
298
|
+
let fileUrl = '';
|
|
299
|
+
if (type === 'text') {
|
|
300
|
+
const options = this.getNodeParameter('options', i, {});
|
|
301
|
+
fileUrl = String((_b = this.getNodeParameter('fileUrl', i, '')) !== null && _b !== void 0 ? _b : '').trim();
|
|
302
|
+
if (!content && !fileUrl) {
|
|
303
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Enter a message, a File URL, or both', {
|
|
304
|
+
itemIndex: i,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
if (fileUrl && !HTTP_URL.test(fileUrl)) {
|
|
308
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'File URL must start with http:// or https://', {
|
|
309
|
+
itemIndex: i,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
body.private = options.private === true;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
if (!content) {
|
|
316
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Enter the Message: it is the body of the buttons, list or link button', { itemIndex: i });
|
|
317
|
+
}
|
|
318
|
+
const { attributes, mediaUrl } = interactiveAttributes.call(this, i, type);
|
|
319
|
+
body.content_type = 'input_select';
|
|
320
|
+
body.content_attributes = attributes;
|
|
321
|
+
fileUrl = mediaUrl !== null && mediaUrl !== void 0 ? mediaUrl : '';
|
|
322
|
+
}
|
|
323
|
+
if (content)
|
|
324
|
+
body.content = content;
|
|
325
|
+
if (fileUrl)
|
|
326
|
+
body.attachments = [await uploadByUrl.call(this, fileUrl, i)];
|
|
327
|
+
return (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/messages`, { body }));
|
|
328
|
+
}
|
|
329
|
+
async function setCustomAttributes(i) {
|
|
330
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
331
|
+
const updates = (0, GenericFunctions_1.pairsToObject)(this.getNodeParameter('customAttributes', i, {}));
|
|
332
|
+
if (Object.keys(updates).length === 0) {
|
|
333
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Add at least one attribute with a key', {
|
|
334
|
+
itemIndex: i,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
const conversation = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/conversations/${id}`));
|
|
338
|
+
const merged = { ...(0, GenericFunctions_1.asObject)(conversation.custom_attributes), ...updates };
|
|
339
|
+
await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/custom_attributes`, {
|
|
340
|
+
body: { custom_attributes: merged },
|
|
341
|
+
});
|
|
342
|
+
return (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/conversations/${id}`));
|
|
343
|
+
}
|
|
344
|
+
async function addLabels(i) {
|
|
345
|
+
var _a;
|
|
346
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
347
|
+
const wanted = String((_a = this.getNodeParameter('labels', i, '')) !== null && _a !== void 0 ? _a : '')
|
|
348
|
+
.split(',')
|
|
349
|
+
.map((label) => label.trim().toLowerCase())
|
|
350
|
+
.filter((label) => label.length > 0);
|
|
351
|
+
if (wanted.length === 0) {
|
|
352
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Enter at least one label', { itemIndex: i });
|
|
353
|
+
}
|
|
354
|
+
const current = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/conversations/${id}/labels`));
|
|
355
|
+
const labels = [...new Set([...current.map(String), ...wanted])];
|
|
356
|
+
const response = await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/conversations/${id}/labels`, {
|
|
357
|
+
body: { labels },
|
|
358
|
+
});
|
|
359
|
+
return { labels: (0, GenericFunctions_1.asArray)(response) };
|
|
360
|
+
}
|
|
361
|
+
function approvedTemplates(inbox) {
|
|
362
|
+
var _a;
|
|
363
|
+
const templates = (_a = inbox === null || inbox === void 0 ? void 0 : inbox.message_templates) !== null && _a !== void 0 ? _a : [];
|
|
364
|
+
return templates.filter((template) => { var _a; return String((_a = template.status) !== null && _a !== void 0 ? _a : '').toUpperCase() === 'APPROVED'; });
|
|
365
|
+
}
|
|
366
|
+
function placeholdersOf(text) {
|
|
367
|
+
return [...new Set([...text.matchAll(/\{\{\s*(\w+)\s*\}\}/g)].map((m) => m[1]))];
|
|
368
|
+
}
|
|
369
|
+
function component(template, type) {
|
|
370
|
+
var _a;
|
|
371
|
+
return (_a = template.components) === null || _a === void 0 ? void 0 : _a.find((entry) => { var _a; return ((_a = entry.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === type; });
|
|
372
|
+
}
|
|
373
|
+
function templateFields(template) {
|
|
374
|
+
var _a, _b, _c, _d;
|
|
375
|
+
const fields = [];
|
|
376
|
+
const header = component(template, 'HEADER');
|
|
377
|
+
const format = String((_a = header === null || header === void 0 ? void 0 : header.format) !== null && _a !== void 0 ? _a : '').toUpperCase();
|
|
378
|
+
if (['IMAGE', 'VIDEO', 'DOCUMENT'].includes(format)) {
|
|
379
|
+
fields.push({ id: 'header_media_url', displayName: `Header ${format.toLowerCase()} URL` });
|
|
380
|
+
}
|
|
381
|
+
else if (format === 'TEXT' && ((_b = header === null || header === void 0 ? void 0 : header.text) !== null && _b !== void 0 ? _b : '').includes('{')) {
|
|
382
|
+
fields.push({ id: 'header_text', displayName: 'Header text variable' });
|
|
383
|
+
}
|
|
384
|
+
for (const placeholder of placeholdersOf(bodyText(template))) {
|
|
385
|
+
fields.push({ id: `body_${placeholder}`, displayName: `Body variable ${placeholder}` });
|
|
386
|
+
}
|
|
387
|
+
((_d = (_c = component(template, 'BUTTONS')) === null || _c === void 0 ? void 0 : _c.buttons) !== null && _d !== void 0 ? _d : []).forEach((button, index) => {
|
|
388
|
+
var _a, _b;
|
|
389
|
+
const type = String((_a = button.type) !== null && _a !== void 0 ? _a : '').toUpperCase();
|
|
390
|
+
if (type === 'URL' && ((_b = button.url) !== null && _b !== void 0 ? _b : '').includes('{')) {
|
|
391
|
+
fields.push({ id: `button_url_${index + 1}`, displayName: `Button ${index + 1} URL variable` });
|
|
392
|
+
}
|
|
393
|
+
else if (type === 'COPY_CODE') {
|
|
394
|
+
fields.push({ id: `button_code_${index + 1}`, displayName: `Button ${index + 1} coupon code` });
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
return fields;
|
|
398
|
+
}
|
|
399
|
+
function processedParams(template, values, body) {
|
|
400
|
+
var _a, _b, _c, _d;
|
|
401
|
+
const out = {};
|
|
402
|
+
if (Object.keys(body).length > 0)
|
|
403
|
+
out.body = body;
|
|
404
|
+
const format = String((_b = (_a = component(template, 'HEADER')) === null || _a === void 0 ? void 0 : _a.format) !== null && _b !== void 0 ? _b : '').toUpperCase();
|
|
405
|
+
if (values.header_media_url) {
|
|
406
|
+
out.header = { media_url: values.header_media_url, media_type: format.toLowerCase() };
|
|
407
|
+
}
|
|
408
|
+
else if (values.header_text) {
|
|
409
|
+
out.header = { '1': values.header_text };
|
|
410
|
+
}
|
|
411
|
+
const buttons = ((_d = (_c = component(template, 'BUTTONS')) === null || _c === void 0 ? void 0 : _c.buttons) !== null && _d !== void 0 ? _d : []).map((_, index) => {
|
|
412
|
+
const url = values[`button_url_${index + 1}`];
|
|
413
|
+
const code = values[`button_code_${index + 1}`];
|
|
414
|
+
if (url)
|
|
415
|
+
return { type: 'url', parameter: url };
|
|
416
|
+
if (code)
|
|
417
|
+
return { type: 'copy_code', parameter: code };
|
|
418
|
+
return { type: 'none', parameter: '' };
|
|
419
|
+
});
|
|
420
|
+
if (buttons.some((button) => button.type !== 'none'))
|
|
421
|
+
out.buttons = buttons;
|
|
422
|
+
return out;
|
|
423
|
+
}
|
|
424
|
+
function bodyText(template) {
|
|
425
|
+
var _a, _b;
|
|
426
|
+
const body = (_a = template.components) === null || _a === void 0 ? void 0 : _a.find((component) => { var _a; return ((_a = component.type) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === 'BODY'; });
|
|
427
|
+
return (_b = body === null || body === void 0 ? void 0 : body.text) !== null && _b !== void 0 ? _b : '';
|
|
428
|
+
}
|
|
429
|
+
async function sendWhatsAppTemplate(i) {
|
|
430
|
+
var _a;
|
|
431
|
+
const inboxId = this.getNodeParameter('inboxId', i);
|
|
432
|
+
const contactId = this.getNodeParameter('contactId', i);
|
|
433
|
+
const key = this.getNodeParameter('template', i);
|
|
434
|
+
const [name, language] = key.split('::');
|
|
435
|
+
if (!name || !language) {
|
|
436
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Choose a template from the list, or use the format template_name::language', { itemIndex: i });
|
|
437
|
+
}
|
|
438
|
+
const inbox = (await fetchInboxes.call(this)).find((entry) => String(entry.id) === String(inboxId));
|
|
439
|
+
if (!inbox) {
|
|
440
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Inbox ${inboxId} was not found`, {
|
|
441
|
+
itemIndex: i,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
const template = approvedTemplates(inbox).find((entry) => entry.name === name && entry.language === language);
|
|
445
|
+
if (!template) {
|
|
446
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No approved template "${name}" (${language}) in this inbox`, { itemIndex: i });
|
|
447
|
+
}
|
|
448
|
+
const text = bodyText(template);
|
|
449
|
+
const placeholders = placeholdersOf(text);
|
|
450
|
+
const mapper = this.getNodeParameter('templateFields', i, {});
|
|
451
|
+
const values = {};
|
|
452
|
+
for (const [id, value] of Object.entries((_a = mapper.value) !== null && _a !== void 0 ? _a : {})) {
|
|
453
|
+
if (value !== undefined && value !== null && String(value) !== '')
|
|
454
|
+
values[id] = String(value);
|
|
455
|
+
}
|
|
456
|
+
const entries = this.getNodeParameter('bodyVariables.values', i, []).map((entry) => { var _a; return String((_a = entry.value) !== null && _a !== void 0 ? _a : ''); });
|
|
457
|
+
if (entries.length > 0) {
|
|
458
|
+
if (entries.length !== placeholders.length) {
|
|
459
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The template body has ${placeholders.length} variable(s) but ${entries.length} value(s) were given`, { itemIndex: i });
|
|
460
|
+
}
|
|
461
|
+
placeholders.forEach((placeholder, index) => {
|
|
462
|
+
values[`body_${placeholder}`] = entries[index];
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
const missing = templateFields(template).filter((field) => !values[field.id]);
|
|
466
|
+
if (missing.length > 0) {
|
|
467
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Missing value for: ${missing.map((field) => field.displayName).join(', ')}`, { itemIndex: i });
|
|
468
|
+
}
|
|
469
|
+
const processed = {};
|
|
470
|
+
let content = text;
|
|
471
|
+
for (const placeholder of placeholders) {
|
|
472
|
+
const value = values[`body_${placeholder}`];
|
|
473
|
+
processed[placeholder] = value;
|
|
474
|
+
content = content.replace(new RegExp(`\\{\\{\\s*${placeholder}\\s*\\}\\}`, 'g'), () => value);
|
|
475
|
+
}
|
|
476
|
+
const templateParams = {
|
|
477
|
+
name: template.name,
|
|
478
|
+
category: template.category,
|
|
479
|
+
language: template.language,
|
|
480
|
+
};
|
|
481
|
+
const params = processedParams(template, values, processed);
|
|
482
|
+
if (Object.keys(params).length > 0)
|
|
483
|
+
templateParams.processed_params = params;
|
|
484
|
+
const body = {
|
|
485
|
+
inbox_id: inboxId,
|
|
486
|
+
contact_id: contactId,
|
|
487
|
+
message: {
|
|
488
|
+
content: content || template.name,
|
|
489
|
+
template_params: templateParams,
|
|
490
|
+
},
|
|
491
|
+
};
|
|
492
|
+
const status = this.getNodeParameter('initialStatus', i, '');
|
|
493
|
+
if (status)
|
|
494
|
+
body.status = status;
|
|
495
|
+
return (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', '/conversations', { body }));
|
|
496
|
+
}
|
|
497
|
+
class WebzzConnect {
|
|
498
|
+
constructor() {
|
|
499
|
+
this.description = {
|
|
500
|
+
displayName: 'WebzzConnect',
|
|
501
|
+
name: 'webzzConnect',
|
|
502
|
+
icon: { light: 'file:webzzconnect.svg', dark: 'file:webzzconnect.dark.svg' },
|
|
503
|
+
group: ['transform'],
|
|
504
|
+
version: [1],
|
|
505
|
+
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
|
|
506
|
+
description: 'Work with contacts, deals, conversations and WhatsApp templates in WebzzConnect',
|
|
507
|
+
defaults: { name: 'WebzzConnect' },
|
|
508
|
+
usableAsTool: true,
|
|
509
|
+
inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
510
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
|
|
511
|
+
credentials: [
|
|
512
|
+
{
|
|
513
|
+
name: 'webzzConnectApi',
|
|
514
|
+
required: true,
|
|
515
|
+
displayOptions: { show: { authentication: ['apiKey'] } },
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
name: 'webzzConnectOAuth2Api',
|
|
519
|
+
required: true,
|
|
520
|
+
displayOptions: { show: { authentication: ['oAuth2'] } },
|
|
521
|
+
},
|
|
522
|
+
],
|
|
523
|
+
properties: [
|
|
524
|
+
GenericFunctions_1.authenticationProperty,
|
|
525
|
+
{
|
|
526
|
+
displayName: 'Resource',
|
|
527
|
+
name: 'resource',
|
|
528
|
+
type: 'options',
|
|
529
|
+
noDataExpression: true,
|
|
530
|
+
options: [
|
|
531
|
+
{ name: 'Contact', value: 'contact' },
|
|
532
|
+
{ name: 'Conversation', value: 'conversation' },
|
|
533
|
+
{ name: 'Deal', value: 'deal' },
|
|
534
|
+
{ name: 'WhatsApp Template', value: 'whatsAppTemplate' },
|
|
535
|
+
],
|
|
536
|
+
default: 'contact',
|
|
537
|
+
},
|
|
538
|
+
...ConnectionDescription_1.connectionOperations,
|
|
539
|
+
...ContactDescription_1.contactOperations,
|
|
540
|
+
...ContactDescription_1.contactFields,
|
|
541
|
+
...DealDescription_1.dealOperations,
|
|
542
|
+
...DealDescription_1.dealFields,
|
|
543
|
+
...ConversationDescription_1.conversationOperations,
|
|
544
|
+
...ConversationDescription_1.conversationFields,
|
|
545
|
+
...WhatsAppTemplateDescription_1.whatsAppTemplateOperations,
|
|
546
|
+
...WhatsAppTemplateDescription_1.whatsAppTemplateFields,
|
|
547
|
+
],
|
|
548
|
+
};
|
|
549
|
+
this.methods = {
|
|
550
|
+
resourceMapping: {
|
|
551
|
+
async getTemplateFields() {
|
|
552
|
+
var _a;
|
|
553
|
+
const inboxId = this.getCurrentNodeParameter('inboxId');
|
|
554
|
+
const key = String((_a = this.getCurrentNodeParameter('template')) !== null && _a !== void 0 ? _a : '');
|
|
555
|
+
const [name, language] = key.split('::');
|
|
556
|
+
if (!inboxId || !name || !language)
|
|
557
|
+
return { fields: [] };
|
|
558
|
+
const inbox = (await fetchInboxes.call(this)).find((entry) => String(entry.id) === String(inboxId));
|
|
559
|
+
const template = approvedTemplates(inbox).find((entry) => entry.name === name && entry.language === language);
|
|
560
|
+
if (!template)
|
|
561
|
+
return { fields: [] };
|
|
562
|
+
return {
|
|
563
|
+
fields: templateFields(template).map((field) => ({
|
|
564
|
+
id: field.id,
|
|
565
|
+
displayName: field.displayName,
|
|
566
|
+
required: true,
|
|
567
|
+
defaultMatch: false,
|
|
568
|
+
canBeUsedToMatch: false,
|
|
569
|
+
display: true,
|
|
570
|
+
type: 'string',
|
|
571
|
+
})),
|
|
572
|
+
};
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
loadOptions: {
|
|
576
|
+
async getPipelines() {
|
|
577
|
+
const pipelines = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/crm/pipelines'));
|
|
578
|
+
return [
|
|
579
|
+
{ name: 'Default', value: '' },
|
|
580
|
+
...pipelines.map((pipeline) => ({
|
|
581
|
+
name: String(pipeline.name),
|
|
582
|
+
value: String(pipeline.id),
|
|
583
|
+
})),
|
|
584
|
+
];
|
|
585
|
+
},
|
|
586
|
+
async getStages() {
|
|
587
|
+
var _a;
|
|
588
|
+
const selected = (this.getCurrentNodeParameter('pipelineId') ||
|
|
589
|
+
this.getCurrentNodeParameter('filters.pipelineId') ||
|
|
590
|
+
'');
|
|
591
|
+
const pipelines = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/crm/pipelines'));
|
|
592
|
+
const options = [{ name: 'Default', value: '' }];
|
|
593
|
+
for (const pipeline of pipelines) {
|
|
594
|
+
if (selected && String(pipeline.id) !== String(selected))
|
|
595
|
+
continue;
|
|
596
|
+
const stages = (_a = pipeline.stages) !== null && _a !== void 0 ? _a : [];
|
|
597
|
+
for (const stage of stages) {
|
|
598
|
+
const kind = stage.kind && stage.kind !== 'open' ? ` (${String(stage.kind)})` : '';
|
|
599
|
+
const prefix = selected ? '' : `${String(pipeline.name)} / `;
|
|
600
|
+
options.push({
|
|
601
|
+
name: `${prefix}${String(stage.name)}${kind}`,
|
|
602
|
+
value: String(stage.id),
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return options;
|
|
607
|
+
},
|
|
608
|
+
async getLostReasons() {
|
|
609
|
+
const reasons = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/crm/lost_reasons'));
|
|
610
|
+
return [
|
|
611
|
+
{ name: 'None', value: '' },
|
|
612
|
+
...reasons.map((reason) => ({ name: String(reason.name), value: String(reason.id) })),
|
|
613
|
+
];
|
|
614
|
+
},
|
|
615
|
+
async getInboxes() {
|
|
616
|
+
const inboxes = await fetchInboxes.call(this);
|
|
617
|
+
return inboxes.map((inbox) => ({ name: String(inbox.name), value: String(inbox.id) }));
|
|
618
|
+
},
|
|
619
|
+
async getAgents() {
|
|
620
|
+
const inboxId = this.getCurrentNodeParameter('inboxId');
|
|
621
|
+
if (!inboxId)
|
|
622
|
+
return [];
|
|
623
|
+
const agents = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/assignable_agents', {
|
|
624
|
+
qs: { 'inbox_ids[]': GenericFunctions_1.pathId.call(this, inboxId), include_agent_bots: 1 },
|
|
625
|
+
}));
|
|
626
|
+
return agents.map((agent) => {
|
|
627
|
+
var _a, _b;
|
|
628
|
+
return agent.assignee_type === 'AgentBot'
|
|
629
|
+
? { name: `${String(agent.name)} (virtual agent)`, value: `AgentBot:${String(agent.id)}` }
|
|
630
|
+
: {
|
|
631
|
+
name: String((_b = (_a = agent.available_name) !== null && _a !== void 0 ? _a : agent.name) !== null && _b !== void 0 ? _b : agent.email),
|
|
632
|
+
value: String(agent.id),
|
|
633
|
+
};
|
|
634
|
+
});
|
|
635
|
+
},
|
|
636
|
+
async getTeams() {
|
|
637
|
+
const teams = (0, GenericFunctions_1.asArray)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', '/teams'));
|
|
638
|
+
return teams.map((team) => ({ name: String(team.name), value: String(team.id) }));
|
|
639
|
+
},
|
|
640
|
+
async getWhatsAppInboxes() {
|
|
641
|
+
const inboxes = await fetchInboxes.call(this);
|
|
642
|
+
return inboxes
|
|
643
|
+
.filter((inbox) => inbox.channel_type === 'Channel::Whatsapp')
|
|
644
|
+
.map((inbox) => ({ name: String(inbox.name), value: String(inbox.id) }));
|
|
645
|
+
},
|
|
646
|
+
async getWhatsAppTemplates() {
|
|
647
|
+
const inboxId = this.getCurrentNodeParameter('inboxId');
|
|
648
|
+
if (!inboxId)
|
|
649
|
+
return [];
|
|
650
|
+
const inbox = (await fetchInboxes.call(this)).find((entry) => String(entry.id) === String(inboxId));
|
|
651
|
+
return approvedTemplates(inbox).map((template) => ({
|
|
652
|
+
name: `${String(template.name)} (${String(template.language)})`,
|
|
653
|
+
value: `${String(template.name)}::${String(template.language)}`,
|
|
654
|
+
description: bodyText(template).slice(0, 200),
|
|
655
|
+
}));
|
|
656
|
+
},
|
|
657
|
+
},
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
async execute() {
|
|
661
|
+
const items = this.getInputData();
|
|
662
|
+
const returnData = [];
|
|
663
|
+
const resource = this.getNodeParameter('resource', 0);
|
|
664
|
+
const operation = this.getNodeParameter('operation', 0);
|
|
665
|
+
for (let i = 0; i < items.length; i++) {
|
|
666
|
+
try {
|
|
667
|
+
let result = {};
|
|
668
|
+
if (resource === 'connection') {
|
|
669
|
+
const { kind, account, virtual_agent, user } = await GenericFunctions_1.getConnectionInfo.call(this);
|
|
670
|
+
result = { kind, account, virtual_agent, user };
|
|
671
|
+
}
|
|
672
|
+
else if (resource === 'contact') {
|
|
673
|
+
if (operation === 'create') {
|
|
674
|
+
const fields = {
|
|
675
|
+
name: this.getNodeParameter('name', i, ''),
|
|
676
|
+
email: this.getNodeParameter('email', i, ''),
|
|
677
|
+
phoneNumber: this.getNodeParameter('phoneNumber', i, ''),
|
|
678
|
+
...this.getNodeParameter('additionalFields', i, {}),
|
|
679
|
+
};
|
|
680
|
+
result = (0, GenericFunctions_1.unwrapContact)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', '/contacts', { body: contactBody(fields) }));
|
|
681
|
+
}
|
|
682
|
+
else if (operation === 'createOrUpdate') {
|
|
683
|
+
result = await createOrUpdateContact.call(this, i);
|
|
684
|
+
}
|
|
685
|
+
else if (operation === 'update') {
|
|
686
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('contactId', i));
|
|
687
|
+
const fields = this.getNodeParameter('updateFields', i, {});
|
|
688
|
+
result = (0, GenericFunctions_1.unwrapContact)(await GenericFunctions_1.wzApiRequest.call(this, 'PATCH', `/contacts/${id}`, {
|
|
689
|
+
body: contactBody(fields),
|
|
690
|
+
}));
|
|
691
|
+
}
|
|
692
|
+
else if (operation === 'get') {
|
|
693
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('contactId', i));
|
|
694
|
+
result = (0, GenericFunctions_1.unwrapContact)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/contacts/${id}`));
|
|
695
|
+
}
|
|
696
|
+
else if (operation === 'search') {
|
|
697
|
+
const query = this.getNodeParameter('query', i);
|
|
698
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
699
|
+
const limit = returnAll ? 0 : this.getNodeParameter('limit', i);
|
|
700
|
+
result = await GenericFunctions_1.wzPaginate.call(this, '/contacts/search', {
|
|
701
|
+
qs: { q: query },
|
|
702
|
+
returnAll,
|
|
703
|
+
limit,
|
|
704
|
+
pageSize: 100,
|
|
705
|
+
extract: GenericFunctions_1.asArray,
|
|
706
|
+
hasMore: (response) => (0, GenericFunctions_1.asObject)((0, GenericFunctions_1.asObject)(response).meta).has_more === true,
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
else if (resource === 'deal') {
|
|
711
|
+
if (operation === 'create') {
|
|
712
|
+
const fields = this.getNodeParameter('additionalFields', i, {});
|
|
713
|
+
const body = dealBody({ ...fields, title: this.getNodeParameter('title', i) });
|
|
714
|
+
body.contact_id = this.getNodeParameter('contactId', i);
|
|
715
|
+
const pipelineId = this.getNodeParameter('pipelineId', i, '');
|
|
716
|
+
const stageId = this.getNodeParameter('stageId', i, '');
|
|
717
|
+
if (pipelineId)
|
|
718
|
+
body.pipeline_id = pipelineId;
|
|
719
|
+
if (stageId)
|
|
720
|
+
body.stage_id = stageId;
|
|
721
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', '/crm/deals', { body }));
|
|
722
|
+
}
|
|
723
|
+
else if (operation === 'update') {
|
|
724
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('dealId', i));
|
|
725
|
+
const fields = this.getNodeParameter('updateFields', i, {});
|
|
726
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'PATCH', `/crm/deals/${id}`, {
|
|
727
|
+
body: dealBody(fields),
|
|
728
|
+
}));
|
|
729
|
+
}
|
|
730
|
+
else if (operation === 'moveStage') {
|
|
731
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('dealId', i));
|
|
732
|
+
const stageId = this.getNodeParameter('stageId', i);
|
|
733
|
+
if (!stageId) {
|
|
734
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Choose the stage to move the deal to', {
|
|
735
|
+
itemIndex: i,
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
const options = this.getNodeParameter('moveOptions', i, {});
|
|
739
|
+
const body = compact({
|
|
740
|
+
stage_id: stageId,
|
|
741
|
+
lost_reason_id: options.lostReasonId,
|
|
742
|
+
lost_note: options.lostNote,
|
|
743
|
+
});
|
|
744
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', `/crm/deals/${id}/move`, { body }));
|
|
745
|
+
}
|
|
746
|
+
else if (operation === 'get') {
|
|
747
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('dealId', i));
|
|
748
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/crm/deals/${id}`));
|
|
749
|
+
}
|
|
750
|
+
else if (operation === 'search') {
|
|
751
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
752
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
753
|
+
const limit = returnAll ? 0 : this.getNodeParameter('limit', i);
|
|
754
|
+
result = await GenericFunctions_1.wzPaginate.call(this, '/crm/deals', {
|
|
755
|
+
qs: compact({
|
|
756
|
+
q: filters.q,
|
|
757
|
+
contact_id: filters.contactId,
|
|
758
|
+
pipeline_id: filters.pipelineId,
|
|
759
|
+
stage_id: filters.stageId,
|
|
760
|
+
owner_id: filters.ownerId,
|
|
761
|
+
status: filters.status,
|
|
762
|
+
}),
|
|
763
|
+
returnAll,
|
|
764
|
+
limit,
|
|
765
|
+
pageSize: 25,
|
|
766
|
+
extract: GenericFunctions_1.asArray,
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
else if (resource === 'conversation') {
|
|
771
|
+
if (operation === 'create') {
|
|
772
|
+
const content = this.getNodeParameter('content', i, '');
|
|
773
|
+
const body = {
|
|
774
|
+
inbox_id: this.getNodeParameter('inboxId', i),
|
|
775
|
+
contact_id: this.getNodeParameter('contactId', i),
|
|
776
|
+
};
|
|
777
|
+
if (content)
|
|
778
|
+
body.message = { content };
|
|
779
|
+
const status = this.getNodeParameter('initialStatus', i, '');
|
|
780
|
+
if (status)
|
|
781
|
+
body.status = status;
|
|
782
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'POST', '/conversations', { body }));
|
|
783
|
+
}
|
|
784
|
+
else if (operation === 'sendMessage') {
|
|
785
|
+
result = await sendConversationMessage.call(this, i);
|
|
786
|
+
}
|
|
787
|
+
else if (operation === 'get') {
|
|
788
|
+
const id = GenericFunctions_1.pathId.call(this, this.getNodeParameter('conversationId', i));
|
|
789
|
+
result = (0, GenericFunctions_1.asObject)(await GenericFunctions_1.wzApiRequest.call(this, 'GET', `/conversations/${id}`));
|
|
790
|
+
}
|
|
791
|
+
else if (operation === 'assign') {
|
|
792
|
+
result = await assignConversation.call(this, i);
|
|
793
|
+
}
|
|
794
|
+
else if (operation === 'unassign') {
|
|
795
|
+
result = await unassignConversation.call(this, i);
|
|
796
|
+
}
|
|
797
|
+
else if (operation === 'updateStatus') {
|
|
798
|
+
result = await updateConversationStatus.call(this, i);
|
|
799
|
+
}
|
|
800
|
+
else if (operation === 'setCustomAttributes') {
|
|
801
|
+
result = await setCustomAttributes.call(this, i);
|
|
802
|
+
}
|
|
803
|
+
else if (operation === 'addLabels') {
|
|
804
|
+
result = await addLabels.call(this, i);
|
|
805
|
+
}
|
|
806
|
+
else if (operation === 'getAll') {
|
|
807
|
+
const filters = this.getNodeParameter('filters', i, {});
|
|
808
|
+
const returnAll = this.getNodeParameter('returnAll', i);
|
|
809
|
+
const limit = returnAll ? 0 : this.getNodeParameter('limit', i);
|
|
810
|
+
result = await GenericFunctions_1.wzPaginate.call(this, '/conversations', {
|
|
811
|
+
qs: compact({
|
|
812
|
+
status: filters.status || 'open',
|
|
813
|
+
inbox_id: filters.inboxId,
|
|
814
|
+
agent_id: filters.agentId ? GenericFunctions_1.pathId.call(this, filters.agentId) : undefined,
|
|
815
|
+
}),
|
|
816
|
+
returnAll,
|
|
817
|
+
limit,
|
|
818
|
+
pageSize: 25,
|
|
819
|
+
extract: (response) => { var _a; return (0, GenericFunctions_1.asArray)((_a = (0, GenericFunctions_1.asObject)(response).data) !== null && _a !== void 0 ? _a : response); },
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
else if (resource === 'whatsAppTemplate' && operation === 'send') {
|
|
824
|
+
result = await sendWhatsAppTemplate.call(this, i);
|
|
825
|
+
}
|
|
826
|
+
const cleaned = (0, GenericFunctions_1.stripInternalKeys)(result);
|
|
827
|
+
const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(cleaned), { itemData: { item: i } });
|
|
828
|
+
returnData.push(...executionData);
|
|
829
|
+
}
|
|
830
|
+
catch (error) {
|
|
831
|
+
if (this.continueOnFail()) {
|
|
832
|
+
returnData.push({
|
|
833
|
+
json: { error: error.message },
|
|
834
|
+
pairedItem: { item: i },
|
|
835
|
+
});
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
throw (0, GenericFunctions_1.errorForItem)(this.getNode(), error, i);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
return [returnData];
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
exports.WebzzConnect = WebzzConnect;
|
|
845
|
+
//# sourceMappingURL=WebzzConnect.node.js.map
|