@tiledesk/tiledesk-tybot-connector 0.2.130-rc5 → 0.2.131-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/CHANGELOG.md CHANGED
@@ -17,6 +17,15 @@ available on:
17
17
  - Added flowError on JSONCondition when result = null
18
18
  - Added fix on Filler -->
19
19
 
20
+ # v0.2.131-rc1
21
+ - added: AUDIO_RECORD vxml action as reply_v2 actionType
22
+ - added: DirAddTags action
23
+
24
+ # v0.2.130
25
+ - (TiledeskChatbotUtil) fix process.env.API_ENDPOINT => process.env.API_URL
26
+ - index.js /block => added "token": "NO-TOKEN"
27
+ - (TiledeskChatbotUtil) added: chatbot.addParameter(TiledeskChatbotConst.API_BASE_URL, process.env.API_ENDPOINT);
28
+
20
29
  # v0.2.130-rc5
21
30
  - (TiledeskChatbotUtil) fix process.env.API_ENDPOINT => process.env.API_URL
22
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "0.2.130-rc5",
3
+ "version": "0.2.131-rc1",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -52,7 +52,8 @@ const { DirIfOnlineAgentsV2 } = require('./directives/DirIfOnlineAgentsV2');
52
52
  const { DirContactUpdate } = require('./directives/DirContactUpdate');
53
53
  const { DirClearTranscript } = require('./directives/DirClearTranscript');
54
54
  const { DirMoveToUnassigned } = require('./directives/DirMoveToUnassigned');
55
- const { DirWhatsappStatic, DirSendWhatsapp } = require('./directives/DirSendWhatsapp');
55
+ const { DirAddTags } = require('./directives/DirAddTags');
56
+ const { DirSendWhatsapp } = require('./directives/DirSendWhatsapp');
56
57
 
57
58
  class DirectivesChatbotPlug {
58
59
 
@@ -348,6 +349,13 @@ class DirectivesChatbotPlug {
348
349
  this.process(next_dir);
349
350
  });
350
351
  }
352
+ else if (directive_name === Directives.AUDIO_RECORD) {
353
+ // console.log("...DirReply");
354
+ new DirReply(context).execute(directive, async () => {
355
+ let next_dir = await this.nextDirective(this.directives);
356
+ this.process(next_dir);
357
+ });
358
+ }
351
359
  else if (directive_name === Directives.RANDOM_REPLY) {
352
360
  // console.log("...DirRandomReply");
353
361
  new DirRandomReply(context).execute(directive, async () => {
@@ -732,6 +740,20 @@ class DirectivesChatbotPlug {
732
740
  this.process(next_dir);
733
741
  });
734
742
  }
743
+ else if (directive_name === Directives.ADD_TAGS) {
744
+ // console.log(".....DirAddTags")
745
+ new DirAddTags(context).execute(directive, async (stop) => {
746
+ if (context.log) { console.log("GPTTask stop?", stop);}
747
+ if (stop == true) {
748
+ if (context.log) { console.log("Stopping Actions on:", JSON.stringify(directive));}
749
+ this.theend();
750
+ }
751
+ else {
752
+ let next_dir = await this.nextDirective(this.directives);
753
+ this.process(next_dir);
754
+ }
755
+ });
756
+ }
735
757
  else {
736
758
  //console.log("Unhandled Post-message Directive:", directive_name);
737
759
  let next_dir = await this.nextDirective(this.directives);
@@ -0,0 +1,375 @@
1
+ const axios = require("axios").default;
2
+ const { TiledeskChatbot } = require("../../models/TiledeskChatbot");
3
+ const { Filler } = require("../Filler");
4
+ let https = require("https");
5
+ const { DirIntent } = require("./DirIntent");
6
+ const { TiledeskChatbotConst } = require("../../models/TiledeskChatbotConst");
7
+ const { TiledeskChatbotUtil } = require("../../models/TiledeskChatbotUtil");
8
+ const req = require("express/lib/request");
9
+ const { rejects } = require("assert");
10
+ const { update } = require("../../models/faq");
11
+ require('dotenv').config();
12
+
13
+ class DirAddTags {
14
+
15
+ constructor(context) {
16
+ if (!context) {
17
+ throw new Error('context object is mandatory');
18
+ }
19
+ this.context = context;
20
+ this.chatbot = this.context.chatbot;
21
+ this.tdcache = this.context.tdcache;
22
+ this.requestId = this.context.requestId;
23
+ this.tdClient = this.context.tdclient;
24
+ // this.intentDir = new DirIntent(context);
25
+ this.log = context.log;
26
+ // this.log = true;
27
+ }
28
+
29
+ execute(directive, callback) {
30
+ if (this.log) { console.log("AddTags directive: ", directive); }
31
+ let action;
32
+ if (directive.action) {
33
+ action = directive.action;
34
+ }
35
+ else {
36
+ console.error("Incorrect directive: ", JSON.stringify(directive));
37
+ callback();
38
+ return;
39
+ }
40
+ this.go(action, (stop) => {
41
+ callback(stop);
42
+ })
43
+ }
44
+
45
+ async go(action, callback) {
46
+ if (this.log) { console.log("(DirAddTags) action:", JSON.stringify(action)); }
47
+ if (!this.tdcache) {
48
+ console.error("Error: (DirAddTags) tdcache is mandatory");
49
+ callback();
50
+ return;
51
+ }
52
+
53
+ // default value
54
+ let target = "request";
55
+ let pushToList = false;
56
+
57
+ target = action.target
58
+ pushToList = action.pushToList
59
+
60
+ if (!action.tags || action.tags === '') {
61
+ console.error("Error: (DirAddTags) tags attribute is mandatory")
62
+ await this.chatbot.addParameter("flowError", "Add tags Error: tags attribute is mandatory");
63
+ callback();
64
+ return;
65
+ }
66
+
67
+ let requestVariables = null;
68
+ requestVariables =
69
+ await TiledeskChatbot.allParametersStatic(
70
+ this.tdcache, this.requestId
71
+ )
72
+
73
+ const filler = new Filler();
74
+ const filled_tags = filler.fill(action.tags, requestVariables);
75
+
76
+ if (this.log) {
77
+ console.log("(DirAddTags) tags: ", filled_tags);
78
+ }
79
+
80
+ const server_base_url = process.env.API_ENDPOINT || process.env.API_URL;
81
+ if (this.log) {
82
+ console.log("(DirAddTags) server_base_url ", server_base_url);
83
+ }
84
+
85
+
86
+ // let request = await this.tdClient.getRequestById(this.requestId);
87
+ // if (this.log) { console.log('(DirAddTags) request detail: ', request) }
88
+ // if(!request){
89
+ // if (this.log) { console.log("(DirAddTags) - request not found for request_id:", this.requestId); }
90
+ // callback();
91
+ // return;
92
+ // }
93
+
94
+
95
+ /** use case: CONVERSATION */
96
+ if(target === 'request'){
97
+
98
+ let newTags = filled_tags.split(',').filter(tag => tag !== '').map(el => el.trim())
99
+
100
+ if(action.pushToList){
101
+ newTags.forEach(async (tag) => {
102
+ let tags = await this.addNewTag(server_base_url,tag)
103
+ if(!tags){
104
+ callback();
105
+ return;
106
+ }
107
+ })
108
+ }
109
+
110
+ if (this.log) { console.log('(DirAddTags) UPDATE request with newTags', newTags) }
111
+ let updatedRequest = await this.updateRequestWithTags(server_base_url, newTags)
112
+ if(!updatedRequest){
113
+ callback();
114
+ return;
115
+ }
116
+
117
+ }
118
+
119
+ /** use case: LEAD */
120
+ if(target === 'lead'){
121
+ let newTags = filled_tags.split(',').filter(tag => tag !== '').map(el => el.trim())
122
+
123
+ let request = await this.tdClient.getRequestById(this.requestId);
124
+ if (this.log) { console.log('(DirAddTags) request detail: ', request) }
125
+ if(!request){
126
+ if (this.log) { console.log("(DirAddTags) - request not found for request_id:", this.requestId); }
127
+ callback();
128
+ return;
129
+ }
130
+
131
+ if(action.pushToList){
132
+ newTags.forEach(async (tag) => {
133
+ let tags = await this.addNewTag(server_base_url,tag)
134
+ if(!tags){
135
+ callback();
136
+ return;
137
+ }
138
+ })
139
+ }
140
+
141
+ if (this.log) { console.log('(DirAddTags) UPDATE lead with newTags', newTags) }
142
+ let updatedLead = await this.updateLeadWithTags(server_base_url, request.lead._id, newTags)
143
+ if(!updatedLead){
144
+ callback();
145
+ return;
146
+ }
147
+ }
148
+
149
+ callback();
150
+ return;
151
+
152
+
153
+ }
154
+
155
+ async convertToJson(data) {
156
+
157
+ return new Promise((resolve) => {
158
+ let json = null;
159
+ try {
160
+ json = JSON.parse(data);
161
+ resolve(json)
162
+ } catch (err) {
163
+ resolve(data)
164
+ }
165
+ })
166
+
167
+ }
168
+
169
+ async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
170
+ let trueIntentDirective = null;
171
+ if (trueIntent) {
172
+ trueIntentDirective = DirIntent.intentDirectiveFor(trueIntent, trueIntentAttributes);
173
+ }
174
+ let falseIntentDirective = null;
175
+ if (falseIntent) {
176
+ falseIntentDirective = DirIntent.intentDirectiveFor(falseIntent, falseIntentAttributes);
177
+ }
178
+ if (result === true) {
179
+ if (trueIntentDirective) {
180
+ this.intentDir.execute(trueIntentDirective, () => {
181
+ if (callback) {
182
+ callback();
183
+ }
184
+ })
185
+ }
186
+ else {
187
+ if (this.log) { console.log("No trueIntentDirective specified"); }
188
+ if (callback) {
189
+ callback();
190
+ }
191
+ }
192
+ }
193
+ else {
194
+ if (falseIntentDirective) {
195
+ this.intentDir.execute(falseIntentDirective, () => {
196
+ if (callback) {
197
+ callback();
198
+ }
199
+ });
200
+ }
201
+ else {
202
+ if (this.log) { console.log("No falseIntentDirective specified"); }
203
+ if (callback) {
204
+ callback();
205
+ }
206
+ }
207
+ }
208
+ }
209
+
210
+ async #assignAttributes(action, answer) {
211
+ if (this.log) {
212
+ console.log("assignAttributes action:", action)
213
+ console.log("assignAttributes answer:", answer)
214
+ }
215
+ if (this.context.tdcache) {
216
+ if (action.assignReplyTo && answer) {
217
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, action.assignReplyTo, answer);
218
+ }
219
+ // Debug log
220
+ if (this.log) {
221
+ const all_parameters = await TiledeskChatbot.allParametersStatic(this.context.tdcache, this.context.requestId);
222
+ for (const [key, value] of Object.entries(all_parameters)) {
223
+ if (this.log) { console.log("(DirAddTags) request parameter:", key, "value:", value, "type:", typeof value) }
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ #myrequest(options, callback) {
230
+ if (this.log) {
231
+ console.log("API URL:", options.url);
232
+ console.log("** Options:", JSON.stringify(options));
233
+ }
234
+ let axios_options = {
235
+ url: options.url,
236
+ method: options.method,
237
+ params: options.params,
238
+ headers: options.headers
239
+ }
240
+ if (options.json !== null) {
241
+ axios_options.data = options.json
242
+ }
243
+ if (this.log) {
244
+ console.log("axios_options:", JSON.stringify(axios_options));
245
+ }
246
+ if (options.url.startsWith("https:")) {
247
+ const httpsAgent = new https.Agent({
248
+ rejectUnauthorized: false,
249
+ });
250
+ axios_options.httpsAgent = httpsAgent;
251
+ }
252
+ axios(axios_options)
253
+ .then((res) => {
254
+ if (this.log) {
255
+ console.log("Response for url:", options.url);
256
+ console.log("Response headers:\n", JSON.stringify(res.headers));
257
+ }
258
+ if (res && res.status == 200 && res.data) {
259
+ if (callback) {
260
+ callback(null, res.data);
261
+ }
262
+ }
263
+ else {
264
+ if (callback) {
265
+ callback(new Error("Response status is not 200"), null);
266
+ }
267
+ }
268
+ })
269
+ .catch((error) => {
270
+ if (callback) {
271
+ callback(error, null);
272
+ }
273
+ });
274
+ }
275
+
276
+ async addNewTag(server_base_url, tag){
277
+ return new Promise((resolve, rejects)=> {
278
+ const HTTPREQUEST = {
279
+ url: server_base_url + "/" + this.context.projectId + "/tags",
280
+ headers: {
281
+ 'Content-Type': 'application/json',
282
+ 'Authorization': 'JWT ' + this.context.token
283
+ },
284
+ method: "POST",
285
+ json: {
286
+ tag: tag,
287
+ color: '#f0806f'
288
+ }
289
+ }
290
+ this.#myrequest(
291
+ HTTPREQUEST, async (err, resbody) => {
292
+ if (err) {
293
+ console.error("(httprequest) DirAddTags add tags to list err: ", err);
294
+ resolve(true)
295
+ } else {
296
+ if (resbody) {
297
+ resolve(true)
298
+ } else {
299
+ resolve(false)
300
+ }
301
+ }
302
+ }
303
+ )
304
+ })
305
+ }
306
+
307
+
308
+ async updateRequestWithTags(server_base_url, tags) {
309
+ return new Promise((resolve) => {
310
+ let json = []
311
+ let filteredTags = tags.map((tag) => ({tag: tag, color: '#f0806f'}))
312
+ json.push(...filteredTags)
313
+ if (this.log) {
314
+ console.log('(httprequest) DirAddTags updateRequestWithTags tags--> ', json)
315
+ }
316
+ const HTTPREQUEST = {
317
+ url: server_base_url + "/" + this.context.projectId + "/requests/" + this.requestId + '/tag',
318
+ headers: {
319
+ 'Content-Type': 'application/json',
320
+ 'Authorization': 'JWT ' + this.context.token
321
+ },
322
+ method: "PUT",
323
+ json: json
324
+ }
325
+
326
+ this.#myrequest(
327
+ HTTPREQUEST, async (err, resbody) => {
328
+ if (err) {
329
+ console.error("(httprequest) DirAddTags patch request with new tags err: ", err);
330
+ resolve(true)
331
+ } else {
332
+ if (resbody) {
333
+ resolve(resbody)
334
+ } else {
335
+ resolve(false)
336
+ }
337
+ }
338
+ }
339
+ )
340
+ })
341
+ }
342
+
343
+ async updateLeadWithTags(server_base_url, lead_id, tags) {
344
+ return new Promise((resolve) => {
345
+ const HTTPREQUEST = {
346
+ url: server_base_url + "/" + this.context.projectId + "/leads/" + lead_id + '/tag',
347
+ headers: {
348
+ 'Content-Type': 'application/json',
349
+ 'Authorization': 'JWT ' + this.context.token
350
+ },
351
+ method: "PUT",
352
+ json: tags
353
+ }
354
+
355
+ this.#myrequest(
356
+ HTTPREQUEST, async (err, resbody) => {
357
+ if (err) {
358
+ console.error("(httprequest) DirAddTags put lead with new tags err: ", err);
359
+ resolve(true)
360
+ } else {
361
+ if (resbody) {
362
+ resolve(resbody)
363
+ } else {
364
+ resolve(false)
365
+ }
366
+ }
367
+ }
368
+ )
369
+ })
370
+ }
371
+
372
+
373
+ }
374
+
375
+ module.exports = { DirAddTags }
@@ -47,6 +47,7 @@ class Directives {
47
47
  static BLIND_TRANSFER = 'blind_transfer';
48
48
  static SPEECH_FORM = 'speech_form';
49
49
  static PLAY_PROMPT = 'play_prompt';
50
+ static AUDIO_RECORD = 'audio_record';
50
51
  static GPT_ASSISTANT = 'gpt_assistant';
51
52
  static REPLY_V2 = 'replyv2';
52
53
  static IF_ONLINE_AGENTS_V2 = "ifonlineagentsv2";
@@ -54,6 +55,7 @@ class Directives {
54
55
  static CLEAR_TRANSCRIPT = "clear_transcript";
55
56
  static MOVE_TO_UNASSIGNED = "move_to_unassigned";
56
57
  static CONNECT_BLOCK = "connect_block";
58
+ static ADD_TAGS = 'add_tags'
57
59
 
58
60
  // static WHEN_ONLINE_MOVE_TO_AGENT = "whenonlinemovetoagent"; // DEPRECATED?
59
61
  // static WHEN_OFFLINE_HOURS = "whenofflinehours"; // DEPRECATED // adds a message on top of the original message when offline hours opts: --replace