@tiledesk/tiledesk-voice-twilio-connector 0.1.13 → 0.1.14-rc1

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
@@ -37,7 +37,6 @@ var redis_client;
37
37
 
38
38
  //UTILS
39
39
  const CHANNEL_NAME = require('./tiledesk/constants').CHANNEL_NAME
40
- const TYPE_MESSAGE = require('./tiledesk/constants').TYPE_MESSAGE
41
40
  const CALL_STATUS = require('./tiledesk/constants').CALL_STATUS
42
41
  const VOICE_NAME = require('./tiledesk/constants').VOICE_NAME
43
42
  const VOICE_LANGUAGE = require('./tiledesk/constants').VOICE_LANGUAGE
@@ -54,6 +53,13 @@ let twilio = require('twilio');
54
53
  const VoiceResponse = require('twilio').twiml.VoiceResponse;
55
54
  const { MessagingResponse } = require('twilio').twiml;
56
55
 
56
+ let start1= ''
57
+ let time = null;
58
+
59
+ /*UTILS*/
60
+ const utilsMess = require('./tiledesk/utils-message.js')
61
+ const TYPE_MESSAGE = require('./tiledesk/constants').TYPE_MESSAGE
62
+
57
63
  router.get("/", async (req, res) => {
58
64
  res.send("Welcome to Tiledesk-voice-twilio connector");
59
65
  });
@@ -61,6 +67,7 @@ router.get("/", async (req, res) => {
61
67
 
62
68
  // TILEDESK WEBHOOK: message from tiledesk to user (chatbot/agent messagges)
63
69
  router.post("/tiledesk", async (req, res) => {
70
+ winston.debug("(vxml) Message received from Tiledesk in projectID: "+ req.body.payload.id_project + ' ---- and text: '+req.body.payload.text )
64
71
  let tiledeskMessage = req.body.payload
65
72
  let project_id = tiledeskMessage.id_project
66
73
 
@@ -73,6 +80,15 @@ router.post("/tiledesk", async (req, res) => {
73
80
  });
74
81
  tdChannel.setProjectId(project_id)
75
82
 
83
+ /*SKIP INFO MESSAGES*/
84
+ /*SKIP CURRENT USER MESSAGES*/
85
+ if(!utilsMess.messageType(TYPE_MESSAGE.INFO, tiledeskMessage) && !(tiledeskMessage.sender.indexOf("vxml") > -1) ){
86
+ winston.verbose("> whook SAVE MESSAGE TO QUEUE " + JSON.stringify(tiledeskMessage) );
87
+ start1 = new Date().getTime();
88
+ console.log("(WH) time: ", new Date().getTime() - time)
89
+ console.log("(WH) received message: ", tiledeskMessage.text, ' --- at time:', new Date(), start1)
90
+ }
91
+
76
92
  await tdChannel.addMessageToQueue(tiledeskMessage)
77
93
 
78
94
  res.send("(vxml) Message received from Voice VXML Proxy");
@@ -82,7 +98,8 @@ router.post("/tiledesk", async (req, res) => {
82
98
 
83
99
  // TWILIO WEBHOOK : message from user to tiledesk
84
100
  router.post('/webhook/:id_project', async (req, res) => {
85
- winston.verbose('(voice) called POST /webhook/:id_project '+ new Date(), req.params)
101
+ winston.debug('(voice) called POST /webhook/:id_project '+ new Date(), req.params)
102
+ let start_call = new Date().getTime();
86
103
 
87
104
  let project_id = req.params.id_project;
88
105
  let callSid = req.body.CallSid;
@@ -117,11 +134,14 @@ router.post('/webhook/:id_project', async (req, res) => {
117
134
  BASE_URL: BASE_URL
118
135
  });
119
136
 
137
+ let start2 = new Date().getTime();
120
138
  let user = await tdChannel.signIn(from, settings);
121
139
  if(!user){
122
140
  res.status(401).send({message: "Cannot able to signIn with current caller phone :" + from});
123
141
  return;
124
142
  }
143
+ let end2 = new Date().getTime();
144
+ console.log('Time after signIn: ', end2-start2, '[ms]')
125
145
 
126
146
  //let conversation_id = await tdChannel.getConversation(ani, callId, user.token);
127
147
  let conversation_id = await tdChannel.generateConversation(from, callSid, user.token);
@@ -146,7 +166,7 @@ router.post('/webhook/:id_project', async (req, res) => {
146
166
 
147
167
  await redis_client.set('tiledesk:vxml:'+callSid+':session', JSON.stringify(session_data), {'EX': 86400});
148
168
 
149
-
169
+ let start4 = new Date().getTime();
150
170
  let tiledeskMessage= {
151
171
  text:'/start',
152
172
  senderFullname: from,
@@ -164,7 +184,8 @@ router.post('/webhook/:id_project', async (req, res) => {
164
184
  if(!message){
165
185
  return res.status(503).send({ message: "Bad response: Quota exceeded" })
166
186
  }
167
-
187
+ let end4 = new Date().getTime();
188
+ console.log('Time after sent message /start: ', end4-start4, '[ms]')
168
189
 
169
190
  //generate Tiledesk wait message
170
191
  let delayTime = await voiceChannel.getNextDelayTimeForCallId(callSid)
@@ -181,12 +202,17 @@ router.post('/webhook/:id_project', async (req, res) => {
181
202
  res.set('Content-Type', 'text/xml');
182
203
  res.status(200).send(messageToVXML);
183
204
 
205
+ let end_call = new Date().getTime();
206
+ console.log('Time to responde to /webhook/:id_project : ', end_call-start_call, '[ms]')
207
+
184
208
  });
185
209
 
186
210
 
187
211
  router.post('/nextblock/:callSid/', async(req, res) => {
188
- winston.verbose("(vxml) called POST /nextblock" + new Date(), req.body);
189
- winston.verbose("(vxml) called POST /nextblock query", req.query);
212
+ let start_call = new Date()
213
+ winston.debug("(vxml) called POST /nextblock ", req.body);
214
+ winston.debug("(vxml) called POST /nextblock query ", req.query);
215
+ console.log('/nextblock at: ', new Date(), 'with text:', req.body.SpeechResult)
190
216
 
191
217
  let usertext = req.body.SpeechResult;
192
218
  let confidence = req.body.Confidence
@@ -236,18 +262,21 @@ router.post('/nextblock/:callSid/', async(req, res) => {
236
262
 
237
263
  let message = {}, queue = []
238
264
  queue = await tdChannel.getMessagesFromQueue(conversation_id)
239
- winston.debug('/NEXT controllo coda--> ', queue.length, usertext)
265
+ winston.verbose('/NEXT controllo coda--> '+ queue.length + ' ' + usertext)
240
266
  if(queue.length === 0 && (usertext === '' || !usertext)){
241
267
  winston.debug('QUEUE is empty--> ',queue)
242
268
 
243
269
  //CASE: queue is empty --> generate Tiledesk wait message and manage delayTime
244
270
  let delayTime = await voiceChannel.getNextDelayTimeForCallId(callSid)
271
+ console.log('delay /nextblock -->', delayTime)
245
272
  message = await tdChannel.generateWaitTdMessage(from, delayTime)
246
273
  //update delayIndex for wait command message time
247
274
  await voiceChannel.saveDelayIndexForCallId(from)
248
275
 
249
276
  } else if(queue.length > 0 && (usertext === '' || !usertext)){
250
277
 
278
+ let end1 = new Date().getTime()
279
+ console.log('Time between wh message and /nextblock queue message:', end1-start1, '[ms] (message:', queue[0].text , ') at time', new Date())
251
280
  //CASE: queue has at least one message to reproduce --> get message from tiledesk queue and reset delayTime
252
281
  message = queue[0]
253
282
  winston.debug('QUEUE --> ',queue[0])
@@ -266,10 +295,14 @@ router.post('/nextblock/:callSid/', async(req, res) => {
266
295
  type: 'text',
267
296
  channel: { name: CHANNEL_NAME }
268
297
  };
298
+ let startSend= new Date().getTime()
269
299
  let tdMessage = await tdChannel.send(tiledeskMessage, user.token, conversation_id);
270
300
  winston.debug("message sent : ", tdMessage);
301
+ let endSend = new Date().getTime();
302
+ console.log('Time to send messagge ( ', usertext, '): ', endSend - startSend, '[ms] at time', new Date())
271
303
  //generate Tiledesk wait message
272
304
  let delayTime = await voiceChannel.getNextDelayTimeForCallId(callSid)
305
+ console.log('(message sent) delay /nextblock -->', delayTime)
273
306
  message = await tdChannel.generateWaitTdMessage(from, delayTime)
274
307
  //update delayIndex for wait command message time
275
308
  await voiceChannel.saveDelayIndexForCallId(callSid)
@@ -279,11 +312,96 @@ router.post('/nextblock/:callSid/', async(req, res) => {
279
312
  // convert response to vxml
280
313
  let messageToVXML = await tdTranslator.toVXML(message, callSid, vxmlAttributes)
281
314
  winston.debug("(voice) VXML to SEND: "+ messageToVXML);
282
- winston.debug("(voice) send response to TWILIO : "+ new Date());
315
+
316
+ let end_call = new Date()
317
+ console.log('Time to responde to /nextblock/:callSid : ', end_call-start_call, '[ms]')
283
318
 
284
319
  // Render the response as XML in reply to the webhook request
285
320
  res.set('Content-Type', 'text/xml');
286
321
  res.status(200).send(messageToVXML);
322
+
323
+ })
324
+
325
+ router.post('/speechresult/:callSid', async (req, res) => {
326
+
327
+ let startTime = new Date();
328
+ winston.verbose("(vxml) called POST /speechresult ", req.body);
329
+ winston.verbose("(vxml) called POST /speechresult query ", req.query);
330
+
331
+ let usertext = req.body.SpeechResult;
332
+ let confidence = req.body.Confidence
333
+ let callSid = req.params.callSid;
334
+
335
+ let sessionInfo;
336
+ let project_id, conversation_id, user;
337
+ let from, to;
338
+
339
+ let redis_data = await redis_client.get('tiledesk:vxml:'+callSid+':session');
340
+ //let redis_data = await redis_client.hGetAll('tiledesk:vxml:'+callId);
341
+ if (!redis_data) {
342
+ return res.status(500).send({ success: "false", message: "Can't retrive data for callSid ->" + callSid });
343
+ }
344
+ sessionInfo = JSON.parse(redis_data)
345
+ project_id = sessionInfo.project_id;
346
+ from = sessionInfo.from;
347
+ to = sessionInfo.to;
348
+ conversation_id = sessionInfo.conversation_id;
349
+ user = sessionInfo.user;
350
+
351
+ let vxmlAttributes = {
352
+ voiceName: VOICE_NAME,
353
+ voiceLanguage: VOICE_LANGUAGE,
354
+ callSid: callSid,
355
+ };
356
+
357
+ const tdChannel = new TiledeskChannel({
358
+ API_URL: API_URL,
359
+ redis_client: redis_client
360
+ })
361
+ tdChannel.setProjectId(project_id);
362
+
363
+ const tdTranslator = new TiledeskTwilioTranslator({
364
+ BASE_URL: BASE_URL
365
+ });
366
+
367
+ winston.verbose("(vxml) usertext "+usertext);
368
+ let message = {};
369
+ if(usertext){
370
+ let tiledeskMessage= {
371
+ text:usertext,
372
+ senderFullname: from,
373
+ type: 'text',
374
+ channel: { name: CHANNEL_NAME }
375
+ };
376
+ let tdMessage = await tdChannel.send(tiledeskMessage, user.token, conversation_id);
377
+ winston.debug("message sent : ", tdMessage);
378
+ //generate Tiledesk wait message
379
+ let delayTime = await voiceChannel.getNextDelayTimeForCallId(callSid)
380
+ message = await tdChannel.generateWaitTdMessage(from, 50)
381
+ //update delayIndex for wait command message time
382
+ await voiceChannel.saveDelayIndexForCallId(callSid)
383
+
384
+ }else {
385
+
386
+ let delayTime = await voiceChannel.getNextDelayTimeForCallId(callSid)
387
+ message = await tdChannel.generateWaitTdMessage(from, 50)
388
+ //update delayIndex for wait command message time
389
+ await voiceChannel.saveDelayIndexForCallId(from)
390
+ }
391
+
392
+ // convert response to vxml
393
+ let messageToVXML = await tdTranslator.toVXML(message, callSid, vxmlAttributes)
394
+ winston.debug("(voice) VXML to SEND: "+ messageToVXML);
395
+
396
+ let endTime = new Date()
397
+ let diffTIme = endTime - startTime
398
+ winston.verbose("(voice) send response to TWILIO in : " + diffTIme + "ms");
399
+
400
+ // Render the response as XML in reply to the webhook request
401
+ res.set('Content-Type', 'text/xml');
402
+ res.status(200).send(messageToVXML);
403
+
404
+
287
405
  })
288
406
 
289
407
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-voice-twilio-connector",
3
- "version": "0.1.13",
3
+ "version": "0.1.14-rc1",
4
4
  "description": "Tiledesk VOICE Twilio connector",
5
5
  "license": "MIT",
6
6
  "author": "Gabriele Panico",
@@ -179,7 +179,7 @@ class TiledeskChannel {
179
179
  winston.debug("[TiledeskChannel] send message response: ", response.data);
180
180
  return response.data;
181
181
  }).catch((err) => {
182
- winston.error("[TiledeskChannel] send message: ", err);
182
+ winston.error("[TiledeskChannel] send message: ", err.response?.data);
183
183
  return null;
184
184
  })
185
185
 
@@ -69,7 +69,7 @@ class TiledeskTwilioTranslator {
69
69
 
70
70
  //MANAGE CLOSE info message
71
71
  const isInfoSupport = utils.messageType(TYPE_MESSAGE.INFO_SUPPORT, msg)
72
- winston.verbose("[TiledeskVXMLTranslator] isInfoSupport::"+ isInfoSupport);
72
+ winston.debug("[TiledeskVXMLTranslator] isInfoSupport:"+ isInfoSupport);
73
73
  if(isInfoSupport && utils.infoMessageType(msg) === INFO_MESSAGE_TYPE.CHAT_CLOSED){
74
74
  const hangUp = this.hangupCall(xml)
75
75
  return hangUp;
@@ -83,7 +83,7 @@ class TiledeskTwilioTranslator {
83
83
 
84
84
  /** check for WAIT **/
85
85
  const isWait = this.checkIfIsWait(msg);
86
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isWait:"+ isWait);
86
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isWait:"+ isWait);
87
87
  if(isWait){
88
88
  const delayForm = await this.delayVXMLConverter(xml, msg, vxmlAttributes);
89
89
  return delayForm;
@@ -91,7 +91,7 @@ class TiledeskTwilioTranslator {
91
91
 
92
92
  /** check for DTMF FORM **/
93
93
  const isDtmfForm = this.checkIfIsDTMFForm(msg);
94
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isDtmfForm: "+ isDtmfForm);
94
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isDtmfForm: "+ isDtmfForm);
95
95
  if(isDtmfForm){
96
96
  const DTMFForm = await this.dtmfFormVXMLConverter(xml, msg, vxmlAttributes);
97
97
  return DTMFForm;
@@ -99,7 +99,7 @@ class TiledeskTwilioTranslator {
99
99
 
100
100
  /** check for BLIND TRANSFER **/
101
101
  const isBlindFransfer = this.checkIfIsBlindFransfer(msg);
102
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isBlindFransfer: "+ isBlindFransfer);
102
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isBlindFransfer: "+ isBlindFransfer);
103
103
  if(isBlindFransfer){
104
104
  const blindTransfer = await this.blindTransferVXMLConverter(xml, msg, vxmlAttributes);
105
105
  return blindTransfer;
@@ -107,7 +107,7 @@ class TiledeskTwilioTranslator {
107
107
 
108
108
  /** check for DTMF MENU **/
109
109
  const isMenu = this.checkIfIsDTMFMenuMessage(msg);
110
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isMenu: "+ isMenu);
110
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isMenu: "+ isMenu);
111
111
  if(isMenu){
112
112
  const menu = await this.menuVXMLConverter(xml, msg, vxmlAttributes);
113
113
  return menu;
@@ -115,14 +115,14 @@ class TiledeskTwilioTranslator {
115
115
 
116
116
  /** check for SPEECH FORM **/
117
117
  const isSpeechForm = this.checkIfIsSpeechFormMessage(msg);
118
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isSpeechForm: "+ isSpeechForm);
118
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isSpeechForm: "+ isSpeechForm);
119
119
  if(isSpeechForm){
120
120
  const form = await this.speechFormVXMLConverter(xml, msg, vxmlAttributes);
121
121
  return form;
122
122
  }
123
123
 
124
124
  /** check for FORM (PlayPrompt action) **/
125
- winston.verbose("[TiledeskVXMLTranslator] toVXML: isPrompt: true");
125
+ winston.debug("[TiledeskVXMLTranslator] toVXML: isPrompt: true");
126
126
  const prompt = await this.playPromptVXMLConverter(xml, msg, vxmlAttributes);
127
127
  return prompt;
128
128
 
@@ -264,7 +264,7 @@ class TiledeskTwilioTranslator {
264
264
  const gather = rootEle.ele("Gather", { input: "speech"})
265
265
 
266
266
  const queryUrl = '?intentName='+ querystring.encode(xmlAttributes.intentName) + "&previousIntentTimestamp="+Date.now();
267
- gather.att("action", this.BASE_URL + '/nextblock/' + xmlAttributes.callSid + queryUrl)
267
+ gather.att("action", this.BASE_URL + '/speechresult/' + xmlAttributes.callSid + queryUrl)
268
268
  .att("method", "POST")
269
269
  .att("language", xmlAttributes.voiceLanguage)
270
270
  .att('speechTimeout', "auto")
@@ -272,9 +272,9 @@ class TiledeskTwilioTranslator {
272
272
  if(xmlAttributes && xmlAttributes.noInputTimeout){
273
273
  gather.att("timeout", xmlAttributes.noInputTimeout/1000 ).up();
274
274
  }
275
- if(xmlAttributes && xmlAttributes.incompleteSpeechTimeout){
275
+ /*if(xmlAttributes && xmlAttributes.incompleteSpeechTimeout){
276
276
  gather.att("speechTimeout", xmlAttributes.incompleteSpeechTimeout/1000 ).up();
277
- }
277
+ }*/
278
278
 
279
279
  const prompt = this.promptVXML(gather, message, xmlAttributes);
280
280