@tiledesk/tiledesk-whatsapp-connector 0.1.50 → 0.1.52

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 CHANGED
@@ -12,6 +12,11 @@ const cors = require('cors');
12
12
  var winston = require('./winston');
13
13
  const url = require('url');
14
14
 
15
+ //const ext = require('./routes/ext')
16
+ //const extRoute = ext.router;
17
+ const api = require('./routes/api');
18
+ const apiRoute = api.router;
19
+
15
20
  // tiledesk clients
16
21
  //const { TiledeskClient } = require('@tiledesk/tiledesk-client');
17
22
  const { TiledeskWhatsappTranslator } = require('./tiledesk/TiledeskWhatsappTranslator');
@@ -42,6 +47,9 @@ router.use(bodyParser.urlencoded({ extended: true }));
42
47
  router.use(express.static(path.join(__dirname, 'template')));
43
48
  router.use(cors());
44
49
 
50
+ router.use('/ext', apiRoute);
51
+ router.use('/api', apiRoute);
52
+
45
53
  let API_URL = null;
46
54
  let GRAPH_URL = null;
47
55
  let BASE_URL = null;
@@ -163,7 +171,7 @@ router.post('/uninstall', async (req, res) => {
163
171
  }));
164
172
 
165
173
  }).catch((err) => {
166
- winston.error("(wab) uninsallation error: " + err.data)
174
+ winston.error("(wab) uninstallation error: " + err.data)
167
175
  res.send("An error occurred during the uninstallation");
168
176
  })
169
177
  })
@@ -174,6 +182,11 @@ router.get('/configure', async (req, res) => {
174
182
 
175
183
  let project_id = req.query.project_id;
176
184
  let token = req.query.token;
185
+ let popup_view = false;
186
+
187
+ if (req.query.view && req.query.view === 'popup') {
188
+ popup_view = true
189
+ }
177
190
 
178
191
  if (!project_id || !token) {
179
192
  let error_message = "Query params project_id and token are required."
@@ -237,7 +250,8 @@ router.get('/configure', async (req, res) => {
237
250
  project_id: project_id,
238
251
  token: token,
239
252
  proxy_url: proxy_url,
240
- departments: departments
253
+ departments: departments,
254
+ popup_view: popup_view
241
255
  }
242
256
  var html = template(replacements);
243
257
  res.send(html);
@@ -430,12 +444,6 @@ router.get('/direct/tiledesk', async (req, res) => {
430
444
  let CONTENT_KEY = "whatsapp-" + project_id;
431
445
  let settings = await db.get(CONTENT_KEY);
432
446
 
433
- /*
434
- let tiledeskChannelMessage = {
435
- text: "Ciao, benvenuto sull'ambiente di sviluppo di Tiledesk! Questo messaggio serve ad aprire una nuova conversazione. Ha funzionato?"
436
- }
437
- */
438
-
439
447
  let tiledeskChannelMessage = {
440
448
  text: "Sample text",
441
449
  attributes: {
@@ -466,7 +474,6 @@ router.get('/direct/tiledesk', async (req, res) => {
466
474
  })
467
475
 
468
476
  router.post('/tiledesk/broadcast', async (req, res) => {
469
-
470
477
  winston.verbose("(wab) Message received from Tiledesk (Broadcast)");
471
478
 
472
479
  let tiledeskChannelMessage = req.body.payload;
@@ -480,11 +487,88 @@ router.post('/tiledesk/broadcast', async (req, res) => {
480
487
  return res.status(400).send({ success: false, error: "WhatsApp is not installed for the project_id: " + project_id });
481
488
  }
482
489
 
490
+ if (!settings.business_account_id) {
491
+ return res.status(400).send({ success: false, error: "Missing parameter 'WhatsApp Business Account ID'. Please update your app."})
492
+ }
493
+
483
494
  let receiver_list = req.body.receiver_list;
484
- console.log("receiver_list: ", receiver_list);
495
+ let phone_number_id = req.body.phone_number_id;
496
+
497
+ let tm = new TemplateManager({ token: settings.wab_token, business_account_id: settings.business_account_id, GRAPH_URL: GRAPH_URL })
498
+ const tlr = new TiledeskWhatsappTranslator();
499
+ const twClient = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL, API_URL: API_URL, BASE_FILE_URL: BASE_FILE_URL });
500
+
501
+ let response = await tm.getTemplates();
502
+ let templates = response.data;
503
+
504
+ let selected_template = templates.find(t => t.name === tiledeskChannelMessage.attributes.attachment.template.name);
505
+
506
+ let params_object = await tm.generateParamsObject(selected_template);
507
+
508
+ tiledeskChannelMessage.attributes.attachment.template.params = params_object;
509
+ winston.verbose("(wab) --> tiledeskChannelMessage: ", tiledeskChannelMessage)
485
510
 
511
+ let messages_sent = 0;
512
+ let errors = [];
513
+ let error_count = 0;
514
+
515
+ if (receiver_list) {
516
+ let i = 0;
517
+ async function execute(whatsapp_receiver) {
518
+
519
+ let customTiledeskJsonMessage = await tlr.sanitizeTiledeskMessage(tiledeskChannelMessage, whatsapp_receiver)
520
+ winston.info("customTiledeskJsonMessage: ", customTiledeskJsonMessage)
521
+
522
+ let whatsappJsonMessage = await tlr.toWhatsapp(customTiledeskJsonMessage, whatsapp_receiver.phone_number);
523
+ winston.verbose("(wab) message created for receiver: " + whatsapp_receiver.phone_number);
524
+ winston.verbose("(wab) whatsappJsonMessage", whatsappJsonMessage);
525
+
526
+ await twClient.sendMessage(phone_number_id, whatsappJsonMessage).then((response) => {
527
+ winston.verbose("(wab) Message sent to WhatsApp! " + response.status + " " + response.statusText);
528
+ messages_sent += 1;
529
+ i += 1;
530
+ if (i < receiver_list.length) {
531
+ execute(receiver_list[i])
532
+ } else {
533
+ return res.status(200).send({ success: true, message: "Broadcast terminated", messages_sent: messages_sent, errors: errors });
534
+ winston.debug("(wab) End of list")
535
+ }
536
+ }).catch((err) => {
537
+ winston.error("(wab) error send message: " + err.response.data.error.message);
538
+ errors.push({ receiver: whatsapp_receiver.phone_number, error: err.response.data.error.message });
539
+ i += 1;
540
+ if (i < receiver_list.length) {
541
+ execute(receiver_list[i])
542
+ } else {
543
+ winston.debug("(wab) End of list")
544
+ return res.status(200).send({ success: true, message: "Broadcast terminated", messages_sent: messages_sent, errors: errors });
545
+ }
546
+ })
547
+ }
548
+ execute(receiver_list[0]);
549
+ }
550
+
551
+ })
552
+
553
+
554
+ /*
555
+ router.post('/tiledesk/broadcast2', async (req, res) => {
556
+
557
+ winston.verbose("(wab) Message received from Tiledesk (Broadcast)");
558
+
559
+ let tiledeskChannelMessage = req.body.payload;
560
+ winston.verbose("(wab) tiledeskChannelMessage: ", tiledeskChannelMessage)
561
+ let project_id = req.body.payload.id_project;
562
+
563
+ let CONTENT_KEY = "whatsapp-" + project_id;
564
+ let settings = await db.get(CONTENT_KEY);
565
+
566
+ if (!settings) {
567
+ return res.status(400).send({ success: false, error: "WhatsApp is not installed for the project_id: " + project_id });
568
+ }
569
+
570
+ let receiver_list = req.body.receiver_list;
486
571
  let phone_number_id = req.body.phone_number_id;
487
- console.log("phone_number_id: ", phone_number_id);
488
572
 
489
573
  if (!tiledeskChannelMessage.attributes.attachment.template) {
490
574
  return res.status(400).send({ success: false, error: "Message must contain a template." })
@@ -507,7 +591,6 @@ router.post('/tiledesk/broadcast', async (req, res) => {
507
591
  let whatsappJsonMessage = await tlr.toWhatsapp(customTiledeskJsonMessage, whatsapp_receiver.phone_number);
508
592
  winston.verbose("(wab) message created for receiver: " + whatsapp_receiver.phone_number);
509
593
  winston.verbose("(wab) whatsappJsonMessage", whatsappJsonMessage);
510
- console.log("(wab) whatsappJsonMessage", JSON.stringify(whatsappJsonMessage, null, 2));
511
594
 
512
595
  //winston.debug("(wab) End of list")
513
596
  //return res.sendStatus(200);
@@ -530,24 +613,21 @@ router.post('/tiledesk/broadcast', async (req, res) => {
530
613
  execute(receiver_list[i])
531
614
  } else {
532
615
  winston.debug("(wab) End of list")
533
- console.log("errors: ", JSON.stringify(errors, null, 2))
534
616
  return res.status(200).send({ success: true, message: "Broadcast terminated", messages_sent: messages_sent, errors: errors });
535
617
  }
536
618
  })
537
619
  }
538
620
  execute(receiver_list[0]);
539
621
  }
540
-
541
-
542
-
543
622
  })
623
+ */
544
624
 
545
625
  router.post('/tiledesk', async (req, res) => {
546
626
 
547
627
  winston.verbose("(wab) Message received from Tiledesk")
548
628
 
549
629
  var tiledeskChannelMessage = req.body.payload;
550
- winston.verbose("(wab) tiledeskChannelMessage: ", tiledeskChannelMessage)
630
+ winston.debug("(wab) tiledeskChannelMessage: ", tiledeskChannelMessage)
551
631
  var project_id = req.body.payload.id_project;
552
632
 
553
633
  // get settings from mongo
@@ -1041,6 +1121,7 @@ router.get("/templates/:project_id", async (req, res) => {
1041
1121
 
1042
1122
  })
1043
1123
 
1124
+ /*
1044
1125
  router.get("/ext/templates/:project_id", async (req, res) => {
1045
1126
  winston.verbose("(wab) /ext/templates");
1046
1127
 
@@ -1069,6 +1150,24 @@ router.get("/ext/templates/:project_id", async (req, res) => {
1069
1150
  }
1070
1151
 
1071
1152
  })
1153
+ */
1154
+
1155
+ //router.delete("/ext/")
1156
+
1157
+ /*
1158
+ router.get("/ext/:project_id", async (req, res) => {
1159
+ winston.verbose("(wab) /ext/");
1160
+
1161
+ let project_id = req.params.project_id;
1162
+ let CONTENT_KEY = "whatsapp-" + project_id;
1163
+ let settings = await db.get(CONTENT_KEY);
1164
+
1165
+ if (!settings) {
1166
+ return res.status(200).send({ success: false, message: "WhatsApp not installed for the project_id " + project_id })
1167
+ }
1168
+ return res.status(200).send({ success: true, settings: settings })
1169
+ })
1170
+ */
1072
1171
 
1073
1172
  // *****************************
1074
1173
  // ********* FUNCTIONS *********
@@ -1138,6 +1237,19 @@ async function startApp(settings, callback) {
1138
1237
  callback(null);
1139
1238
  }
1140
1239
  })
1240
+
1241
+ api.startRoute({
1242
+ DB: db,
1243
+ API_URL: API_URL,
1244
+ GRAPH_URL: GRAPH_URL,
1245
+ BASE_FILE_URL: BASE_FILE_URL
1246
+ }, (err) => {
1247
+ if (!err) {
1248
+ winston.info("(wab) API route successfully started.")
1249
+ } else {
1250
+ winston.info("(wab) Unable to start API route.")
1251
+ }
1252
+ })
1141
1253
  }
1142
1254
 
1143
1255
  function connectRedis() {
package/logs/app.log CHANGED
@@ -1,4 +0,0 @@
1
- info: (wab) Starting Whatsapp App
2
- info: (wab) API_URL: https://tiledesk-server-pre.herokuapp.com
3
- info: (wab) BASE_URL: https://tiledesk-whatsapp-app-pre.giovannitroisi3.repl.co
4
- info: (wab) GRAPH_URL: https://graph.facebook.com/v14.0/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-whatsapp-connector",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Tiledesk Whatsapp connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/routes/api.js ADDED
@@ -0,0 +1,237 @@
1
+ const { json } = require('body-parser');
2
+ const express = require('express');
3
+ var winston = require('../winston');
4
+ const router = express.Router({ mergeParams: true });
5
+
6
+ const { TemplateManager } = require('../tiledesk/TemplateManager');
7
+ const { TiledeskWhatsappTranslator } = require('../tiledesk/TiledeskWhatsappTranslator');
8
+ const { TiledeskWhatsapp } = require('../tiledesk/TiledeskWhatsapp');
9
+
10
+ let db = null;
11
+ let API_URL = null;
12
+ let GRAPH_URL = null;
13
+ let BASE_FILE_URL = null;
14
+
15
+ router.get('/', async (req, res) => {
16
+ res.status(200).send({ message: "API route works"})
17
+ })
18
+
19
+ router.get('/disconnect/:project_id', async (req, res) => {
20
+
21
+ let project_id = req.params.project_id;
22
+ let CONTENT_KEY = "whatsapp-" + project_id;
23
+
24
+ let settings = await db.get(CONTENT_KEY);
25
+
26
+ if (!settings) {
27
+ return res.status(200).send({ success: false, message: "Unable to find content for the projectId " + project_id })
28
+ }
29
+
30
+ if (req.query.ghost && req.query.ghost === 'true') {
31
+ settings.trashed = true;
32
+ await db.set(CONTENT_KEY, settings);
33
+ winston.verbose("(wab) Content deleted.");
34
+ res.status(200).send({ success: true, message: "Disconnected" });
35
+
36
+ } else {
37
+ await db.remove(CONTENT_KEY);
38
+ winston.verbose("(wab) Content deleted.");
39
+ res.status(200).send({ success: true, message: "Disconnected" });
40
+ }
41
+
42
+ })
43
+
44
+ router.post('/customer/io', async (req, res) => {
45
+ winston.verbose("Event received from customer.io");
46
+ winston.debug("Body (customer.io): ", req.body);
47
+
48
+ let tiledeskChannelMessage = req.body;
49
+
50
+ let project_id = req.body.id_project;
51
+
52
+ let CONTENT_KEY = "whatsapp-" + project_id;
53
+ let settings = await db.get(CONTENT_KEY);
54
+
55
+ if (!settings) {
56
+ return res.status(500).send({ success: false, message: "WhatsApp not installed for the projectId: " + project_id });
57
+ }
58
+
59
+ const tlr = new TiledeskWhatsappTranslator();
60
+
61
+ let receiver = tiledeskChannelMessage.receiver_phone_number;
62
+ let phone_number_id = tiledeskChannelMessage.phone_number_id;
63
+
64
+ let whatsappJsonMessage = await tlr.toWhatsapp(tiledeskChannelMessage, receiver);
65
+ winston.debug("[ CUSTOMER.IO ] whatsappJsonMessage: ", JSON.stringify(whatsappJsonMessage, null, 2));
66
+
67
+ if (whatsappJsonMessage) {
68
+ const twClient = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL, API_URL: API_URL, BASE_FILE_URL: BASE_FILE_URL });
69
+
70
+ twClient.sendMessage(phone_number_id, whatsappJsonMessage).then((response) => {
71
+ winston.verbose("(wab) Message sent to WhatsApp! " + response.status + " " + response.statusText);
72
+ res.status(200).send({ success: true, message: "Message sent!"});
73
+ }).catch((err) => {
74
+ res.status(400).send({ success: false, error: err });
75
+ winston.error("(wab) error send message: ", err.data);
76
+ })
77
+
78
+ } else {
79
+ res.status(400).send({ success: false, error: "whatsappJsonMessage is undefined" });
80
+ winston.error("(wab) error send message: ", err);
81
+ }
82
+ })
83
+
84
+
85
+ router.get("/:project_id", async (req, res) => {
86
+ winston.verbose("(wab) /api/project_id");
87
+
88
+ let project_id = req.params.project_id;
89
+ let CONTENT_KEY = "whatsapp-" + project_id;
90
+ let settings = await db.get(CONTENT_KEY);
91
+
92
+ if (!settings) {
93
+ return res.status(200).send({ success: false, message: "WhatsApp not installed for the project_id " + project_id })
94
+ }
95
+ return res.status(200).send({ success: true, settings: settings })
96
+ })
97
+
98
+ router.get("/templates/:project_id", async (req, res) => {
99
+ winston.verbose("(wab) /api/templates");
100
+
101
+ let project_id = req.params.project_id;
102
+
103
+ let CONTENT_KEY = "whatsapp-" + project_id;
104
+ let settings = await db.get(CONTENT_KEY);
105
+
106
+ if (settings) {
107
+
108
+ if (settings.business_account_id) {
109
+ let tm = new TemplateManager({ token: settings.wab_token, business_account_id: settings.business_account_id, GRAPH_URL: GRAPH_URL })
110
+ let templates = await tm.getTemplates();
111
+ if (templates) {
112
+ res.status(200).send(templates.data);
113
+ } else {
114
+ res.status(500).send({ success: false, code: '02', message: "A problem occurred while getting templates from WhatsApp" })
115
+ }
116
+
117
+ } else {
118
+ res.status(500).send({ success: false, code: '03', message: "Missing parameter 'WhatsApp Business Account ID'. Please update your app." })
119
+ }
120
+
121
+ } else {
122
+ res.status(400).send({ success: false, code: '01', message: "WhatsApp not installed for the project_id " + project_id })
123
+ }
124
+ })
125
+
126
+ router.post('/tiledesk/broadcast', async (req, res) => {
127
+ winston.verbose("(wab) Action received from Tiledesk (Broadcast)");
128
+ winston.debug("Body (broadcast): ",JSON.stringify(req.body, null, 2));
129
+
130
+ let body = req.body;
131
+
132
+ let project_id = body.id_project;
133
+ let receiver_list = body.receiver_list;
134
+ let phone_number_id = body. phone_number_id;
135
+ let template = body.template;
136
+
137
+ let CONTENT_KEY = "whatsapp-" + project_id;
138
+ let settings = await db.get(CONTENT_KEY);
139
+
140
+ if (!settings) {
141
+ return res.status(400).send({ success: false, error: "WhatsApp is not installed for the project_id: " + project_id });
142
+ }
143
+
144
+ if (!settings.business_account_id) {
145
+ return res.status(400).send({ success: false, error: "Missing parameter 'WhatsApp Business Account ID'. Please update your app."})
146
+ }
147
+
148
+ const tm = new TemplateManager({ token: settings.wab_token, business_account_id: settings.business_account_id, GRAPH_URL: GRAPH_URL })
149
+ const tlr = new TiledeskWhatsappTranslator();
150
+ const twClient = new TiledeskWhatsapp({ token: settings.wab_token, GRAPH_URL: GRAPH_URL, API_URL: API_URL, BASE_FILE_URL: BASE_FILE_URL });
151
+
152
+ let response = await tm.getTemplates();
153
+ let templates = response.data;
154
+
155
+ let selected_template = templates.find(t => t.name === template.name);
156
+ let params_object = await tm.generateParamsObject(selected_template);
157
+
158
+ // Send messages
159
+ let messages_sent = 0;
160
+ let errors = [];
161
+ let error_count = 0;
162
+
163
+ if (receiver_list) {
164
+ let i = 0;
165
+ async function execute(receiver) {
166
+ let whatsappJsonMessage = await tlr.createTemplateMessage(selected_template, receiver, params_object);
167
+ winston.debug("(wab) whatsappJsonMessage: ", JSON.stringify(whatsappJsonMessage, null, 2));
168
+
169
+ await twClient.sendMessage(phone_number_id, whatsappJsonMessage).then((response) => {
170
+ winston.verbose("(wab) Message sent to WhatsApp! " + response.status + " " + response.statusText);
171
+ messages_sent += 1;
172
+ i += 1;
173
+ if (i < receiver_list.length) {
174
+ execute(receiver_list[i])
175
+ } else {
176
+ winston.debug("(wab) End of list")
177
+ return res.status(200).send({ success: true, message: "Broadcast terminated", messages_sent: messages_sent, errors: errors });
178
+ }
179
+ }).catch((err) => {
180
+ winston.error("(wab) error send message: " + err.response.data.error.message);
181
+ errors.push({ receiver: receiver.phone_number, error: err.response.data.error.message });
182
+ i += 1;
183
+ if (i < receiver_list.length) {
184
+ execute(receiver_list[i])
185
+ } else {
186
+ winston.debug("(wab) End of list")
187
+ return res.status(200).send({ success: true, message: "Broadcast terminated", messages_sent: messages_sent, errors: errors });
188
+ }
189
+ })
190
+ }
191
+ execute(receiver_list[0]);
192
+ }
193
+
194
+ })
195
+
196
+
197
+ // start api route from whatsappRoute
198
+ async function startRoute(settings, callback) {
199
+ winston.info("(wab) Starting api route", settings);
200
+
201
+ if (!settings.DB) {
202
+ winston.error("(wab) db id mandatory. Exit...");
203
+ return callback('Missing parameter: db');
204
+ } else {
205
+ db = settings.DB;
206
+ winston.info("(wab) db " + db);
207
+ }
208
+
209
+ if (!settings.GRAPH_URL) {
210
+ winston.error("(wab) GRAPH_URL is mandatory. Exit...");
211
+ return callback('Missing parameter: GRAPH_URL');
212
+ } else {
213
+ GRAPH_URL = settings.GRAPH_URL;
214
+ winston.info("(wab) GRAPH_URL: " + GRAPH_URL);
215
+ }
216
+
217
+ if (!settings.API_URL) {
218
+ winston.error("(wab) API_URL is mandatory. Exit...");
219
+ return callback('Missing parameter: API_URL');
220
+ } else {
221
+ API_URL = settings.API_URL;
222
+ winston.info("(wab) API_URL: " + API_URL);
223
+ }
224
+
225
+ if (!settings.BASE_FILE_URL) {
226
+ winston.error("(wab) BASE_FILE_URL is mandatory. Exit...");
227
+ return callback('Missing parameter: BASE_FILE_URL');
228
+ } else {
229
+ BASE_FILE_URL = settings.BASE_FILE_URL;
230
+ winston.info("(wab) BASE_FILE_URL: " + BASE_FILE_URL);
231
+ }
232
+
233
+
234
+
235
+ }
236
+
237
+ module.exports = { router: router, startRoute: startRoute };
@@ -89,11 +89,10 @@
89
89
  </div>
90
90
 
91
91
  </div>
92
-
93
-
94
92
 
95
93
 
96
94
  <!-- INFO BOX -->
95
+ {{#unless popup_view}}
97
96
  <div class="info-box">
98
97
 
99
98
  <div class="info-list">
@@ -126,10 +125,11 @@
126
125
  </ul>
127
126
  </div>
128
127
  </div>
128
+ {{/unless}}
129
129
 
130
130
  <!-- Docs Section -->
131
+ {{#unless popup_view}}
131
132
  <div class="docs-box">
132
-
133
133
 
134
134
  <div class="docs-section">
135
135
  <p style="margin-top: 20px; font-size: 18px; font-weight: 600;">Before you start</p>
@@ -159,6 +159,7 @@
159
159
 
160
160
  </div>
161
161
  </div>
162
+ {{/unless}}
162
163
 
163
164
 
164
165
  <!-- CONFIGURE BOX -->
@@ -198,7 +199,7 @@
198
199
  <label class="input-label" for="wab_token">Whatsapp Token
199
200
  </label>
200
201
  <div style="display: flex; flex-direction: row; align-items: center;">
201
- <input type="text" required class="form-control custom-input" name="wab_token" value="{{ wab_token }}" placeholder="Enter the Whatsapp Token">
202
+ <input id="tkn" type="text" required class="form-control custom-input" name="wab_token" value="{{ wab_token }}" placeholder="Enter the Whatsapp Token">
202
203
  <span style="margin-left: 10px;">
203
204
  <i class="fa fa-question-circle custom-tooltip">
204
205
  <span class="custom-tooltiptext">This is the permanent WhatsApp Business token.</span>
@@ -263,7 +264,8 @@
263
264
  </div>
264
265
  {{else}}
265
266
  <div style="width: 500px; text-align: right;">
266
- <input type="submit" class="btn" style="width: 200px; background-color: #0ba2dc; color: white; font-weight: 500;" value="Connect">
267
+ <input type="submit" class="btn" style="width: 200px; background-color: #0ba2dc; color: white; font-weight: 500;" value="Connect"
268
+ onclick="postMessage('connectWhatsapp')">
267
269
  </div>
268
270
  {{/if}}
269
271
  </form>
@@ -288,7 +290,7 @@
288
290
  <input type="hidden" name="project_id" value="{{ project_id }}">
289
291
  <input type="hidden" name="token" value="{{ token }}">
290
292
  <input type="hidden" name="subscription_id" value="{{ subscription_id }}">
291
- <input type="submit" class="btn disconnect-button" style="margin-top: 10px; width: 160px;" value="Disconnect">
293
+ <input type="submit" class="btn disconnect-button" style="margin-top: 10px; width: 160px;" value="Disconnect" onclick="postMessage('disconnectWhatsapp')">
292
294
  </form>
293
295
  </div>
294
296
  {{else}}
@@ -331,6 +333,19 @@
331
333
  console.error('Async: Could not copy text: ', err);
332
334
  }
333
335
  }
336
+
337
+ function postMessage(action) {
338
+
339
+ const tkn = document.getElementById('tkn').value;
340
+ let connected = false;
341
+ if (tkn) {
342
+ connected = true;
343
+ }
344
+ const msg = { action: action, calledBy: 'whatsapp_proxy', connected: connected}
345
+ window.parent.postMessage(msg, '*');
346
+ }
347
+
334
348
  </script>
349
+
335
350
 
336
351
  </body>
@@ -107,7 +107,7 @@
107
107
  <input type="hidden" name="project_id" value="{{ project_id }}" />
108
108
  <input type="hidden" name="app_id" value="{{ app_id }}" />
109
109
  <input type="hidden" name="token" value="{{ token }}" />
110
- <input type="submit" class="btn uninstall-button" value="Yes, uninstall">
110
+ <input type="submit" class="btn uninstall-button" value="Yes, uninstall" onclick="postMessage('uninstallWhatsapp')">
111
111
  </form>
112
112
  </div>
113
113
  </div>
@@ -138,7 +138,8 @@
138
138
  <input type="hidden" name="project_id" value="{{ project_id }}" />
139
139
  <input type="hidden" name="app_id" value="{{ app_id }}" />
140
140
  <input type="hidden" name="token" value="{{ token }}" />
141
- <input type="submit" class="btn install-button" value="Install">
141
+ <input type="submit" class="btn install-button" value="Install" onclick="postMessage('installWhatsapp')">
142
+ <!--<input type="submit" class="btn install-button" value="Install" onclick="postMessage('installWhatsapp')">-->
142
143
  </form>
143
144
  </div>
144
145
  </div>
@@ -213,6 +214,13 @@
213
214
 
214
215
  <p style="font-size: 18px;"><b>What's new?</b></p>
215
216
 
217
+ <div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 15px;">
218
+ <div>
219
+ <p>Bug fixes and performance improvements</p>
220
+ </div>
221
+ <p style="font-size: 12px; color: #676767; margin-bottom: 0px;">Version <b>0.1.52</b></p>
222
+ </div>
223
+
216
224
  <div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 15px;">
217
225
  <div>
218
226
  <p style="margin-bottom: 0px">Bug fixes</p>
@@ -238,14 +246,13 @@
238
246
  <p style="font-size: 12px; color: #676767; margin-bottom: 0px;">Version <b>0.1.48</b></p>
239
247
  </div>
240
248
 
241
- <div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 15px;">
242
- <div>
243
- <p style="margin-bottom: 0px">Bug fixes and minor improvements</p>
244
- <!--<p>Bug fixes and performance improvements</p>-->
245
- </div>
246
- <p style="font-size: 12px; color: #676767; margin-bottom: 0px;">Version <b>0.1.45</b></p>
247
- </div>
248
-
249
249
  <hr style="margin-top: 50px; margin-bottom: 20px">
250
+
251
+ <script>
252
+ function postMessage(action) {
253
+ const msg = { action: action, calledBy: 'whatsapp_proxy' }
254
+ window.parent.postMessage(msg, '*');
255
+ }
256
+ </script>
250
257
 
251
258
  </body>
@@ -47,30 +47,6 @@ class MessageHandler {
47
47
  return tiledeskCommandMessage;
48
48
  }
49
49
 
50
- /*
51
- generateMessageObjectOriginal(command_message) {
52
- let parentUid = this.tiledeskChannelMessage.uid
53
- //command_message.uid = this.tiledeskChannelMessage.uid + "_" + index;
54
- command_message.uid = this.tiledeskChannelMessage.uid;
55
- if(command_message.text) command_message.text = command_message.text.trim()//remove black msg with only spaces
56
- command_message.language = message.language;
57
- command_message.recipient = message.recipient;
58
- command_message.recipient_fullname = message.recipient_fullname;
59
- command_message.sender = message.sender;
60
- command_message.sender_fullname = message.sender_fullname;
61
- command_message.channel_type = message.channel_type;
62
- command_message.status = message.status;
63
- command_message.isSender = message.isSender;
64
- command_message.attributes? command_message.attributes.commands = true : command_message.attributes = {commands : true}
65
- command_message.attributes.parentUid = parentUid //added to manage message STATUS UPDATES
66
- command_message.attributes = {...message.attributes, ...command_message.attributes}
67
- //this.addedNew(command_message)
68
- //callback();
69
-
70
- return command_message
71
- }
72
- */
73
-
74
50
  }
75
51
 
76
52
  module.exports = { MessageHandler }
@@ -42,6 +42,121 @@ class TemplateManager {
42
42
  })
43
43
  }
44
44
 
45
+ async generateParamsObject2(template) {
46
+ let params;
47
+ let body_component = template.components.find(c => c.type === 'BODY');
48
+
49
+ this.generateBody(body_component).then((body_params) => {
50
+ params = {
51
+ body: body_params
52
+ }
53
+ return params;
54
+ })
55
+
56
+
57
+ }
58
+
59
+ async generateBody(body_component) {
60
+ let body_params = [];
61
+ return new Promise((resolve, reject) => {
62
+ if (body_component) {
63
+ if (body_component.example) {
64
+ body_component.example.body_text[0].forEach((p, i) => {
65
+ body_params.push({ type: "text", text: null })
66
+ })
67
+ }
68
+ }
69
+ resolve(body_params)
70
+ })
71
+ }
72
+
73
+ async generateParamsObject(template) {
74
+ let header_params = [];
75
+ let body_params = [];
76
+ let url_button_params = [];
77
+ let header_component = template.components.find(c => c.type === 'HEADER');
78
+ let body_component = template.components.find(c => c.type === 'BODY');
79
+ let buttons_component = template.components.find(c => c.type === 'BUTTONS');
80
+ let url_button_component;
81
+
82
+ if (buttons_component) {
83
+ url_button_component = buttons_component.buttons.find(c => c.type === 'URL')
84
+ }
85
+
86
+ if (header_component) {
87
+ if (header_component.example) {
88
+ if (header_component.example.header_text) {
89
+ header_component.example.header_text.forEach((p, i) => {
90
+ header_params.push({ type: "text", text: null })
91
+ })
92
+ }
93
+
94
+ if (header_component.example.header_handle) {
95
+ if (header_component.format === 'IMAGE') {
96
+ header_component.example.header_handle.forEach((p, i) => {
97
+ header_params.push({ type: header_component.format, image: { link: null } })
98
+ })
99
+ }
100
+ if (header_component.format === 'DOCUMENT') {
101
+ header_component.example.header_handle.forEach((p, i) => {
102
+ header_params.push({ type: header_component.format, document: { link: null } })
103
+ })
104
+ }
105
+ }
106
+
107
+ } else {
108
+
109
+ if (header_component.format === 'LOCATION') {
110
+ header_params.push({ type: header_component.format, location: { latitude: null, longitude: null, name: null, address: null } })
111
+ }
112
+ else {
113
+ console.log("(Template Manager) Unrecognized Header: ", header_component)
114
+ }
115
+
116
+ }
117
+ }
118
+
119
+ if (body_component) {
120
+ if (body_component.example) {
121
+ body_component.example.body_text[0].forEach((p, i) => {
122
+ body_params.push({ type: "text", text: null })
123
+ })
124
+ }
125
+ }
126
+
127
+ if (url_button_component) {
128
+ if (url_button_component.example) {
129
+ url_button_component.example.forEach((p, i) => {
130
+ url_button_params.push({ type: "text", text: null })
131
+ })
132
+ }
133
+ }
134
+
135
+
136
+ /*
137
+ let params = {
138
+ header: header_params,
139
+ body: body_params,
140
+ buttons: url_button_params
141
+ }
142
+ */
143
+
144
+ let params = {}
145
+
146
+ if (header_params.length > 0) {
147
+ params.header = header_params;
148
+ }
149
+
150
+ if (body_params.length > 0) {
151
+ params.body = body_params;
152
+ }
153
+
154
+ if (url_button_params.length > 0) {
155
+ params.buttons = url_button_params;
156
+ }
157
+ return params;
158
+ }
159
+
45
160
  async getTemplateNamespace() {
46
161
 
47
162
  return await axios({
@@ -157,7 +157,7 @@ class TiledeskChannel {
157
157
  winston.debug("(wab) [TiledeskChannel] get departments response.data: ", response.data)
158
158
  return response.data;
159
159
  }).catch((err) => {
160
- winston.error("(wab) [TiledeskChannel] get departments error: ", err);
160
+ winston.error("(wab) [TiledeskChannel] get departments error");
161
161
  })
162
162
  }
163
163
 
@@ -85,6 +85,9 @@ class TiledeskWhatsapp {
85
85
  let download_url = response.data.url;
86
86
  let mime_type = response.data.mime_type;
87
87
  let extension = mime_type.substring(mime_type.lastIndexOf("/") + 1);
88
+ if (extension === 'ogg') {
89
+ extension = 'mp3'
90
+ }
88
91
  let tid = this.getId();
89
92
  let type = "media-" + tid + "." + extension;
90
93
 
@@ -127,7 +130,6 @@ class TiledeskWhatsapp {
127
130
 
128
131
  async uploadMedia(path, type) {
129
132
  let url = this.base_file_url + "/" + type + "/public/";
130
- console.log("upload media url: ", url);
131
133
  winston.debug("(wab) [TiledeskWhatsapp] Uploading file...");
132
134
 
133
135
  const form = new FormData();
@@ -143,7 +145,6 @@ class TiledeskWhatsapp {
143
145
  return await axios.post(url, form, request_config).then((response) => {
144
146
 
145
147
  winston.debug("(wab) [TiledeskWhatsapp] upload response: ", response.data);
146
- console.log("\n\nresponse.data: ", response.data)
147
148
  if (type == "images") {
148
149
  //let image_url = "https://tiledesk-server-pre.herokuapp.com/images/?path=" + response.data.filename;
149
150
  let image_url = this.base_file_url + "/images/?path=" + response.data.filename;
@@ -30,7 +30,7 @@ const path = require('path');
30
30
 
31
31
  this.log = false;
32
32
  }
33
-
33
+
34
34
 
35
35
  /*
36
36
  *************** START ***************
@@ -260,7 +260,7 @@ const path = require('path');
260
260
 
261
261
  }
262
262
  else if (tiledeskChannelMessage.attributes.attachment.template) {
263
- winston.debug("(wab) [Translator] template: ", tiledeskChannelMessage.attributes.attachment.template)
263
+ winston.verbose("(wab) [Translator] template: ", tiledeskChannelMessage.attributes.attachment.template)
264
264
 
265
265
  let template = tiledeskChannelMessage.attributes.attachment.template;
266
266
 
@@ -338,6 +338,99 @@ const path = require('path');
338
338
  }
339
339
  }
340
340
 
341
+ async createTemplateMessage(template, receiver, params) {
342
+
343
+ let whatsapp_message = {
344
+ messaging_product: TiledeskWhatsappTranslator.WHATSAPP_MESSAGING_PRODUCT,
345
+ to: receiver.phone_number,
346
+ type: "template"
347
+ }
348
+
349
+ whatsapp_message.template = {
350
+ name: template.name,
351
+ language: {
352
+ code: template.language
353
+ }
354
+ }
355
+
356
+ /*
357
+ let params_filled = await this.fillParams(params, receiver);
358
+
359
+ let components = [];
360
+ if (params_filled && params_filled.header) {
361
+ let component = {
362
+ type: "header",
363
+ parameters: params_filled.header
364
+ }
365
+ components.push(component);
366
+ }
367
+ if (params_filled && params_filled.body) {
368
+ let component = {
369
+ type: "body",
370
+ parameters: params_filled.body
371
+ }
372
+ components.push(component);
373
+ }
374
+ if (params_filled && params_filled.buttons) {
375
+
376
+ let component = {
377
+ type: "button",
378
+ sub_type: "url",
379
+ index: "0",
380
+ parameters: params_filled.buttons
381
+ }
382
+ components.push(component);
383
+ }
384
+ */
385
+
386
+ let components = [];
387
+
388
+
389
+ if (receiver.header_params) {
390
+ let component = {
391
+ type: "header",
392
+ parameters: receiver.header_params
393
+ }
394
+ components.push(component);
395
+ }
396
+
397
+ if (receiver.body_params) {
398
+ let component = {
399
+ type: "body",
400
+ parameters: receiver.body_params
401
+ }
402
+ components.push(component);
403
+ }
404
+
405
+ if (receiver.buttons_params) {
406
+
407
+ let component = {
408
+ type: "button",
409
+ sub_type: "url",
410
+ index: "0",
411
+ parameters: receiver.buttons_params
412
+ }
413
+ components.push(component);
414
+ }
415
+
416
+ if (receiver.url_buttons_params) {
417
+
418
+ let component = {
419
+ type: "button",
420
+ sub_type: "url",
421
+ index: "0",
422
+ parameters: receiver.url_buttons_params
423
+ }
424
+ components.push(component);
425
+ }
426
+
427
+ if (components.length > 0) {
428
+ whatsapp_message.template.components = components;
429
+ }
430
+
431
+
432
+ return whatsapp_message;
433
+ }
341
434
 
342
435
  async toTiledesk(whatsappChannelMessage, from, media_url) {
343
436
 
@@ -353,9 +446,17 @@ const path = require('path');
353
446
  return data;
354
447
  }
355
448
 
449
+ else if (whatsappChannelMessage.type == 'button') {
450
+ var tiledeskMessage = {
451
+ text: whatsappChannelMessage.button.text, // or whatsappChannelMessage.button.payload (?)
452
+ senderFullname: from,
453
+ channel: { name: TiledeskWhatsappTranslator.CHANNEL_NAME }
454
+ }
455
+ return tiledeskMessage;
456
+ }
356
457
 
357
458
  // interactive message
358
- if (whatsappChannelMessage.type == 'interactive') {
459
+ else if (whatsappChannelMessage.type == 'interactive') {
359
460
 
360
461
  // list reply
361
462
  if (whatsappChannelMessage.interactive.type == 'list_reply') {
@@ -413,7 +514,7 @@ const path = require('path');
413
514
  }
414
515
 
415
516
  // media message - image
416
- if (whatsappChannelMessage.type == 'image') {
517
+ else if (whatsappChannelMessage.type == 'image') {
417
518
 
418
519
  let text = "Image attached"
419
520
  if (whatsappChannelMessage.image.caption) {
@@ -433,7 +534,7 @@ const path = require('path');
433
534
  }
434
535
 
435
536
  // media message - video
436
- if (whatsappChannelMessage.type == 'video') {
537
+ else if (whatsappChannelMessage.type == 'video') {
437
538
 
438
539
  let text = "Video attached"
439
540
  if (whatsappChannelMessage.video.caption) {
@@ -455,7 +556,7 @@ const path = require('path');
455
556
  }
456
557
 
457
558
  // media message - document
458
- if (whatsappChannelMessage.type == 'document') {
559
+ else if (whatsappChannelMessage.type == 'document') {
459
560
 
460
561
  let text = "Document attached"
461
562
  if (whatsappChannelMessage.document.caption) {
@@ -477,7 +578,7 @@ const path = require('path');
477
578
  }
478
579
 
479
580
  // media message - audio
480
- if (whatsappChannelMessage.type == 'audio') {
581
+ else if (whatsappChannelMessage.type == 'audio') {
481
582
 
482
583
  let text = "Audio attached"
483
584
  /*if (whatsappChannelMessage.document.caption) {
@@ -497,13 +598,61 @@ const path = require('path');
497
598
  }
498
599
  return tiledeskMessage;
499
600
  }
601
+
602
+ else {
603
+ winston.verbose("(wab) [Translator] unsupported whatsapp messsage type");
604
+ return null;
605
+ }
606
+ }
607
+
608
+ async fillParams(params, rcv_option) {
609
+ winston.verbose("(wab) [Translator] fillParams...");
610
+
611
+ if (!params) {
612
+ return null;
613
+ }
614
+
615
+ let header_params = params.header;
616
+ if (header_params) {
617
+ header_params.forEach((param, i) => {
618
+ if (param.type === "text") {
619
+ param.text = rcv_option.header_params[i];
620
+ }
621
+ if (param.type === "IMAGE") {
622
+ param.image = {
623
+ link: rcv_option.header_params[i]
624
+ }
625
+ }
626
+ if (param.type === 'DOCUMENT') {
627
+ param.document = {
628
+ link: rcv_option.header_params[i]
629
+ }
630
+ }
631
+ if (param.type === 'LOCATION') {
632
+ // Check how to send location template!
633
+ }
634
+ })
635
+ }
636
+
637
+ let body_params = params.body;
638
+ if (body_params) {
639
+ body_params.forEach((param, i) => {
640
+ param.text = rcv_option.body_params[i];
641
+ })
642
+ }
643
+
644
+ let buttons_params = params.buttons;
645
+ if (buttons_params) {
646
+ buttons_params.forEach((param, i) => {
647
+ param.text = rcv_option.buttons_params[i];
648
+ })
649
+ }
650
+ return params;
500
651
  }
501
652
 
502
653
 
503
654
  async sanitizeTiledeskMessage(tiledeskJsonMessage, rcv_option) {
504
- console.log("tiledeskJsonMessage: ", JSON.stringify(tiledeskJsonMessage, null, 2))
505
- //console.log("rcv_option: ", rcv_option)
506
- console.log("Sanitizing...")
655
+ winston.verbose("(wab) [Translator] Sanitizing...");
507
656
 
508
657
  if (!tiledeskJsonMessage.attributes.attachment.template.params) {
509
658
  return tiledeskJsonMessage;
@@ -515,11 +664,19 @@ const path = require('path');
515
664
  if (param.type === "text") {
516
665
  param.text = rcv_option.header_params[i];
517
666
  }
518
- if (param.type === "image") {
667
+ if (param.type === "IMAGE") {
519
668
  param.image = {
520
669
  link: rcv_option.header_params[i]
521
670
  }
522
671
  }
672
+ if (param.type === 'DOCUMENT') {
673
+ param.document = {
674
+ link: rcv_option.header_params[i]
675
+ }
676
+ }
677
+ if (param.type === 'LOCATION') {
678
+ // Check how to send location template!
679
+ }
523
680
  })
524
681
  }
525
682
 
@@ -532,17 +689,11 @@ const path = require('path');
532
689
 
533
690
  let buttons_params = tiledeskJsonMessage.attributes.attachment.template.params.buttons;
534
691
  if (buttons_params) {
535
- /*
536
- buttons_params.forEach((button, i) => {
537
- button.parameters[0].text = rcv_option.buttons_params[i];
538
- })
539
- */
540
692
  buttons_params.forEach((param, i) => {
541
693
  param.text = rcv_option.buttons_params[i];
542
694
  })
543
695
  }
544
696
 
545
- console.log("tiledeskJsonMessage: ", JSON.stringify(tiledeskJsonMessage, null, 2))
546
697
  return tiledeskJsonMessage;
547
698
  }
548
699
  /*
Binary file
Binary file