@tiledesk/tiledesk-whatsapp-connector 0.1.41 → 0.1.43
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/index.js +156 -233
- package/logs/app.log +4 -0
- package/package.json +3 -2
- package/template/css/detail.css +22 -0
- package/template/detail.html +25 -2
- package/tiledesk/KVBaseMongo.js +13 -18
- package/tiledesk/MessageHandler.js +3 -4
- package/tiledesk/TiledeskAppsClient.js +6 -9
- package/tiledesk/TiledeskBotTester.js +6 -5
- package/tiledesk/TiledeskChannel.js +67 -24
- package/tiledesk/TiledeskSubscriptionClient.js +3 -5
- package/tiledesk/TiledeskWhatsapp.js +14 -18
- package/tiledesk/TiledeskWhatsappTranslator.js +24 -10
- package/winston.js +41 -0
package/index.js
CHANGED
|
@@ -9,6 +9,8 @@ const path = require('path');
|
|
|
9
9
|
const pjson = require('./package.json');
|
|
10
10
|
const { v4: uuidv4 } = require('uuid');
|
|
11
11
|
const cors = require('cors');
|
|
12
|
+
var winston = require('./winston');
|
|
13
|
+
const url = require('url');
|
|
12
14
|
|
|
13
15
|
// tiledesk clients
|
|
14
16
|
//const { TiledeskClient } = require('@tiledesk/tiledesk-client');
|
|
@@ -23,7 +25,7 @@ const { TiledeskBotTester } = require('./tiledesk/TiledeskBotTester');
|
|
|
23
25
|
// mongo
|
|
24
26
|
const { KVBaseMongo } = require('./tiledesk/KVBaseMongo');
|
|
25
27
|
const kvbase_collection = 'kvstore';
|
|
26
|
-
const db = new KVBaseMongo(
|
|
28
|
+
const db = new KVBaseMongo(kvbase_collection);
|
|
27
29
|
|
|
28
30
|
// mongo old
|
|
29
31
|
//const { KVBaseMongo } = require('@tiledesk/tiledesk-kvbasemongo')
|
|
@@ -46,7 +48,6 @@ let APPS_API_URL = null;
|
|
|
46
48
|
let REDIS_HOST = null;
|
|
47
49
|
let REDIS_PORT = null;
|
|
48
50
|
let REDIS_PASSWORD = null;
|
|
49
|
-
let log = false;
|
|
50
51
|
|
|
51
52
|
// Handlebars register helpers
|
|
52
53
|
handlebars.registerHelper('isEqual', (a, b) => {
|
|
@@ -63,12 +64,18 @@ router.get('/', async (req, res) => {
|
|
|
63
64
|
|
|
64
65
|
router.get('/detail', async (req, res) => {
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
winston.verbose("(wab) /detail")
|
|
68
|
+
|
|
69
|
+
let project_id = req.query.project_id;
|
|
67
70
|
let token = req.query.token;
|
|
68
71
|
let app_id = req.query.app_id;
|
|
69
72
|
|
|
73
|
+
const tdChannel = new TiledeskChannel({ settings: { project_id: project_id, token: token }, API_URL: API_URL })
|
|
74
|
+
let isAvailable = await tdChannel.getProjectDetail();
|
|
75
|
+
winston.debug("(wab) app is available: ", isAvailable);
|
|
76
|
+
|
|
70
77
|
const appClient = new TiledeskAppsClient({ APPS_API_URL: APPS_API_URL });
|
|
71
|
-
let installation = await appClient.getInstallations(
|
|
78
|
+
let installation = await appClient.getInstallations(project_id, app_id);
|
|
72
79
|
|
|
73
80
|
let installed = false;
|
|
74
81
|
if (installation) {
|
|
@@ -76,16 +83,14 @@ router.get('/detail', async (req, res) => {
|
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
readHTMLFile('/detail.html', (err, html) => {
|
|
79
|
-
if (err) {
|
|
80
|
-
console.error("(wab) error read html file: ", err);
|
|
81
|
-
}
|
|
82
86
|
var template = handlebars.compile(html);
|
|
83
87
|
var replacements = {
|
|
84
88
|
app_version: pjson.version,
|
|
85
|
-
project_id:
|
|
89
|
+
project_id: project_id,
|
|
86
90
|
token: token,
|
|
87
91
|
app_id: app_id,
|
|
88
|
-
installed: installed
|
|
92
|
+
installed: installed,
|
|
93
|
+
isAvailable: isAvailable
|
|
89
94
|
}
|
|
90
95
|
var html = template(replacements);
|
|
91
96
|
res.send(html);
|
|
@@ -94,11 +99,13 @@ router.get('/detail', async (req, res) => {
|
|
|
94
99
|
|
|
95
100
|
router.post('/install', async (req, res) => {
|
|
96
101
|
|
|
102
|
+
winston.verbose("(wab) /install")
|
|
103
|
+
|
|
97
104
|
let project_id = req.body.project_id;
|
|
98
105
|
let app_id = req.body.app_id;
|
|
99
106
|
let token = req.body.token;
|
|
100
107
|
|
|
101
|
-
|
|
108
|
+
winston.debug("(wab) Install app " + app_id + " for project id " + project_id);
|
|
102
109
|
let installation_info = {
|
|
103
110
|
project_id: project_id,
|
|
104
111
|
app_id: app_id,
|
|
@@ -107,38 +114,27 @@ router.post('/install', async (req, res) => {
|
|
|
107
114
|
|
|
108
115
|
const appClient = new TiledeskAppsClient({ APPS_API_URL: APPS_API_URL });
|
|
109
116
|
appClient.install(installation_info).then((installation) => {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (err) {
|
|
119
|
-
console.error("(wab) error read html file: ", err);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
var template = handlebars.compile(html);
|
|
123
|
-
var replacements = {
|
|
124
|
-
app_version: pjson.version,
|
|
125
|
-
project_id: project_id,
|
|
126
|
-
token: token,
|
|
127
|
-
app_id: app_id,
|
|
128
|
-
installed: installed
|
|
117
|
+
winston.debug("(wab) installation response: " + installation);
|
|
118
|
+
|
|
119
|
+
res.redirect(url.format({
|
|
120
|
+
pathname:"/detail",
|
|
121
|
+
query: {
|
|
122
|
+
"project_id": project_id,
|
|
123
|
+
"app_id": app_id,
|
|
124
|
+
"token": token
|
|
129
125
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
})
|
|
133
|
-
|
|
126
|
+
}));
|
|
127
|
+
|
|
134
128
|
}).catch((err) => {
|
|
135
|
-
|
|
129
|
+
winston.error("(wab) installation error: " + err.data)
|
|
136
130
|
res.send("An error occurred during the installation");
|
|
137
131
|
})
|
|
138
132
|
|
|
139
133
|
})
|
|
140
134
|
|
|
141
135
|
router.post('/uninstall', async (req, res) => {
|
|
136
|
+
|
|
137
|
+
winston.verbose("(wab) /uninstall");
|
|
142
138
|
let project_id = req.body.project_id;
|
|
143
139
|
let app_id = req.body.app_id;
|
|
144
140
|
let token = req.body.token;
|
|
@@ -146,40 +142,26 @@ router.post('/uninstall', async (req, res) => {
|
|
|
146
142
|
const appClient = new TiledeskAppsClient({ APPS_API_URL: APPS_API_URL });
|
|
147
143
|
appClient.uninstall(project_id, app_id).then((response) => {
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
//console.log("(wab) uninstallation response: ", response);
|
|
151
|
-
//}
|
|
152
|
-
|
|
153
|
-
let installed = false;
|
|
145
|
+
winston.debug("(wab) uninstallation response: " + response);
|
|
154
146
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
147
|
+
res.redirect(url.format({
|
|
148
|
+
pathname:"/detail",
|
|
149
|
+
query: {
|
|
150
|
+
"project_id": project_id,
|
|
151
|
+
"app_id": app_id,
|
|
152
|
+
"token": token
|
|
158
153
|
}
|
|
159
|
-
|
|
160
|
-
var template = handlebars.compile(html);
|
|
161
|
-
var replacements = {
|
|
162
|
-
app_version: pjson.version,
|
|
163
|
-
project_id: project_id,
|
|
164
|
-
token: token,
|
|
165
|
-
app_id: app_id,
|
|
166
|
-
installed: installed
|
|
167
|
-
}
|
|
168
|
-
var html = template(replacements);
|
|
169
|
-
res.send(html);
|
|
170
|
-
})
|
|
154
|
+
}));
|
|
171
155
|
|
|
172
156
|
}).catch((err) => {
|
|
173
|
-
|
|
157
|
+
winston.error("(wab) uninsallation error: " + err.data)
|
|
174
158
|
res.send("An error occurred during the uninstallation");
|
|
175
159
|
})
|
|
176
160
|
})
|
|
177
161
|
|
|
178
162
|
router.get('/configure', async (req, res) => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
//console.log("(wab) /configure query: ", req.query);
|
|
182
|
-
//}
|
|
163
|
+
|
|
164
|
+
winston.verbose("(wab) /configure");
|
|
183
165
|
|
|
184
166
|
let projectId = "";
|
|
185
167
|
let token = "";
|
|
@@ -190,24 +172,18 @@ router.get('/configure', async (req, res) => {
|
|
|
190
172
|
let proxy_url = BASE_URL + "/webhook/" + projectId;
|
|
191
173
|
|
|
192
174
|
let CONTENT_KEY = "whatsapp-" + projectId;
|
|
193
|
-
|
|
175
|
+
|
|
194
176
|
let settings = await db.get(CONTENT_KEY);
|
|
195
|
-
|
|
196
|
-
//console.log("(wab) settings: ", settings);
|
|
197
|
-
}
|
|
177
|
+
winston.debug("(wab) settings: " + settings);
|
|
198
178
|
|
|
199
179
|
// get departments
|
|
200
180
|
const tdChannel = new TiledeskChannel({ settings: { project_id: projectId, token: token }, API_URL: API_URL })
|
|
201
181
|
let departments = await tdChannel.getDepartments(token);
|
|
202
|
-
|
|
182
|
+
winston.debug("(wab) found " + departments.length + " departments")
|
|
203
183
|
|
|
204
184
|
if (settings) {
|
|
205
185
|
|
|
206
186
|
readHTMLFile('/configure.html', (err, html) => {
|
|
207
|
-
if (err) {
|
|
208
|
-
console.error("(wab) error read html file: ", err);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
187
|
var template = handlebars.compile(html);
|
|
212
188
|
var replacements = {
|
|
213
189
|
app_version: pjson.version,
|
|
@@ -230,7 +206,7 @@ router.get('/configure', async (req, res) => {
|
|
|
230
206
|
readHTMLFile('/configure.html', (err, html) => {
|
|
231
207
|
|
|
232
208
|
if (err) {
|
|
233
|
-
|
|
209
|
+
winston.error("(wab) error read html file: " + err);
|
|
234
210
|
}
|
|
235
211
|
|
|
236
212
|
var template = handlebars.compile(html);
|
|
@@ -249,10 +225,8 @@ router.get('/configure', async (req, res) => {
|
|
|
249
225
|
})
|
|
250
226
|
|
|
251
227
|
router.post('/update', async (req, res) => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
// console.log("(wab) body: ", req.body);
|
|
255
|
-
//}
|
|
228
|
+
|
|
229
|
+
winston.verbose("(wab) /update");
|
|
256
230
|
|
|
257
231
|
let projectId = req.body.project_id;
|
|
258
232
|
let token = req.body.token;
|
|
@@ -268,7 +242,7 @@ router.post('/update', async (req, res) => {
|
|
|
268
242
|
// get departments
|
|
269
243
|
const tdChannel = new TiledeskChannel({ settings: { project_id: projectId, token: token }, API_URL: API_URL })
|
|
270
244
|
let departments = await tdChannel.getDepartments(token);
|
|
271
|
-
|
|
245
|
+
|
|
272
246
|
if (settings) {
|
|
273
247
|
|
|
274
248
|
settings.wab_token = wab_token;
|
|
@@ -278,10 +252,6 @@ router.post('/update', async (req, res) => {
|
|
|
278
252
|
await db.set(CONTENT_KEY, settings);
|
|
279
253
|
|
|
280
254
|
readHTMLFile('/configure.html', (err, html) => {
|
|
281
|
-
if (err) {
|
|
282
|
-
console.error("(wab) error read html file: ", err);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
255
|
var template = handlebars.compile(html);
|
|
286
256
|
var replacements = {
|
|
287
257
|
app_version: pjson.version,
|
|
@@ -301,7 +271,7 @@ router.post('/update', async (req, res) => {
|
|
|
301
271
|
|
|
302
272
|
} else {
|
|
303
273
|
|
|
304
|
-
const tdClient = new TiledeskSubscriptionClient({ API_URL: API_URL, project_id: projectId, token: token
|
|
274
|
+
const tdClient = new TiledeskSubscriptionClient({ API_URL: API_URL, project_id: projectId, token: token })
|
|
305
275
|
|
|
306
276
|
const subscription_info = {
|
|
307
277
|
target: BASE_URL + "/tiledesk",
|
|
@@ -318,9 +288,7 @@ router.post('/update', async (req, res) => {
|
|
|
318
288
|
// promise
|
|
319
289
|
tdClient.subscribe(subscription_info).then((data) => {
|
|
320
290
|
let subscription = data;
|
|
321
|
-
|
|
322
|
-
//console.log("\n(wab) Subscription: ", subscription)
|
|
323
|
-
//}
|
|
291
|
+
winston.debug("\n(wab) Subscription: " + subscription)
|
|
324
292
|
|
|
325
293
|
let settings = {
|
|
326
294
|
project_id: projectId,
|
|
@@ -337,10 +305,6 @@ router.post('/update', async (req, res) => {
|
|
|
337
305
|
//let cnt = db.get(CONTENT_KEY);
|
|
338
306
|
|
|
339
307
|
readHTMLFile('/configure.html', (err, html) => {
|
|
340
|
-
if (err) {
|
|
341
|
-
console.error("(wab) error read html file: ", err);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
308
|
var template = handlebars.compile(html);
|
|
345
309
|
var replacements = {
|
|
346
310
|
app_version: pjson.version,
|
|
@@ -361,10 +325,6 @@ router.post('/update', async (req, res) => {
|
|
|
361
325
|
}).catch((err) => {
|
|
362
326
|
|
|
363
327
|
readHTMLFile('/configure.html', (err, html) => {
|
|
364
|
-
if (err) {
|
|
365
|
-
console.error("(wab) error read html file: ", err);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
328
|
var template = handlebars.compile(html);
|
|
369
329
|
var replacements = {
|
|
370
330
|
app_version: pjson.version,
|
|
@@ -383,10 +343,8 @@ router.post('/update', async (req, res) => {
|
|
|
383
343
|
})
|
|
384
344
|
|
|
385
345
|
router.post('/disconnect', async (req, res) => {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
//console.log("(wab) body: ", req.body)
|
|
389
|
-
//}
|
|
346
|
+
|
|
347
|
+
winston.verbose("(wab) /disconnect")
|
|
390
348
|
|
|
391
349
|
let projectId = req.body.project_id;
|
|
392
350
|
let token = req.body.token;
|
|
@@ -395,15 +353,15 @@ router.post('/disconnect', async (req, res) => {
|
|
|
395
353
|
|
|
396
354
|
let CONTENT_KEY = "whatsapp-" + projectId;
|
|
397
355
|
await db.remove(CONTENT_KEY);
|
|
398
|
-
|
|
356
|
+
winston.verbose("(wab) Content deleted.");
|
|
399
357
|
|
|
400
358
|
let proxy_url = BASE_URL + "/webhook/" + projectId;
|
|
401
359
|
|
|
402
|
-
const tdClient = new TiledeskSubscriptionClient({ API_URL: API_URL, project_id: projectId, token: token
|
|
360
|
+
const tdClient = new TiledeskSubscriptionClient({ API_URL: API_URL, project_id: projectId, token: token })
|
|
403
361
|
// get departments
|
|
404
362
|
const tdChannel = new TiledeskChannel({ settings: { project_id: projectId, token: token }, API_URL: API_URL })
|
|
405
363
|
let departments = await tdChannel.getDepartments(token);
|
|
406
|
-
|
|
364
|
+
|
|
407
365
|
/*
|
|
408
366
|
// callback
|
|
409
367
|
tdClient.unsubsribe(projectId, subscriptionId, (err, data) => {
|
|
@@ -414,11 +372,6 @@ router.post('/disconnect', async (req, res) => {
|
|
|
414
372
|
tdClient.unsubscribe(subscriptionId).then((data) => {
|
|
415
373
|
|
|
416
374
|
readHTMLFile('/configure.html', (err, html) => {
|
|
417
|
-
|
|
418
|
-
if (err) {
|
|
419
|
-
console.error("(wab) error read html file: ", err);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
375
|
var template = handlebars.compile(html);
|
|
423
376
|
var replacements = {
|
|
424
377
|
app_version: pjson.version,
|
|
@@ -432,16 +385,13 @@ router.post('/disconnect', async (req, res) => {
|
|
|
432
385
|
})
|
|
433
386
|
|
|
434
387
|
}).catch((err) => {
|
|
435
|
-
|
|
388
|
+
winston.error("(wab) unsubscribe error: " + err);
|
|
436
389
|
})
|
|
437
390
|
|
|
438
391
|
})
|
|
439
392
|
|
|
440
393
|
router.post('/tiledesk', async (req, res) => {
|
|
441
|
-
|
|
442
|
-
//if (log) {
|
|
443
|
-
//console.log("(wab) tiledeskChannelMessage: ", JSON.stringify(req.body.payload));
|
|
444
|
-
//}
|
|
394
|
+
winston.verbose("(wab) Message received from Tiledesk")
|
|
445
395
|
|
|
446
396
|
var tiledeskChannelMessage = req.body.payload;
|
|
447
397
|
var projectId = req.body.payload.id_project;
|
|
@@ -461,32 +411,30 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
461
411
|
var sender_id = req.body.payload.sender;
|
|
462
412
|
|
|
463
413
|
if (sender_id.indexOf("wab") > -1) {
|
|
464
|
-
|
|
414
|
+
winston.verbose("(wab) Skip same sender");
|
|
465
415
|
return res.sendStatus(200);
|
|
466
416
|
}
|
|
467
417
|
|
|
468
418
|
if (attributes && attributes.subtype === "info") {
|
|
469
|
-
|
|
419
|
+
winston.verbose("(wab) Skip subtype (info)");
|
|
470
420
|
return res.sendStatus(200);
|
|
471
421
|
}
|
|
472
422
|
|
|
473
423
|
if (attributes && attributes.subtype === 'info/support') {
|
|
474
|
-
|
|
424
|
+
winston.verbose("(wab) Skip subtype: " + attributes.subtype);
|
|
475
425
|
return res.sendStatus(200);
|
|
476
426
|
}
|
|
477
427
|
|
|
478
428
|
let recipient_id = tiledeskChannelMessage.recipient;
|
|
479
429
|
let whatsapp_receiver = recipient_id.substring(recipient_id.lastIndexOf("-") + 1);
|
|
480
430
|
let phone_number_id = recipient_id.substring(recipient_id.lastIndexOf("wab-") + 4, recipient_id.lastIndexOf("-"));
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
//console.log("(wab) phone_number_id: ", phone_number_id)
|
|
489
|
-
//}
|
|
431
|
+
|
|
432
|
+
winston.debug("(wab) text: " + text);
|
|
433
|
+
winston.debug("(wab) attributes: " + attributes)
|
|
434
|
+
winston.debug("(wab) tiledesk sender_id: " + sender_id);
|
|
435
|
+
winston.debug("(wab) recipient_id: " + recipient_id);
|
|
436
|
+
winston.debug("(wab) whatsapp_receiver: " + whatsapp_receiver);
|
|
437
|
+
winston.debug("(wab) phone_number_id: " + phone_number_id)
|
|
490
438
|
|
|
491
439
|
const messageHandler = new MessageHandler({ tiledeskChannelMessage: tiledeskChannelMessage });
|
|
492
440
|
const tlr = new TiledeskWhatsappTranslator();
|
|
@@ -497,30 +445,28 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
497
445
|
// message
|
|
498
446
|
if (command.type === "message") {
|
|
499
447
|
let tiledeskCommandMessage = await messageHandler.generateMessageObject(command);
|
|
500
|
-
|
|
501
|
-
//console.log("(wab) message generated from command: ", JSON.stringify(tiledeskCommandMessage))
|
|
502
|
-
//}
|
|
448
|
+
winston.debug("(wab) message generated from command: " + tiledeskCommandMessage)
|
|
503
449
|
|
|
504
450
|
let whatsappJsonMessage = await tlr.toWhatsapp(tiledeskCommandMessage, whatsapp_receiver);
|
|
505
|
-
|
|
451
|
+
winston.verbose("(wab) 🟢 whatsappJsonMessage" + whatsappJsonMessage)
|
|
506
452
|
|
|
507
453
|
if (whatsappJsonMessage) {
|
|
508
454
|
const twClient = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL });
|
|
509
455
|
twClient.sendMessage(phone_number_id, whatsappJsonMessage).then((response) => {
|
|
510
|
-
|
|
456
|
+
winston.verbose("(wab) Message sent to WhatsApp! " + response.status + " " + response.statusText);
|
|
511
457
|
i += 1;
|
|
512
458
|
if (i < commands.length) {
|
|
513
459
|
execute(commands[i]);
|
|
514
460
|
} else {
|
|
515
|
-
|
|
461
|
+
winston.debug("(wab) End of commands")
|
|
516
462
|
}
|
|
517
463
|
}).catch((err) => {
|
|
518
|
-
|
|
464
|
+
winston.error("(wab) send message error: " + err);
|
|
519
465
|
})
|
|
520
466
|
} else {
|
|
521
|
-
|
|
467
|
+
winston.error("(wab) WhatsappJsonMessage is undefined!")
|
|
522
468
|
}
|
|
523
|
-
|
|
469
|
+
|
|
524
470
|
}
|
|
525
471
|
|
|
526
472
|
//wait
|
|
@@ -530,7 +476,7 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
530
476
|
if (i < commands.length) {
|
|
531
477
|
execute(commands[i]);
|
|
532
478
|
} else {
|
|
533
|
-
|
|
479
|
+
winston.debug("(wab) End of commands")
|
|
534
480
|
}
|
|
535
481
|
}, command.time)
|
|
536
482
|
}
|
|
@@ -538,26 +484,26 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
538
484
|
execute(commands[0]);
|
|
539
485
|
}
|
|
540
486
|
|
|
541
|
-
else if (tiledeskChannelMessage.text
|
|
487
|
+
else if (tiledeskChannelMessage.text || tiledeskChannelMessage.metadata) {
|
|
542
488
|
|
|
543
489
|
let whatsappJsonMessage = await tlr.toWhatsapp(tiledeskChannelMessage, whatsapp_receiver);
|
|
544
|
-
|
|
490
|
+
winston.verbose("(wab) 🟢 whatsappJsonMessage" + whatsappJsonMessage)
|
|
545
491
|
|
|
546
492
|
if (whatsappJsonMessage) {
|
|
547
493
|
const twClient = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL });
|
|
548
|
-
|
|
494
|
+
|
|
549
495
|
twClient.sendMessage(phone_number_id, whatsappJsonMessage).then((response) => {
|
|
550
|
-
|
|
496
|
+
winston.verbose("(wab) Message sent to WhatsApp! " + response.status + " " + response.statusText);
|
|
551
497
|
}).catch((err) => {
|
|
552
|
-
|
|
498
|
+
winston.error("(wab) error send message: " + err);
|
|
553
499
|
})
|
|
554
|
-
|
|
500
|
+
|
|
555
501
|
} else {
|
|
556
|
-
|
|
502
|
+
winston.error("(wab) Whatsapp Json Message is undefined!")
|
|
557
503
|
}
|
|
558
|
-
|
|
504
|
+
|
|
559
505
|
} else {
|
|
560
|
-
|
|
506
|
+
winston.debug("(wab) no command, no text --> skip")
|
|
561
507
|
}
|
|
562
508
|
|
|
563
509
|
return res.send(200);
|
|
@@ -566,14 +512,12 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
566
512
|
// Endpoint for Whatsapp Business
|
|
567
513
|
// Accepts POST requests at /webhook endpoint
|
|
568
514
|
router.post("/webhook/:project_id", async (req, res) => {
|
|
569
|
-
|
|
515
|
+
|
|
570
516
|
// Parse the request body from the POST
|
|
571
517
|
let projectId = req.params.project_id;
|
|
572
|
-
|
|
573
|
-
//console.log("/webhook req.body: ", JSON.stringify(req.body, null, 2))
|
|
518
|
+
winston.verbose("(wab) Message received from WhatsApp");
|
|
574
519
|
|
|
575
520
|
// Check the Incoming webhook message
|
|
576
|
-
// console.log("\n***Body: ", JSON.stringify(req.body, null, 2));
|
|
577
521
|
// info on WhatsApp text message payload: https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/payload-examples#text-messages
|
|
578
522
|
if (req.body.object) {
|
|
579
523
|
if (
|
|
@@ -584,12 +528,8 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
584
528
|
req.body.entry[0].changes[0].value.messages[0]
|
|
585
529
|
) {
|
|
586
530
|
|
|
587
|
-
//if (log) {
|
|
588
|
-
// console.log("\n(wab) body: ", JSON.stringify(req.body));
|
|
589
|
-
//}
|
|
590
|
-
|
|
591
531
|
if (req.body.entry[0].changes[0].value.messages[0].type == "system") {
|
|
592
|
-
|
|
532
|
+
winston.verbos("(wab) Skip system message")
|
|
593
533
|
return res.sendStatus(200);
|
|
594
534
|
}
|
|
595
535
|
|
|
@@ -597,11 +537,10 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
597
537
|
|
|
598
538
|
let CONTENT_KEY = "whatsapp-" + projectId;
|
|
599
539
|
let settings = await db.get(CONTENT_KEY);
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
//}
|
|
540
|
+
winston.debug("(wab) settings: " + settings);
|
|
541
|
+
|
|
603
542
|
if (!settings) {
|
|
604
|
-
|
|
543
|
+
winston.verbose("(wab) No settings found. Exit..");
|
|
605
544
|
return res.sendStatus(200);
|
|
606
545
|
}
|
|
607
546
|
|
|
@@ -609,26 +548,23 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
609
548
|
const tdChannel = new TiledeskChannel({ settings: settings, API_URL: API_URL })
|
|
610
549
|
|
|
611
550
|
// Initialize conversation with chatbot
|
|
612
|
-
if (whatsappChannelMessage.text && whatsappChannelMessage.text.body.startsWith("#td")) {
|
|
551
|
+
if (whatsappChannelMessage.text && whatsappChannelMessage.text.body.startsWith("#td")) {
|
|
613
552
|
|
|
614
553
|
let code = whatsappChannelMessage.text.body.split(' ')[0];
|
|
615
|
-
//console.log("(wab) test code: ", code)
|
|
616
554
|
|
|
617
|
-
const bottester = new TiledeskBotTester({project_id: projectId, redis_client: redis_client, db: db, tdChannel: tdChannel, tlr: tlr});
|
|
555
|
+
const bottester = new TiledeskBotTester({ project_id: projectId, redis_client: redis_client, db: db, tdChannel: tdChannel, tlr: tlr });
|
|
618
556
|
bottester.startBotConversation(req.body, code).then((result) => {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
//console.log("(wab) result: ", result);
|
|
622
|
-
//}
|
|
557
|
+
winston.verbose("(wab) test conversation started");
|
|
558
|
+
winston.debug("(wab) startBotConversation result: " + result);
|
|
623
559
|
}).catch((err) => {
|
|
624
|
-
|
|
560
|
+
winston.error("(wab) start test onversation error: " + err);
|
|
625
561
|
})
|
|
626
562
|
|
|
627
|
-
|
|
563
|
+
// Standard message
|
|
628
564
|
} else {
|
|
629
|
-
|
|
565
|
+
|
|
630
566
|
let firstname = req.body.entry[0].changes[0].value.contacts[0].profile.name;
|
|
631
|
-
|
|
567
|
+
|
|
632
568
|
let message_info = {
|
|
633
569
|
channel: "whatsapp",
|
|
634
570
|
whatsapp: {
|
|
@@ -638,93 +574,91 @@ router.post("/webhook/:project_id", async (req, res) => {
|
|
|
638
574
|
lastname: " "
|
|
639
575
|
}
|
|
640
576
|
}
|
|
641
|
-
|
|
577
|
+
|
|
642
578
|
let tiledeskJsonMessage;
|
|
643
|
-
|
|
579
|
+
|
|
644
580
|
if ((whatsappChannelMessage.type == 'text')) {
|
|
645
|
-
|
|
581
|
+
winston.debug("(wab) message type: text")
|
|
646
582
|
tiledeskJsonMessage = await tlr.toTiledesk(whatsappChannelMessage, firstname);
|
|
647
583
|
}
|
|
648
|
-
|
|
584
|
+
|
|
649
585
|
else if (whatsappChannelMessage.type == 'interactive') {
|
|
650
|
-
|
|
586
|
+
winston.debug("(wab) message type: interactive")
|
|
651
587
|
tiledeskJsonMessage = await tlr.toTiledesk(whatsappChannelMessage, firstname);
|
|
652
588
|
}
|
|
653
589
|
|
|
654
590
|
else if ((whatsappChannelMessage.type == 'image') || (whatsappChannelMessage.type == 'video') || (whatsappChannelMessage.type == 'document')) {
|
|
655
591
|
let media;
|
|
656
592
|
const util = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL })
|
|
657
|
-
|
|
593
|
+
|
|
658
594
|
if (whatsappChannelMessage.type == 'image') {
|
|
659
595
|
media = whatsappChannelMessage.image;
|
|
660
596
|
const filename = await util.downloadMedia(media.id);
|
|
661
597
|
if (!filename) {
|
|
662
|
-
|
|
598
|
+
winston.debug("(wab) Unable to download media with id " + media.id + ". Message not sent.");
|
|
663
599
|
return res.status(500).send({ success: false, error: "unable to download media" })
|
|
664
600
|
}
|
|
665
601
|
let file_path = path.join(__dirname, 'tmp', filename);
|
|
666
|
-
|
|
602
|
+
|
|
667
603
|
const image_url = await util.uploadMedia(file_path, "images");
|
|
668
|
-
|
|
669
|
-
|
|
604
|
+
winston.debug("(wab) image_url: " + image_url)
|
|
605
|
+
|
|
670
606
|
tiledeskJsonMessage = await tlr.toTiledesk(whatsappChannelMessage, firstname, image_url);
|
|
671
607
|
}
|
|
672
|
-
|
|
608
|
+
|
|
673
609
|
if (whatsappChannelMessage.type == 'video') {
|
|
674
610
|
media = whatsappChannelMessage.video;
|
|
675
|
-
|
|
611
|
+
|
|
676
612
|
const filename = await util.downloadMedia(media.id);
|
|
677
613
|
if (!filename) {
|
|
678
|
-
|
|
614
|
+
winston.debug("(wab) Unable to download media with id " + media.id + ". Message not sent.");
|
|
679
615
|
return res.status(500).send({ success: false, error: "unable to download media" })
|
|
680
616
|
}
|
|
681
617
|
let file_path = path.join(__dirname, 'tmp', filename);
|
|
682
|
-
|
|
618
|
+
|
|
683
619
|
const media_url = await util.uploadMedia(file_path, "files");
|
|
684
|
-
|
|
685
|
-
|
|
620
|
+
winston.debug("(wab) media_url: " + media_url)
|
|
621
|
+
|
|
686
622
|
tiledeskJsonMessage = await tlr.toTiledesk(whatsappChannelMessage, firstname, media_url);
|
|
687
623
|
}
|
|
688
|
-
|
|
624
|
+
|
|
689
625
|
if (whatsappChannelMessage.type == 'document') {
|
|
690
626
|
media = whatsappChannelMessage.document;
|
|
691
|
-
|
|
627
|
+
|
|
692
628
|
const filename = await util.downloadMedia(media.id);
|
|
693
629
|
if (!filename) {
|
|
694
|
-
|
|
630
|
+
winston.debug("(wab) Unable to download media with id " + media.id + ". Message not sent.");
|
|
695
631
|
return res.status(500).send({ success: false, error: "unable to download media" })
|
|
696
632
|
}
|
|
697
633
|
let file_path = path.join(__dirname, 'tmp', filename);
|
|
698
|
-
|
|
634
|
+
|
|
699
635
|
const media_url = await util.uploadMedia(file_path, "files");
|
|
700
|
-
|
|
701
|
-
|
|
636
|
+
winston.debug("(wab) media_url: " + media_url)
|
|
637
|
+
|
|
702
638
|
tiledeskJsonMessage = await tlr.toTiledesk(whatsappChannelMessage, firstname, media_url);
|
|
703
639
|
}
|
|
704
|
-
|
|
640
|
+
|
|
705
641
|
} else {
|
|
706
642
|
// unsupported. Try anyway to send something.
|
|
707
|
-
|
|
643
|
+
winston.debug("(wab) unsupported message")
|
|
708
644
|
}
|
|
709
645
|
|
|
710
646
|
if (tiledeskJsonMessage) {
|
|
711
|
-
|
|
647
|
+
winston.verbose("(wab) 🟠 tiledeskJsonMessage: " + tiledeskJsonMessage);
|
|
712
648
|
const response = await tdChannel.send(tiledeskJsonMessage, message_info, settings.department_id);
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
//console.log("(wab) response: ", response)
|
|
716
|
-
//}
|
|
649
|
+
winston.verbose("(wab) Message sent to Tiledesk!")
|
|
650
|
+
winston.debug("(wab) response: " + response)
|
|
717
651
|
} else {
|
|
718
|
-
|
|
652
|
+
winston.verbose("(wab) tiledeskJsonMessage is undefined")
|
|
719
653
|
}
|
|
720
|
-
|
|
654
|
+
|
|
721
655
|
}
|
|
722
|
-
}
|
|
723
|
-
res.sendStatus(200);
|
|
724
|
-
|
|
656
|
+
}
|
|
657
|
+
res.sendStatus(200);
|
|
658
|
+
|
|
725
659
|
} else {
|
|
726
660
|
// Return a '404 Not Found' if event is not from a WhatsApp API
|
|
727
|
-
|
|
661
|
+
winston.verbose("(wab) event not from whatsapp")
|
|
728
662
|
res.sendStatus(404);
|
|
729
663
|
}
|
|
730
664
|
});
|
|
@@ -736,8 +670,8 @@ router.get("/webhook/:project_id", async (req, res) => {
|
|
|
736
670
|
* UPDATE YOUR VERIFY TOKEN
|
|
737
671
|
*This will be the Verify Token value when you set up webhook
|
|
738
672
|
**/
|
|
739
|
-
|
|
740
|
-
|
|
673
|
+
winston.verbose("(wab) Verify the webhook... ");
|
|
674
|
+
winston.debug("(wab) req.query: " + req.query);
|
|
741
675
|
|
|
742
676
|
// Parse params from the webhook verification request
|
|
743
677
|
let mode = req.query["hub.mode"];
|
|
@@ -749,31 +683,25 @@ router.get("/webhook/:project_id", async (req, res) => {
|
|
|
749
683
|
let settings = await db.get(CONTENT_KEY);
|
|
750
684
|
|
|
751
685
|
if (!settings || !settings.verify_token) {
|
|
752
|
-
|
|
686
|
+
winston.error("(wab) No settings found! Unable to verify token.")
|
|
753
687
|
res.sendStatus(403);
|
|
754
688
|
} else {
|
|
755
689
|
let VERIFY_TOKEN = settings.verify_token;
|
|
756
690
|
|
|
757
|
-
//if (log) {
|
|
758
|
-
//console.log("token: ", token);
|
|
759
|
-
//console.log("verify token: ", VERIFY_TOKEN);
|
|
760
|
-
//}
|
|
761
|
-
|
|
762
691
|
// Check if a token and mode were sent
|
|
763
692
|
if (mode && token) {
|
|
764
693
|
// Check the mode and token sent are correct
|
|
765
694
|
if (mode === "subscribe" && token === VERIFY_TOKEN) {
|
|
766
|
-
|
|
767
695
|
// Respond with 200 OK and challenge token from the request
|
|
768
|
-
|
|
696
|
+
winston.verbose("(wab) Webhook verified");
|
|
769
697
|
res.status(200).send(challenge);
|
|
770
698
|
} else {
|
|
771
699
|
// Responds with '403 Forbidden' if verify tokens do not match
|
|
772
|
-
|
|
700
|
+
winston.error("(wab) mode is not 'subscribe' or token do not match");
|
|
773
701
|
res.sendStatus(403);
|
|
774
702
|
}
|
|
775
703
|
} else {
|
|
776
|
-
|
|
704
|
+
winston.error("(wab) mode or token undefined");
|
|
777
705
|
res.status(400).send("impossible to verify the webhook: mode or token undefined.")
|
|
778
706
|
}
|
|
779
707
|
|
|
@@ -784,8 +712,8 @@ router.get("/webhook/:project_id", async (req, res) => {
|
|
|
784
712
|
|
|
785
713
|
router.post("/newtest", async (req, res) => {
|
|
786
714
|
|
|
787
|
-
|
|
788
|
-
|
|
715
|
+
winston.verbose("(wab) initializing new test..");
|
|
716
|
+
|
|
789
717
|
let project_id = req.body.project_id;
|
|
790
718
|
let bot_id = req.body.bot_id;
|
|
791
719
|
|
|
@@ -798,17 +726,17 @@ router.post("/newtest", async (req, res) => {
|
|
|
798
726
|
let key = "bottest:" + short_uid;
|
|
799
727
|
|
|
800
728
|
if (!redis_client) {
|
|
801
|
-
return res.status(500).send({ message: "Test it out on Whatsapp not available. Redis not ready."})
|
|
729
|
+
return res.status(500).send({ message: "Test it out on Whatsapp not available. Redis not ready." })
|
|
802
730
|
}
|
|
803
731
|
|
|
804
732
|
await redis_client.set(key, JSON.stringify(info), 'EX', 604800);
|
|
805
733
|
redis_client.get(key, (err, value) => {
|
|
806
734
|
if (err) {
|
|
807
|
-
|
|
808
|
-
return res.status(500).send({success: "false", message: "Testing info could not be saved"});
|
|
735
|
+
winston.error("(wab) redis get err: " + err)
|
|
736
|
+
return res.status(500).send({ success: "false", message: "Testing info could not be saved" });
|
|
809
737
|
} else {
|
|
810
|
-
|
|
811
|
-
return res.status(200).send({short_uid: short_uid});
|
|
738
|
+
winston.debug("(wab) new test initialized with id: " + short_uid)
|
|
739
|
+
return res.status(200).send({ short_uid: short_uid });
|
|
812
740
|
}
|
|
813
741
|
})
|
|
814
742
|
|
|
@@ -819,7 +747,7 @@ router.post("/newtest", async (req, res) => {
|
|
|
819
747
|
// *****************************
|
|
820
748
|
|
|
821
749
|
async function startApp(settings, callback) {
|
|
822
|
-
|
|
750
|
+
winston.info("(wab) Starting Whatsapp App")
|
|
823
751
|
|
|
824
752
|
if (!settings.MONGODB_URL) {
|
|
825
753
|
throw new Error("settings.MONGODB_URL is mandatory");
|
|
@@ -829,28 +757,28 @@ async function startApp(settings, callback) {
|
|
|
829
757
|
throw new Error("settings.API_URL is mandatory");
|
|
830
758
|
} else {
|
|
831
759
|
API_URL = settings.API_URL;
|
|
832
|
-
|
|
760
|
+
winston.info("(wab) API_URL: " + API_URL);
|
|
833
761
|
}
|
|
834
762
|
|
|
835
763
|
if (!settings.BASE_URL) {
|
|
836
764
|
throw new Error("settings.BASE_URL is mandatory");
|
|
837
765
|
} else {
|
|
838
766
|
BASE_URL = settings.BASE_URL;
|
|
839
|
-
|
|
767
|
+
winston.info("(wab) BASE_URL: " + BASE_URL);
|
|
840
768
|
}
|
|
841
769
|
|
|
842
770
|
if (!settings.GRAPH_URL) {
|
|
843
771
|
throw new Error("settings.GRAPH_URL is mandatory");
|
|
844
772
|
} else {
|
|
845
773
|
GRAPH_URL = settings.GRAPH_URL;
|
|
846
|
-
|
|
774
|
+
winston.info("(wab) GRAPH_URL: " + GRAPH_URL);
|
|
847
775
|
}
|
|
848
776
|
|
|
849
777
|
if (!settings.APPS_API_URL) {
|
|
850
778
|
throw new Error("settings.APPS_API_URL is mandatory");
|
|
851
779
|
} else {
|
|
852
780
|
APPS_API_URL = settings.APPS_API_URL;
|
|
853
|
-
|
|
781
|
+
winston.info("(wab) APPS_API_URL: " + APPS_API_URL);
|
|
854
782
|
}
|
|
855
783
|
|
|
856
784
|
if (settings.REDIS_HOST && settings.REDIS_PORT) {
|
|
@@ -859,16 +787,12 @@ async function startApp(settings, callback) {
|
|
|
859
787
|
REDIS_PASSWORD = settings.REDIS_PASSWORD;
|
|
860
788
|
connectRedis();
|
|
861
789
|
} else {
|
|
862
|
-
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
if (settings.log) {
|
|
866
|
-
log = settings.log;
|
|
790
|
+
winston.info("(wab) Missing redis parameters --> Test it out on WhatsApp disabled");
|
|
867
791
|
}
|
|
868
792
|
|
|
869
793
|
db.connect(settings.MONGODB_URL, () => {
|
|
870
|
-
|
|
871
|
-
|
|
794
|
+
winston.info("(wab) KVBaseMongo successfully connected.");
|
|
795
|
+
|
|
872
796
|
if (callback) {
|
|
873
797
|
callback();
|
|
874
798
|
}
|
|
@@ -879,26 +803,25 @@ function connectRedis() {
|
|
|
879
803
|
redis_client = redis.createClient({
|
|
880
804
|
host: REDIS_HOST,
|
|
881
805
|
port: REDIS_PORT,
|
|
882
|
-
password: REDIS_PASSWORD
|
|
806
|
+
password: REDIS_PASSWORD
|
|
883
807
|
});
|
|
884
808
|
|
|
885
809
|
redis_client.on('error', err => {
|
|
886
|
-
|
|
810
|
+
winston.info('(wab) Connect Redis Error ' + err);
|
|
887
811
|
})
|
|
888
812
|
/*
|
|
889
813
|
redis_client.on('connect', () => {
|
|
890
|
-
|
|
814
|
+
winston.info('Redis Connected!'); // Connected!
|
|
891
815
|
});
|
|
892
816
|
*/
|
|
893
817
|
redis_client.on('ready', () => {
|
|
894
|
-
|
|
818
|
+
winston.info("(wab) Redis ready!")
|
|
895
819
|
})
|
|
896
820
|
//await redis_client.connect(); // only for v4
|
|
897
821
|
|
|
898
822
|
}
|
|
899
823
|
|
|
900
824
|
function readHTMLFile(templateName, callback) {
|
|
901
|
-
//console.log("Reading file: ", templateName)
|
|
902
825
|
fs.readFile(__dirname + '/template' + templateName, { encoding: 'utf-8' },
|
|
903
826
|
function(err, html) {
|
|
904
827
|
if (err) {
|