n8n-nodes-zalo-bot-stephen 0.1.7 → 0.1.8
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.
|
@@ -6,6 +6,47 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ZaloBot = void 0;
|
|
7
7
|
const n8n_workflow_1 = require("n8n-workflow");
|
|
8
8
|
const form_data_1 = __importDefault(require("form-data"));
|
|
9
|
+
// Helper function for making requests with retry logic
|
|
10
|
+
async function makeRequestWithRetry(executeFunctions, url, method, body, isMultipart = false, maxRetries = 3) {
|
|
11
|
+
let lastError = null;
|
|
12
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
13
|
+
try {
|
|
14
|
+
const options = {
|
|
15
|
+
method,
|
|
16
|
+
url,
|
|
17
|
+
headers: {},
|
|
18
|
+
};
|
|
19
|
+
if (isMultipart && body instanceof form_data_1.default) {
|
|
20
|
+
options.body = body;
|
|
21
|
+
options.headers = body.getHeaders();
|
|
22
|
+
}
|
|
23
|
+
else if (body) {
|
|
24
|
+
options.body = body;
|
|
25
|
+
options.headers['Content-Type'] = 'application/json';
|
|
26
|
+
options.json = true;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
options.headers['Content-Type'] = 'application/json';
|
|
30
|
+
}
|
|
31
|
+
const response = await executeFunctions.helpers.httpRequest(options);
|
|
32
|
+
return response;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
lastError = error;
|
|
36
|
+
// Don't retry on client errors (4xx)
|
|
37
|
+
if (error.response?.status >= 400 && error.response?.status < 500) {
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
// Retry on network errors or server errors (5xx)
|
|
41
|
+
if (attempt < maxRetries) {
|
|
42
|
+
// Exponential backoff: wait 1s, 2s, 4s
|
|
43
|
+
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt - 1) * 1000));
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw lastError || new Error('Request failed after retries');
|
|
49
|
+
}
|
|
9
50
|
class ZaloBot {
|
|
10
51
|
constructor() {
|
|
11
52
|
this.description = {
|
|
@@ -337,7 +378,7 @@ class ZaloBot {
|
|
|
337
378
|
chat_id: chatId,
|
|
338
379
|
text,
|
|
339
380
|
};
|
|
340
|
-
response = await
|
|
381
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/sendMessage`, 'POST', body);
|
|
341
382
|
}
|
|
342
383
|
else if (operation === 'sendPhoto') {
|
|
343
384
|
const chatId = this.getNodeParameter('chatId', i);
|
|
@@ -369,7 +410,7 @@ class ZaloBot {
|
|
|
369
410
|
if (caption) {
|
|
370
411
|
formData.append('caption', caption);
|
|
371
412
|
}
|
|
372
|
-
response = await
|
|
413
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/sendPhoto`, 'POST', formData, true);
|
|
373
414
|
}
|
|
374
415
|
else {
|
|
375
416
|
const body = {
|
|
@@ -379,7 +420,7 @@ class ZaloBot {
|
|
|
379
420
|
if (caption) {
|
|
380
421
|
body.caption = caption;
|
|
381
422
|
}
|
|
382
|
-
response = await
|
|
423
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/sendPhoto`, 'POST', body);
|
|
383
424
|
}
|
|
384
425
|
}
|
|
385
426
|
else if (operation === 'sendSticker') {
|
|
@@ -389,7 +430,7 @@ class ZaloBot {
|
|
|
389
430
|
chat_id: chatId,
|
|
390
431
|
sticker_id: stickerId,
|
|
391
432
|
};
|
|
392
|
-
response = await
|
|
433
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/sendSticker`, 'POST', body);
|
|
393
434
|
}
|
|
394
435
|
else if (operation === 'sendChatAction') {
|
|
395
436
|
const chatId = this.getNodeParameter('chatId', i);
|
|
@@ -398,7 +439,7 @@ class ZaloBot {
|
|
|
398
439
|
chat_id: chatId,
|
|
399
440
|
action: action,
|
|
400
441
|
};
|
|
401
|
-
response = await
|
|
442
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/sendChatAction`, 'POST', body);
|
|
402
443
|
}
|
|
403
444
|
else {
|
|
404
445
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
@@ -406,7 +447,7 @@ class ZaloBot {
|
|
|
406
447
|
}
|
|
407
448
|
else if (resource === 'bot') {
|
|
408
449
|
if (operation === 'getMe') {
|
|
409
|
-
response = await
|
|
450
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/getMe`, 'GET');
|
|
410
451
|
}
|
|
411
452
|
else {
|
|
412
453
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
@@ -414,7 +455,7 @@ class ZaloBot {
|
|
|
414
455
|
}
|
|
415
456
|
else if (resource === 'webhook') {
|
|
416
457
|
if (operation === 'getWebhookInfo') {
|
|
417
|
-
response = await
|
|
458
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/getWebhookInfo`, 'GET');
|
|
418
459
|
}
|
|
419
460
|
else if (operation === 'setWebhook') {
|
|
420
461
|
const webhookUrl = this.getNodeParameter('webhookUrl', i);
|
|
@@ -423,10 +464,10 @@ class ZaloBot {
|
|
|
423
464
|
url: webhookUrl,
|
|
424
465
|
secret_token: secretToken,
|
|
425
466
|
};
|
|
426
|
-
response = await
|
|
467
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/setWebhook`, 'POST', body);
|
|
427
468
|
}
|
|
428
469
|
else if (operation === 'deleteWebhook') {
|
|
429
|
-
response = await
|
|
470
|
+
response = await makeRequestWithRetry(executeFunctions, `${baseUrl}/deleteWebhook`, 'POST');
|
|
430
471
|
}
|
|
431
472
|
else {
|
|
432
473
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown operation: ${operation}`);
|
|
@@ -436,7 +477,7 @@ class ZaloBot {
|
|
|
436
477
|
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unknown resource: ${resource}`);
|
|
437
478
|
}
|
|
438
479
|
if (!response.ok) {
|
|
439
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.description || 'API request failed'
|
|
480
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.description || 'API request failed');
|
|
440
481
|
}
|
|
441
482
|
returnData.push({
|
|
442
483
|
json: response.result || response,
|
|
@@ -462,45 +503,5 @@ class ZaloBot {
|
|
|
462
503
|
}
|
|
463
504
|
return [returnData];
|
|
464
505
|
}
|
|
465
|
-
async makeRequestWithRetry(executeFunctions, url, method, body, isMultipart = false, maxRetries = 3) {
|
|
466
|
-
let lastError = null;
|
|
467
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
468
|
-
try {
|
|
469
|
-
const options = {
|
|
470
|
-
method,
|
|
471
|
-
url,
|
|
472
|
-
headers: {},
|
|
473
|
-
};
|
|
474
|
-
if (isMultipart && body instanceof form_data_1.default) {
|
|
475
|
-
options.body = body;
|
|
476
|
-
options.headers = body.getHeaders();
|
|
477
|
-
}
|
|
478
|
-
else if (body) {
|
|
479
|
-
options.body = body;
|
|
480
|
-
options.headers['Content-Type'] = 'application/json';
|
|
481
|
-
options.json = true;
|
|
482
|
-
}
|
|
483
|
-
else {
|
|
484
|
-
options.headers['Content-Type'] = 'application/json';
|
|
485
|
-
}
|
|
486
|
-
const response = await executeFunctions.helpers.httpRequest(options);
|
|
487
|
-
return response;
|
|
488
|
-
}
|
|
489
|
-
catch (error) {
|
|
490
|
-
lastError = error;
|
|
491
|
-
// Don't retry on client errors (4xx)
|
|
492
|
-
if (error.response?.status >= 400 && error.response?.status < 500) {
|
|
493
|
-
throw error;
|
|
494
|
-
}
|
|
495
|
-
// Retry on network errors or server errors (5xx)
|
|
496
|
-
if (attempt < maxRetries) {
|
|
497
|
-
// Exponential backoff: wait 1s, 2s, 4s
|
|
498
|
-
await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt - 1) * 1000));
|
|
499
|
-
continue;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
throw lastError || new Error('Request failed after retries');
|
|
504
|
-
}
|
|
505
506
|
}
|
|
506
507
|
exports.ZaloBot = ZaloBot;
|