@tiledesk/tiledesk-tybot-connector 0.2.83 → 0.2.85

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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@
5
5
  available on:
6
6
  ▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
7
7
 
8
+ # v0.2.85
9
+ - Improved "If operating hours" action with time slots
10
+ - Other fix (?)
11
+
12
+ # v0.2.84
13
+ - Fixed "guest#" bug
14
+ - Fixed default_context in AskGPTv2
15
+
8
16
  # v0.2.83
9
17
  - Added support for advanced context in AskGPTv2
10
18
 
@@ -44,28 +44,22 @@ class TiledeskChatbot {
44
44
 
45
45
  async replyToMessage(message, callback) {
46
46
  return new Promise( async (resolve, reject) => {
47
- // get bot info
48
- // if (this.log) {
49
- // console.log("replyToMessage():", JSON.stringify(message));
50
- // }
51
47
  let lead = null;
52
48
  if (message.request) {
53
49
  this.request = message.request;
54
- lead = message.request.lead;
55
- if (lead && lead.fullname) {
56
- if (this.log) {console.log("lead.fullname => params.userFullname:", lead.fullname)}
57
- // await this.addParameter(this.requestId, "userFullname", lead.fullname);
58
- await this.addParameter("userFullname", lead.fullname);
59
- }
60
- if (lead && lead.email) {
61
- if (this.log) {console.log("lead.email => params.userEmail:", lead.email)}
62
- // await this.addParameter(this.requestId, "userEmail", lead.email);
63
- await this.addParameter("userEmail", lead.email);
64
- }
65
- }
66
- if (this.log) {
67
- console.log("replyToMessage() > lead found:", JSON.stringify(lead));
50
+ // lead = message.request.lead;
51
+ // if (lead && lead.fullname) {
52
+ // if (this.log) {console.log("lead.fullname => params.userFullname:", lead.fullname)}
53
+ // await this.addParameter("userFullname", lead.fullname);
54
+ // }
55
+ // if (lead && lead.email) {
56
+ // if (this.log) {console.log("lead.email => params.userEmail:", lead.email)}
57
+ // await this.addParameter("userEmail", lead.email);
58
+ // }
68
59
  }
60
+ // if (this.log) {
61
+ // console.log("replyToMessage() > lead found:", JSON.stringify(lead));
62
+ // }
69
63
 
70
64
  // reset lockedIntent on direct user invocation ( /intent or action => this only?)
71
65
  if (message.sender != "_tdinternal") {
@@ -793,15 +787,8 @@ class TiledeskChatbot {
793
787
  fullname: all_parameters['userFullname'],
794
788
  phone: all_parameters['userPhone']
795
789
  }
796
- // tdclient.updateLeadData(leadId, all_parameters['userEmail'], all_parameters['userFullname'], null, () => {
797
- tdclient.updateLead(leadId, nativeAttributes, null, null, () => {
790
+ tdclient.updateLead(leadId, nativeAttributes, null, null, () => {
798
791
  if (this.log) {console.log("Lead updated.")}
799
- // tdclient.updateRequestAttributes(requestId, {
800
- // preChatForm: all_parameters,
801
- // updated: Date.now
802
- // }, () => {
803
- // if (this.log) {console.log("Prechat updated.");}
804
- // });
805
792
  });
806
793
  };
807
794
  }
@@ -23,6 +23,14 @@ class TiledeskChatbotConst {
23
23
  static REQ_DECODED_JWT_KEY = "decodedCustomJWT";
24
24
  static REQ_REQUESTER_IS_AUTHENTICATED_KEY = "strongAuthenticated";
25
25
  static USER_INPUT = "_userInput";
26
+ static REQ_LEAD_USERFULLNAME_KEY = "userFullname";
27
+ static REQ_LEAD_EMAIL_KEY = "userEmail";
28
+ static REQ_USER_PHONE_KEY = "userPhone";
29
+ static REQ_CURRENT_PHONE_NUMBER_KEY = "currentPhoneNumber";
30
+ static REQ_USER_LEAD_ID_KEY = "userLeadId";
31
+ static REQ_USER_COMPANY_KEY = "userCompany";
32
+ static REQ_TICKET_ID_KEY = "ticketId";
33
+
26
34
 
27
35
  // static REQ_DEPARTMENT_ID_KEY = "tdDepartmentId";
28
36
  // static REQ_PROJECT_ID_KEY = "projectId";
@@ -594,19 +594,16 @@ class TiledeskChatbotUtil {
594
594
  // await chatbot.addParameter("lastUserDocumentType", null);
595
595
  // }
596
596
  if (message && message.request && message.request.lead) {
597
+ console.log("lead found. lead.email:", message.request.lead.email, "lead.fullname:", message.request.lead.fullname)
597
598
  if (message.request.lead.email) {
598
- await chatbot.addParameter("userEmail", message.request.lead.email);
599
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_LEAD_EMAIL_KEY, message.request.lead.email);
599
600
  }
600
- if (message.request.lead.fullname && !message.request.lead.fullname.startsWith("guest#")) {
601
+ // if (message.request.lead.fullname && !message.request.lead.fullname.startsWith("guest#")) {
602
+ if (message.request.lead.fullname) {
601
603
  // worth saving
604
+ console.log("worth saving. lead found. lead.email:", message.request.lead.email, "lead.fullname:", message.request.lead.fullname)
602
605
  try {
603
- // const current_userFullname = await chatbot.getParameter("userFullname");
604
- // if (current_userFullname && current_userFullname.startsWith("guest#")) { // replace if exists as guest#
605
- // await chatbot.addParameter("userFullname", message.request.lead.fullname);
606
- // }
607
- // else if (!current_userFullname) {
608
- await chatbot.addParameter("userFullname", message.request.lead.fullname);
609
- // }
606
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_LEAD_USERFULLNAME_KEY, message.request.lead.fullname);
610
607
  }
611
608
  catch(error) {
612
609
  console.error("Error on setting userFullname:", error);
@@ -617,22 +614,22 @@ class TiledeskChatbotUtil {
617
614
  }
618
615
  // console.log("Getting userPhone:", JSON.stringify(message.request));
619
616
  if (message.request.lead.phone) {
620
- await chatbot.addParameter("userPhone", message.request.lead.phone);
617
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_USER_PHONE_KEY, message.request.lead.phone);
621
618
  }
622
619
  if (message.request.lead.lead_id && message.request.lead.lead_id.startsWith("wab-")) {
623
620
  const splits = message.request.lead.lead_id.split("-");
624
621
  if (splits && splits.length > 1) {
625
- await chatbot.addParameter("currentPhoneNumber",splits[1]);
622
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_CURRENT_PHONE_NUMBER_KEY,splits[1]);
626
623
  }
627
624
  }
628
625
  if (message.request.lead._id) {
629
- await chatbot.addParameter("userLeadId", message.request.lead._id);
626
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_USER_LEAD_ID_KEY, message.request.lead._id);
630
627
  }
631
628
  if (message.request.lead.company) {
632
- await chatbot.addParameter("userCompany", message.request.lead.company);
629
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_USER_COMPANY_KEY, message.request.lead.company);
633
630
  }
634
631
  if (message.request.ticket_id) {
635
- await chatbot.addParameter("ticketId", message.request.ticket_id);
632
+ await chatbot.addParameter(TiledeskChatbotConst.REQ_TICKET_ID_KEY, message.request.ticket_id);
636
633
  }
637
634
  }
638
635
 
@@ -702,6 +699,7 @@ class TiledeskChatbotUtil {
702
699
  const value_type = typeof value;
703
700
  //if (projectId === "641864da99c1fb00131ba495") {console.log("641864da99c1fb00131ba495 > importing payload parameter:", key, "value:", value, "type:", value_type);}
704
701
  //await chatbot.addParameter(key, String(value));
702
+ console.log("Adding from message.attributes:", key, "->", value);
705
703
  await chatbot.addParameter(key, value);
706
704
  }
707
705
  }
@@ -777,6 +775,8 @@ class TiledeskChatbotUtil {
777
775
  // "sub": "guest",
778
776
  // "jti": "f053af3d-14ca-411b-9903-78bd74e24218"
779
777
  // }
778
+ // let userFullname = await chatbot.getParameter(TiledeskChatbotConst.REQ_LEAD_USERFULLNAME_KEY);
779
+ // console.log("userFullname:", userFullname);
780
780
  }
781
781
 
782
782
  static actionsToDirectives(actions) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.2.83",
3
+ "version": "0.2.85",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -49,6 +49,7 @@ const { DirAskGPTV2 } = require('./directives/DirAskGPTV2');
49
49
  const { DirAssistant } = require('./directives/DirAssistant');
50
50
  const { DirReplyV2 } = require('./directives/DirReplyV2');
51
51
  const { DirIfOnlineAgentsV2 } = require('./directives/DirIfOnlineAgentsV2');
52
+ const { DirContactUpdate } = require('./directives/DirContactUpdate');
52
53
 
53
54
  class DirectivesChatbotPlug {
54
55
 
@@ -239,10 +240,6 @@ class DirectivesChatbotPlug {
239
240
  // go on
240
241
  // console.log("Going on to next directive...");
241
242
  }
242
- // }
243
- // catch(error) {
244
- // console.error("Error on locks:", error);
245
- // }
246
243
 
247
244
  }
248
245
  if (directive == null || (directive !== null && directive["name"] === undefined)) {
@@ -272,8 +269,6 @@ class DirectivesChatbotPlug {
272
269
  let next_dir = await this.nextDirective(this.directives);
273
270
  this.process(next_dir);
274
271
  }
275
- // let next_dir = await this.nextDirective(this.directives);
276
- // this.process(next_dir);
277
272
  });
278
273
  }
279
274
  else if (directive_name === Directives.MESSAGE) {
@@ -360,8 +355,6 @@ class DirectivesChatbotPlug {
360
355
  let next_dir = await this.nextDirective(this.directives);
361
356
  this.process(next_dir);
362
357
  }
363
- // let next_dir = await this.nextDirective(this.directives);
364
- // this.process(next_dir);
365
358
  });
366
359
  }
367
360
  else if (directive_name === Directives.IF_ONLINE_AGENTS) {
@@ -448,57 +441,6 @@ class DirectivesChatbotPlug {
448
441
  this.process(next_dir);
449
442
  });
450
443
  }
451
- // else if (directive_name === Directives.WHEN_OPEN) {
452
- // // DEPRECATED
453
- // const whenOpenDir = new DirWhenOpen(
454
- // {
455
- // tdclient: this.context.tdclient, // matches open hours
456
- // log: false
457
- // });
458
- // whenOpenDir.execute(directive, directives, curr_directive_index, async () => {
459
- // let next_dir = await this.nextDirective(this.directives);
460
- // this.process(next_dir);
461
- // });
462
- // }
463
- // else if (directive_name === Directives.WHEN_CLOSED) {
464
- // // DEPRECATED
465
- // const whenOpenDir = new DirWhenOpen(
466
- // {
467
- // tdclient: this.context.tdclient,
468
- // checkOpen: false, // matches closed hours
469
- // log: false
470
- // });
471
- // whenOpenDir.execute(directive, directives, curr_directive_index, async () => {
472
- // let next_dir = await this.nextDirective(this.directives);
473
- // this.process(next_dir);
474
- // });
475
- // }
476
- // else if (directive_name === Directives.IF_AGENTS) {
477
- // // DEPRECATED
478
- // const ifNoAgentsDir = new DirIfAvailableAgents(
479
- // {
480
- // tdclient: this.context.tdclient,
481
- // checkAgents: true, // check available agents > 0
482
- // log: false
483
- // });
484
- // ifNoAgentsDir.execute(directive, directives, curr_directive_index, async () => {
485
- // let next_dir = await this.nextDirective(this.directives);
486
- // this.process(next_dir);
487
- // });
488
- // }
489
- // else if (directive_name === Directives.IF_NO_AGENTS) {
490
- // // DEPRECATED
491
- // const ifNoAgentsDir = new DirIfAvailableAgents(
492
- // {
493
- // tdclient: this.context.tdclient,
494
- // checkAgents: false, // check no available agents
495
- // log: false
496
- // });
497
- // ifNoAgentsDir.execute(directive, directives, curr_directive_index, async () => {
498
- // let next_dir = await this.nextDirective(this.directives);
499
- // this.process(next_dir);
500
- // });
501
- // }
502
444
  else if (directive_name === Directives.AGENT) {
503
445
  // console.log("...DirMoveToAgent");
504
446
  new DirMoveToAgent(context).execute(directive, async () => {
@@ -506,35 +448,6 @@ class DirectivesChatbotPlug {
506
448
  this.process(next_dir);
507
449
  });
508
450
  }
509
- // else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) { // DEPRECATED?
510
- // // let depId;
511
- // // if (context.supportRequest && context.supportRequest.department && context.supportRequest.department._id) {
512
- // // depId = context.supportRequest.department._id;
513
- // // console.log("context.supportRequest", JSON.stringify(context.supportRequest));
514
- // // const agentDir = new DirMoveToAgent(
515
- // // {
516
- // // tdclient: context.tdclient,
517
- // // requestId: context.requestId,
518
- // // depId: depId
519
- // // }
520
- // // );
521
- // // if (!directive.action) {
522
- // // directive.action = {}
523
- // // directive.action = {
524
- // // whenOnlineOnly: true
525
- // // }
526
- // // }
527
- // new DirMoveToAgent(context).execute(directive, async () => {
528
- // let next_dir = await this.nextDirective(this.directives);
529
- // this.process(next_dir);
530
- // });
531
- // // }
532
- // // else {
533
- // // console.log("Warning. DepId null while calling 'WHEN_ONLINE_MOVE_TO_AGENT' directive")
534
- // // let next_dir = await this.nextDirective(this.directives);
535
- // // this.process(next_dir);
536
- // // }
537
- // }
538
451
  else if (directive_name === Directives.CLOSE) {
539
452
  // console.log("Exec close()")
540
453
  new DirClose(context).execute(directive, async () => {
@@ -770,6 +683,13 @@ class DirectivesChatbotPlug {
770
683
  }
771
684
  });
772
685
  }
686
+ else if (directive_name === Directives.CONTACT_UPDATE) {
687
+ console.log("...CONTACT_UPDATE");
688
+ new DirContactUpdate(context).execute(directive, async () => {
689
+ let next_dir = await this.nextDirective(this.directives);
690
+ this.process(next_dir);
691
+ });
692
+ }
773
693
  else {
774
694
  //console.log("Unhandled Post-message Directive:", directive_name);
775
695
  let next_dir = await this.nextDirective(this.directives);
@@ -62,8 +62,8 @@ class DirAskGPTV2 {
62
62
  let temperature;
63
63
  let max_tokens;
64
64
  let top_k;
65
- let default_context = "Answer if and ONLY if the answer is contained in the context provided. If the answer is not contained in the context provided ALWAYS answer with <NOANS>\n{context}"
66
-
65
+ let default_context = "You are an helpful assistant for question-answering tasks.\nUse ONLY the following pieces of retrieved context to answer the question.\nIf you don't know the answer, just say that you don't know.\nIf none of the retrieved context answer the question, add this word to the end <NOANS>\n\n{context}";
66
+
67
67
  let source = null;
68
68
 
69
69
  if (!action.question || action.question === '') {
@@ -0,0 +1,97 @@
1
+ const { Filler } = require('../Filler');
2
+ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
3
+ const { TiledeskChatbotUtil } = require('../../models/TiledeskChatbotUtil');
4
+ let axios = require('axios');
5
+ const { TiledeskChatbotConst } = require('../../models/TiledeskChatbotConst');
6
+
7
+ class DirContactUpdate {
8
+
9
+ constructor(context) {
10
+ if (!context) {
11
+ throw new Error('context object is mandatory.');
12
+ }
13
+ this.context = context;
14
+ this.projectId = context.projectId;
15
+ this.requestId = context.requestId;
16
+ this.supportRequest = context.supportRequest;
17
+ this.token = context.token;
18
+ this.tdcache = context.tdcache;
19
+ this.tdclient = context.tdclient;
20
+ this.log = context.log;
21
+ }
22
+
23
+ execute(directive, callback) {
24
+ let action;
25
+ if (directive.action) {
26
+ action = directive.action;
27
+ if (!action.attributes) {
28
+ action.attributes = {}
29
+ }
30
+ action.attributes.fillParams = true;
31
+ }
32
+ else {
33
+ console.error("Incorrect directive (no action provided):", directive);
34
+ callback();
35
+ return;
36
+ }
37
+ this.go(action, () => {
38
+ callback();
39
+ });
40
+ }
41
+
42
+ async go(action, callback) {
43
+ if (this.log) {console.log("(DirContactUpdate) start. Update properties:", action.update); }
44
+ const contactProperties = action.update;
45
+
46
+ // fill
47
+ let requestAttributes = null;
48
+ if (this.tdcache) {
49
+ requestAttributes =
50
+ await TiledeskChatbot.allParametersStatic(
51
+ this.tdcache, this.requestId
52
+ );
53
+ }
54
+ const filler = new Filler();
55
+ let updateProperties = {}
56
+ for (const [key, value] of Object.entries(contactProperties)) {
57
+ updateProperties[key] = filler.fill(value, requestAttributes);
58
+ if (this.log) {console.log("(DirContactUpdate) updating property:", key, "value:", value); }
59
+ }
60
+ const leadId = requestAttributes[TiledeskChatbotConst.REQ_USER_LEAD_ID_KEY];
61
+ this.tdclient.updateLead(leadId, updateProperties, null, null, () => {
62
+ if (this.log) {console.log("(DirContactUpdate) Lead updated.", updateProperties);}
63
+ // send hidden info to update widget lead fullname only if it is a conversation!
64
+ if (this.log) {console.log("(DirContactUpdate) requestId:", this.requestId); }
65
+ if (this.log) {console.log("(DirContactUpdate) updateProperties:", updateProperties); }
66
+ if (this.log) {console.log("(DirContactUpdate) updateProperties['userFullname']:", updateProperties['userFullname']); }
67
+ if (this.requestId.startsWith("support-group") && updateProperties['userFullname']) {
68
+ if (this.log) {console.log("(DirContactUpdate) send hidden info to update widget lead fullname"); }
69
+ const userFullname = updateProperties['userFullname'];
70
+ const updateLeadDataOnWidgetMessage = {
71
+ type: "text",
72
+ text: "Updated lead fullname on widget with: " + userFullname,
73
+ attributes: {
74
+ // subtype: "info",
75
+ updateUserFullname: userFullname
76
+ }
77
+ };
78
+ if (this.log) {console.log("(DirContactUpdate) sending updateLeadDataOnWidgetMessage:", updateLeadDataOnWidgetMessage); }
79
+ this.context.tdclient.sendSupportMessage(
80
+ this.requestId,
81
+ updateLeadDataOnWidgetMessage,
82
+ (err) => {
83
+ if (err) {
84
+ console.error("(DirContactUpdate) Error sending reply:", err);
85
+ }
86
+ if (this.log) {console.log("(DirContactUpdate) hidden message sent:", updateLeadDataOnWidgetMessage);}
87
+ callback();
88
+ });
89
+ }
90
+ else {
91
+ callback();
92
+ }
93
+ });
94
+ }
95
+ }
96
+
97
+ module.exports = { DirContactUpdate };
@@ -1,4 +1,5 @@
1
1
  // const { TiledeskClient } = require('@tiledesk/tiledesk-client');
2
+ let axios = require('axios');
2
3
  const { DirIntent } = require('./DirIntent');
3
4
  const ms = require('minimist-string');
4
5
 
@@ -9,6 +10,7 @@ class DirIfOpenHours {
9
10
  throw new Error('context object is mandatory.');
10
11
  }
11
12
  this.tdclient = context.tdclient;
13
+ this.context = context;
12
14
  // this.tdclient = new TiledeskClient({
13
15
  // projectId: context.projectId,
14
16
  // token: context.token,
@@ -34,7 +36,8 @@ class DirIfOpenHours {
34
36
  // log: context.log
35
37
  // }
36
38
  // );
37
- this.log = context.log;
39
+ //this.log = context.log;
40
+ this.log = true;
38
41
  }
39
42
 
40
43
  execute(directive, callback) {
@@ -67,11 +70,13 @@ class DirIfOpenHours {
67
70
  }
68
71
 
69
72
  go(action, callback) {
73
+
70
74
  const trueIntent = action.trueIntent;
71
75
  const falseIntent = action.falseIntent;
72
76
  const trueIntentAttributes = action.trueIntentAttributes;
73
77
  const falseIntentAttributes = action.falseIntentAttributes;
74
78
  const stopOnConditionMet = action.stopOnConditionMet;
79
+
75
80
  if (trueIntent && trueIntent.trim() === "") {
76
81
  trueIntent = null;
77
82
  }
@@ -84,36 +89,155 @@ class DirIfOpenHours {
84
89
  callback();
85
90
  return;
86
91
  }
87
- this.tdclient.openNow((err, result) => {
88
- if (this.log) {console.log("openNow():", result);}
89
- if (err) {
90
- console.error("DirIfOpenHours Error:", err);
91
- callback();
92
+
93
+ let slot_id = null;
94
+ if (action.slot_id) {
95
+ slot_id = action.slot_id;
96
+ }
97
+
98
+ const server_base_url = process.env.API_ENDPOINT || process.env.API_URL;
99
+ if (this.log) { console.log("DirAskGPT ApiEndpoint URL: ", server_base_url); }
100
+
101
+ let isopen_url = server_base_url + "/projects/" + this.context.projectId + "/isopen";
102
+ if (slot_id) {
103
+ isopen_url = isopen_url.concat("?timeSlot=" + slot_id);
104
+ }
105
+
106
+ const HTTPREQUEST = {
107
+ url: isopen_url,
108
+ headers: {
109
+ 'Content-Type': 'application/json',
110
+ 'Authorization': 'JWT ' + this.context.token
111
+ },
112
+ method: 'GET'
113
+ }
114
+ if (this.log) { console.log("DirIfOpenHours HTTPREQUEST", HTTPREQUEST); }
115
+
116
+ this.#myrequest(
117
+ HTTPREQUEST, async (err, resbody) => {
118
+ if (this.log && err) {
119
+ console.log("DirIfOpenHours error: ", err);
120
+ }
121
+ if (this.log) { console.log("DirIfOpenHours resbody:", resbody); }
122
+
123
+ if (err) {
124
+ if (callback) {
125
+ if (falseIntent) {
126
+ let intentDirective = DirIntent.intentDirectiveFor(falseIntent);
127
+ if (this.log) {console.log("!agents (openHours) => falseIntent", falseIntent);}
128
+ this.intentDir.execute(intentDirective, () => {
129
+ callback(stopOnConditionMet);
130
+ });
131
+ }
132
+ }
133
+ } else {
134
+ if (resbody.isopen && resbody.isopen === true) {
135
+ if (trueIntent) {
136
+ let intentDirective = DirIntent.intentDirectiveFor(trueIntent);
137
+ if (this.log) {console.log("agents (openHours) => trueIntent");}
138
+ this.intentDir.execute(intentDirective, () => {
139
+ callback(stopOnConditionMet);
140
+ });
141
+ }
142
+ callback();
143
+ return;
144
+ } else {
145
+ if (falseIntent) {
146
+ let intentDirective = DirIntent.intentDirectiveFor(falseIntent);
147
+ if (this.log) {console.log("!agents (openHours) => falseIntent", falseIntent);}
148
+ this.intentDir.execute(intentDirective, () => {
149
+ callback(stopOnConditionMet);
150
+ });
151
+ }
152
+ callback();
153
+ return;
154
+ }
155
+ }
92
156
  }
93
- else if (result && result.isopen) {
94
- if (trueIntent) {
95
- let intentDirective = DirIntent.intentDirectiveFor(trueIntent);
96
- if (this.log) {console.log("agents (openHours) => trueIntent");}
97
- this.intentDir.execute(intentDirective, () => {
98
- callback(stopOnConditionMet);
99
- });
157
+ )
158
+
159
+ // this.tdclient.openNow(action.slot_id, (err, result) => {
160
+ // console.log("openNow():", result);
161
+ // if (this.log) {console.log("openNow():", result);}
162
+ // if (err) {
163
+ // console.error("*** DirIfOpenHours Error:", err);
164
+ // callback();
165
+ // }
166
+ // else if (result && result.isopen) {
167
+ // console.log("yes is open")
168
+ // if (trueIntent) {
169
+ // let intentDirective = DirIntent.intentDirectiveFor(trueIntent);
170
+ // if (this.log) {console.log("agents (openHours) => trueIntent");}
171
+ // this.intentDir.execute(intentDirective, () => {
172
+ // callback(stopOnConditionMet);
173
+ // });
174
+ // }
175
+ // else {
176
+ // callback();
177
+ // return;
178
+ // }
179
+ // }
180
+ // else if (falseIntent) {
181
+ // let intentDirective = DirIntent.intentDirectiveFor(falseIntent);
182
+ // if (this.log) {console.log("!agents (openHours) => falseIntent", falseIntent);}
183
+ // this.intentDir.execute(intentDirective, () => {
184
+ // callback(stopOnConditionMet);
185
+ // });
186
+ // }
187
+ // else {
188
+ // callback();
189
+ // }
190
+ // });
191
+ }
192
+
193
+ #myrequest(options, callback) {
194
+ if (this.log) {
195
+ console.log("API URL:", options.url);
196
+ console.log("** Options:", JSON.stringify(options));
197
+ }
198
+ let axios_options = {
199
+ url: options.url,
200
+ method: options.method,
201
+ params: options.params,
202
+ headers: options.headers
203
+ }
204
+ if (options.json !== null) {
205
+ axios_options.data = options.json
206
+ }
207
+ if (this.log) {
208
+ console.log("axios_options:", JSON.stringify(axios_options));
209
+ }
210
+ if (options.url.startsWith("https:")) {
211
+ const httpsAgent = new https.Agent({
212
+ rejectUnauthorized: false,
213
+ });
214
+ axios_options.httpsAgent = httpsAgent;
215
+ }
216
+ axios(axios_options)
217
+ .then((res) => {
218
+ console.log("siamo quiii")
219
+ if (this.log) {
220
+ console.log("Response for url:", options.url);
221
+ console.log("Response headers:\n", JSON.stringify(res.headers));
222
+ }
223
+ if (res && res.status == 200 && res.data) {
224
+ if (callback) {
225
+ callback(null, res.data);
226
+ }
100
227
  }
101
228
  else {
102
- callback();
103
- return;
229
+ if (callback) {
230
+ callback(new Error("Response status is not 200"), null);
231
+ }
104
232
  }
105
- }
106
- else if (falseIntent) {
107
- let intentDirective = DirIntent.intentDirectiveFor(falseIntent);
108
- if (this.log) {console.log("!agents (openHours) => falseIntent", falseIntent);}
109
- this.intentDir.execute(intentDirective, () => {
110
- callback(stopOnConditionMet);
111
- });
112
- }
113
- else {
114
- callback();
115
- }
116
- });
233
+ })
234
+ .catch((error) => {
235
+ console.log("siamo quiii")
236
+ // console.error("An error occurred:", JSON.stringify(error.data));
237
+ if (callback) {
238
+ callback(error, null);
239
+ }
240
+ });
117
241
  }
118
242
 
119
243
  parseParams(directive_parameter) {
@@ -0,0 +1,139 @@
1
+ // const { TiledeskClient } = require('@tiledesk/tiledesk-client');
2
+ const { DirIntent } = require('./DirIntent');
3
+ const ms = require('minimist-string');
4
+
5
+ class DirIfOpenHours {
6
+
7
+ constructor(context) {
8
+ if (!context) {
9
+ throw new Error('context object is mandatory.');
10
+ }
11
+ this.tdclient = context.tdclient;
12
+ // this.tdclient = new TiledeskClient({
13
+ // projectId: context.projectId,
14
+ // token: context.token,
15
+ // APIURL: context.TILEDESK_APIURL,
16
+ // APIKEY: "___",
17
+ // log: context.log
18
+ // });
19
+ // let context = {
20
+ // projectId: projectId,
21
+ // token: token,
22
+ // requestId: supportRequest,
23
+ // APIURL: API_URL,
24
+ // TILEBOT_ENDPOINT:TILEBOT_ENDPOINT,
25
+ // departmentId: depId,
26
+ // log: false
27
+ // }
28
+ this.intentDir = new DirIntent(context);
29
+ // {
30
+ // API_ENDPOINT: context.TILEDESK_APIURL,
31
+ // TILEBOT_ENDPOINT: context.TILEBOT_ENDPOINT,
32
+ // supportRequest: context.supportRequest,
33
+ // token: context.token,
34
+ // log: context.log
35
+ // }
36
+ // );
37
+ this.log = context.log;
38
+ }
39
+
40
+ execute(directive, callback) {
41
+ let action;
42
+ if (directive.action) {
43
+ action = directive.action
44
+ }
45
+ else if (directive.parameter) {
46
+ let params;
47
+ params = this.parseParams(directive.parameter);
48
+ if (!params.trueIntent && !params.falseIntent) {
49
+ if (this.log) {
50
+ console.log("missing both params.trueIntent & params.falseIntent");
51
+ }
52
+ callback();
53
+ return;
54
+ }
55
+ action = {
56
+ trueIntent: params.trueIntent,
57
+ falseIntent: params.falseIntent
58
+ }
59
+ }
60
+ else {
61
+ callback();
62
+ return;
63
+ }
64
+ this.go(action, (stop) => {
65
+ callback(stop);
66
+ });
67
+ }
68
+
69
+ go(action, callback) {
70
+
71
+ const trueIntent = action.trueIntent;
72
+ const falseIntent = action.falseIntent;
73
+ const trueIntentAttributes = action.trueIntentAttributes;
74
+ const falseIntentAttributes = action.falseIntentAttributes;
75
+ const stopOnConditionMet = action.stopOnConditionMet;
76
+
77
+ if (trueIntent && trueIntent.trim() === "") {
78
+ trueIntent = null;
79
+ }
80
+ if (falseIntent && falseIntent.trim() === "") {
81
+ falseIntent = null;
82
+ }
83
+ if (this.log) {console.log("condition action:", action);}
84
+ if (!trueIntent && !falseIntent) {
85
+ if (this.log) {console.log("Invalid condition, no intents specified");}
86
+ callback();
87
+ return;
88
+ }
89
+ this.tdclient.openNow((err, result) => {
90
+ if (this.log) {console.log("openNow():", result);}
91
+ if (err) {
92
+ console.error("*** DirIfOpenHours Error:", err);
93
+ callback();
94
+ }
95
+ else if (result && result.isopen) {
96
+ if (trueIntent) {
97
+ let intentDirective = DirIntent.intentDirectiveFor(trueIntent);
98
+ if (this.log) {console.log("DirIfOpenHours (openHours) => trueIntent");}
99
+ this.intentDir.execute(intentDirective, () => {
100
+ callback(stopOnConditionMet);
101
+ });
102
+ }
103
+ else {
104
+ callback();
105
+ return;
106
+ }
107
+ }
108
+ else if (falseIntent) {
109
+ let intentDirective = DirIntent.intentDirectiveFor(falseIntent);
110
+ if (this.log) {console.log("DirIfOpenHours (openHours) => falseIntent", falseIntent);}
111
+ this.intentDir.execute(intentDirective, () => {
112
+ callback(stopOnConditionMet);
113
+ });
114
+ }
115
+ else {
116
+ callback();
117
+ }
118
+ });
119
+ }
120
+
121
+ parseParams(directive_parameter) {
122
+ let trueIntent = null;
123
+ let falseIntent = null;
124
+ const params = ms(directive_parameter);
125
+ if (params.trueIntent) {
126
+ trueIntent = params.trueIntent;
127
+ }
128
+ if (params.falseIntent) {
129
+ falseIntent = params.falseIntent;
130
+ }
131
+ return {
132
+ trueIntent: trueIntent,
133
+ falseIntent: falseIntent
134
+ }
135
+ }
136
+
137
+ }
138
+
139
+ module.exports = { DirIfOpenHours };
@@ -119,10 +119,11 @@ class DirReply {
119
119
  // callback(); // cancel reply operation
120
120
  // return;
121
121
  // }
122
- // console.log("valid message!", cleanMessage);
122
+
123
123
  cleanMessage.senderFullname = this.context.chatbot.bot.name;
124
124
  if (this.log) {console.log("Reply:", JSON.stringify(cleanMessage))};
125
125
  await TiledeskChatbotUtil.updateConversationTranscript(this.context.chatbot, cleanMessage);
126
+ // console.log("sending message!", cleanMessage);
126
127
  this.context.tdclient.sendSupportMessage(
127
128
  this.requestId,
128
129
  cleanMessage,
@@ -130,7 +131,7 @@ class DirReply {
130
131
  if (err) {
131
132
  console.error("Error sending reply:", err);
132
133
  }
133
- if (this.log) {console.log("Reply message sent");}
134
+ if (this.log) {console.log("Reply message sent", cleanMessage);}
134
135
  const delay = TiledeskChatbotUtil.totalMessageWait(cleanMessage);
135
136
  // console.log("got total delay:", delay)
136
137
  if (delay > 0 && delay <= 30000) { // prevent long delays
@@ -49,6 +49,7 @@ class Directives {
49
49
  static GPT_ASSISTANT = 'gpt_assistant';
50
50
  static REPLY_V2 = 'replyv2';
51
51
  static IF_ONLINE_AGENTS_V2 = "ifonlineagentsv2";
52
+ static CONTACT_UPDATE = "leadupdate";
52
53
 
53
54
  // static WHEN_ONLINE_MOVE_TO_AGENT = "whenonlinemovetoagent"; // DEPRECATED?
54
55
  // static WHEN_OFFLINE_HOURS = "whenofflinehours"; // DEPRECATED // adds a message on top of the original message when offline hours opts: --replace