@tiledesk/tiledesk-tybot-connector 0.2.601-rc1 → 0.3.0

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +378 -1
  2. package/ExtApi.js +6 -6
  3. package/TdCache copy.js +242 -0
  4. package/TdCache.js +81 -176
  5. package/TdCache_v3.js +261 -0
  6. package/TiledeskExpression.js +7 -3
  7. package/index.js +290 -43
  8. package/logs/app.log +279 -0
  9. package/models/IntentsMachineFactory.js +5 -2
  10. package/models/MockBotsDataSource.js +19 -11
  11. package/models/TiledeskChatbot.js +97 -79
  12. package/models/TiledeskChatbotConst.js +12 -17
  13. package/models/TiledeskChatbotUtil.js +353 -109
  14. package/models/TiledeskIntentsMachine.js +1 -1
  15. package/models/faqKbService.js +1 -1
  16. package/package.json +7 -6
  17. package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +172 -106
  18. package/tiledeskChatbotPlugs/Filler.js +13 -2
  19. package/tiledeskChatbotPlugs/TildeskContextForCodeOrchestrator.js +8 -0
  20. package/tiledeskChatbotPlugs/WebhookChatbotPlug.js +13 -7
  21. package/tiledeskChatbotPlugs/directives/DirAddTags.js +374 -0
  22. package/tiledeskChatbotPlugs/directives/DirAiPrompt.js +476 -0
  23. package/tiledeskChatbotPlugs/directives/DirAskGPT.js +16 -19
  24. package/tiledeskChatbotPlugs/directives/DirAskGPTV2.js +221 -34
  25. package/tiledeskChatbotPlugs/directives/DirAssign.js +0 -11
  26. package/tiledeskChatbotPlugs/directives/DirAssignFromFunction.js +11 -21
  27. package/tiledeskChatbotPlugs/directives/DirAssistant.js +728 -0
  28. package/tiledeskChatbotPlugs/directives/DirBrevo.js +353 -0
  29. package/tiledeskChatbotPlugs/directives/DirCaptureUserReply.js +3 -30
  30. package/tiledeskChatbotPlugs/directives/DirClearTranscript.js +22 -0
  31. package/tiledeskChatbotPlugs/directives/DirClose.js +16 -3
  32. package/tiledeskChatbotPlugs/directives/DirCode.js +1 -1
  33. package/tiledeskChatbotPlugs/directives/DirCondition.js +0 -26
  34. package/tiledeskChatbotPlugs/directives/DirConnectBlock.js +183 -0
  35. package/tiledeskChatbotPlugs/directives/DirContactUpdate.js +121 -0
  36. package/tiledeskChatbotPlugs/directives/DirCustomerio.js +5 -8
  37. package/tiledeskChatbotPlugs/directives/DirDeflectToHelpCenter.js +11 -1
  38. package/tiledeskChatbotPlugs/directives/DirDepartment.js +15 -6
  39. package/tiledeskChatbotPlugs/directives/DirFireTiledeskEvent.js +17 -6
  40. package/tiledeskChatbotPlugs/directives/DirForm.js +12 -2
  41. package/tiledeskChatbotPlugs/directives/DirGptTask.js +83 -38
  42. package/tiledeskChatbotPlugs/directives/DirGptTask_OLD.js +4 -7
  43. package/tiledeskChatbotPlugs/directives/DirHubspot.js +5 -8
  44. package/tiledeskChatbotPlugs/directives/DirIfOnlineAgents.js +14 -27
  45. package/tiledeskChatbotPlugs/directives/DirIfOnlineAgentsV2.js +278 -0
  46. package/tiledeskChatbotPlugs/directives/DirIfOpenHours.js +147 -51
  47. package/tiledeskChatbotPlugs/directives/DirIfOpenHours_OLD.js +125 -0
  48. package/tiledeskChatbotPlugs/directives/DirIntent.js +8 -36
  49. package/tiledeskChatbotPlugs/directives/DirJSONCondition.js +5 -26
  50. package/tiledeskChatbotPlugs/directives/DirMessage.js +19 -17
  51. package/tiledeskChatbotPlugs/directives/DirMessageToBot.js +136 -0
  52. package/tiledeskChatbotPlugs/directives/DirMoveToAgent.js +20 -87
  53. package/tiledeskChatbotPlugs/directives/DirMoveToUnassigned.js +59 -0
  54. package/tiledeskChatbotPlugs/directives/DirQapla.js +6 -9
  55. package/tiledeskChatbotPlugs/directives/DirRandomReply.js +17 -7
  56. package/tiledeskChatbotPlugs/directives/DirRemoveCurrentBot.js +17 -7
  57. package/tiledeskChatbotPlugs/directives/DirReplaceBot.js +11 -2
  58. package/tiledeskChatbotPlugs/directives/DirReplaceBotV2.js +135 -21
  59. package/tiledeskChatbotPlugs/directives/DirReplaceBotV3.js +163 -0
  60. package/tiledeskChatbotPlugs/directives/DirReply.js +42 -9
  61. package/tiledeskChatbotPlugs/directives/DirReplyV2.js +347 -0
  62. package/tiledeskChatbotPlugs/directives/DirSendEmail.js +13 -23
  63. package/tiledeskChatbotPlugs/directives/DirSendWhatsapp.js +247 -0
  64. package/tiledeskChatbotPlugs/directives/DirSetAttributeV2.js +202 -15
  65. package/tiledeskChatbotPlugs/directives/DirSetConversationTags.js +13 -4
  66. package/tiledeskChatbotPlugs/directives/DirWait.js +21 -4
  67. package/tiledeskChatbotPlugs/directives/DirWebRequest.js +1 -2
  68. package/tiledeskChatbotPlugs/directives/DirWebRequestV2.js +166 -103
  69. package/tiledeskChatbotPlugs/directives/DirWhatsappByAttribute.js +2 -60
  70. package/tiledeskChatbotPlugs/directives/Directives.js +16 -1
  71. /package/tiledeskChatbotPlugs/directives/{DirOfflineHours.js → DEPRECATED_DirOfflineHours.js} +0 -0
@@ -0,0 +1,728 @@
1
+ let axios = require('axios');
2
+ let https = require("https");
3
+ const { Filler } = require('../Filler');
4
+ const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
5
+ const { DirIntent } = require('./DirIntent');
6
+
7
+ class DirAssistant {
8
+ constructor(context) {
9
+ if (!context) {
10
+ throw new Error('context object is mandatory.');
11
+ }
12
+ this.context = context;
13
+ this.tdcache = context.tdcache;
14
+ this.requestId = context.requestId;
15
+ this.intentDir = new DirIntent(context);
16
+ this.API_ENDPOINT = context.API_ENDPOINT;
17
+ this.log = context.log;
18
+ }
19
+
20
+ execute(directive, callback) {
21
+ let action;
22
+ if (directive.action) {
23
+ action = directive.action;
24
+ }
25
+ else {
26
+ console.error("Incorrect directive:", JSON.stringify(directive));
27
+ callback();
28
+ return;
29
+ }
30
+ this.go(action, (stop) => {
31
+ if (this.log) {console.log("(DirAssistant, stop?", stop); }
32
+ callback(stop);
33
+ });
34
+ }
35
+
36
+ async go(action, callback) {
37
+ if (this.log) {console.log("DirAssistant action:", JSON.stringify(action));}
38
+ let requestAttributes = null;
39
+ if (this.tdcache) {
40
+ requestAttributes =
41
+ await TiledeskChatbot.allParametersStatic(
42
+ this.tdcache, this.requestId
43
+ );
44
+ }
45
+
46
+ const filler = new Filler();
47
+ const url = filler.fill(action.url, requestAttributes);
48
+ // prompt => Mandatory
49
+ // assistantId => Mandatory
50
+ // threadIdAttribute => Optional // default "firstThread"
51
+ // assignResultTo => Optional // default "assistantReply"
52
+ // assignErrorTo => Optional // default "assistantError"
53
+ // action.settings.timeout => Optional
54
+
55
+ let assignResultTo = "assistantReply";
56
+ if (action.assignResultTo) {
57
+ assignResultTo = action.assignResultTo;
58
+ }
59
+
60
+ let assignErrorTo = "assistantError";
61
+ if (action.assignErrorTo) {
62
+ assignErrorTo = action.assignErrorTo;
63
+ }
64
+
65
+ let threadIdAttribute = "firstThread";
66
+ if (action.threadIdAttribute) {
67
+ threadIdAttribute = action.threadIdAttribute;
68
+ }
69
+
70
+ let _assistantId = null;
71
+ if (action.assistantId) { // mandatory
72
+ _assistantId = action.assistantId;
73
+ }
74
+ else {
75
+ // TODO: LOG SETTINGS ERROR
76
+ console.error("DirAssistant error: no assistantId.");
77
+ callback();
78
+ return;
79
+ }
80
+
81
+ let _prompt = null;
82
+ if (action.prompt) { // mandatory
83
+ _prompt = action.prompt;
84
+ }
85
+ else {
86
+ // TODO: LOG SETTINGS ERROR
87
+ console.error("DirAssistant error: no prompt.");
88
+ callback();
89
+ return;
90
+ }
91
+
92
+ let assistantId = _assistantId;
93
+ try {
94
+ assistantId = filler.fill(_assistantId, requestAttributes);
95
+ }
96
+ catch(error) {
97
+ console.error("Error while filling assistantId:", error);
98
+ }
99
+
100
+ let prompt = _prompt;
101
+ try {
102
+ prompt = filler.fill(_prompt, requestAttributes);
103
+ }
104
+ catch(error) {
105
+ console.error("Error while filling prompt:", error);
106
+ }
107
+
108
+ if (this.log) {
109
+ console.log("settings ok");
110
+ console.log("prompt:", prompt);
111
+ console.log("assistantId:", assistantId);
112
+ }
113
+ // Condition branches
114
+ let trueIntent = action.trueIntent;
115
+ let falseIntent = action.falseIntent;
116
+ if (trueIntent && trueIntent.trim() === "") {
117
+ trueIntent = null;
118
+ }
119
+ if (falseIntent && falseIntent.trim() === "") {
120
+ falseIntent = null;
121
+ }
122
+
123
+ this.timeout = this.#webrequest_timeout(action, 20000, 1, 300000);
124
+
125
+ let apikey = await this.getGPT_APIKEY();
126
+ if (this.log) {console.log("apikey:", apikey);}
127
+ if (!apikey) {
128
+ const reply = "OpenAI APIKEY is mandatory for ChatGPT Assistants. Add your personal OpenAI APIKEY in Settings > Integrations";
129
+ if (this.log) { console.error(reply); };
130
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignErrorTo, reply);
131
+ if (falseIntent) {
132
+ await this.#executeCondition(false, trueIntent, null, falseIntent, null);
133
+ callback(true);
134
+ }
135
+ return;
136
+ }
137
+ else {
138
+ apikey = "Bearer " + apikey;
139
+ }
140
+ let threadId = null;
141
+ try {
142
+ threadId = requestAttributes[threadIdAttribute];
143
+ if (!threadId || (threadId && threadId.trim() === '') ) {
144
+ // create thread if it doesn't exist
145
+ if (this.log) {console.log("Creating thread");}
146
+ const thread = await this.createThread(apikey);
147
+ if (this.log) {console.log("Thread crated.");}
148
+ threadId = thread.id;
149
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, threadIdAttribute, threadId);
150
+ if (this.log) {
151
+ console.log("thread:", thread);
152
+ console.log("threadId:", threadId);
153
+ }
154
+ }
155
+ else {
156
+ if (this.log) { console.log("Reusing threadId (used flow attribute:" + threadIdAttribute + "):", threadId); }
157
+ }
158
+ await this.addMessage(prompt, threadId, apikey);
159
+ if (this.log) {console.log("Message added.");}
160
+ await this.runThreadOnAssistant(assistantId, threadId, apikey);
161
+ let messages = await this.threadMessages(threadId, apikey);
162
+ let lastMessage = null;
163
+ if (messages && messages.data && messages.data.length > 0 && messages.data[0]) {
164
+ if (messages.data[0].content.length > 0 && messages.data[0].content[0] && messages.data[0].content[0].text) {
165
+ lastMessage = messages.data[0].content[0].text.value;
166
+ }
167
+ }
168
+
169
+ // process.exit(0);
170
+ if (lastMessage !== null) {
171
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignResultTo, lastMessage);
172
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, "lastMessageData", messages.data[0].content); // content is an array, see on this source end for messages structure example, including content. Ex get annotation[0]: content[0].text.annotations[0]
173
+ if (trueIntent) {
174
+ await this.#executeCondition(true, trueIntent, null, falseIntent, null);
175
+ callback(true);
176
+ }
177
+ else {
178
+ callback(false);
179
+ return;
180
+ }
181
+ }
182
+ else {
183
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignResultTo, null);
184
+ if (falseIntent) {
185
+ await this.#executeCondition(false, trueIntent, null, falseIntent, null);
186
+ callback(true);
187
+ }
188
+ else {
189
+ callback(false);
190
+ return;
191
+ }
192
+ }
193
+ }
194
+ catch (error) {
195
+ if (this.log) { console.error("error:", error); }
196
+ await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignErrorTo, error);
197
+ if (falseIntent) {
198
+ await this.#executeCondition(false, trueIntent, null, falseIntent, null);
199
+ }
200
+ callback(true);
201
+ return;
202
+ }
203
+
204
+ }
205
+
206
+ async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
207
+ let trueIntentDirective = null;
208
+ if (trueIntent) {
209
+ trueIntentDirective = DirIntent.intentDirectiveFor(trueIntent, trueIntentAttributes);
210
+ }
211
+ let falseIntentDirective = null;
212
+ if (falseIntent) {
213
+ falseIntentDirective = DirIntent.intentDirectiveFor(falseIntent, falseIntentAttributes);
214
+ }
215
+ if (result === true) {
216
+ if (trueIntentDirective) {
217
+ this.intentDir.execute(trueIntentDirective, () => {
218
+ if (callback) {
219
+ callback();
220
+ }
221
+ });
222
+ }
223
+ else {
224
+ if (this.log) {console.log("No trueIntentDirective specified");}
225
+ if (callback) {
226
+ callback();
227
+ }
228
+ }
229
+ }
230
+ else {
231
+ if (falseIntentDirective) {
232
+ this.intentDir.execute(falseIntentDirective, () => {
233
+ if (callback) {
234
+ callback();
235
+ }
236
+ });
237
+ }
238
+ else {
239
+ if (this.log) {console.log("No falseIntentDirective specified");}
240
+ if (callback) {
241
+ callback();
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ #webrequest_timeout(action, default_timeout, min, max) {
248
+ let timeout = default_timeout;
249
+ if (!action.settings) {
250
+ return timeout;
251
+ }
252
+
253
+ if (action.settings.timeout) {
254
+ if ((typeof action.settings.timeout === "number") && action.settings.timeout > min && action.settings.timeout < max) {
255
+ timeout = Math.round(action.settings.timeout)
256
+ // console.log("new timeout:", timeout);
257
+ }
258
+ }
259
+ return timeout
260
+ }
261
+
262
+ async getGPT_APIKEY() {
263
+ if (process.env.TEST_OPENAI_APIKEY) {
264
+ return process.env.TEST_OPENAI_APIKEY
265
+ }
266
+ else {
267
+ return await this.getKeyFromIntegrations();
268
+ }
269
+ }
270
+
271
+ async createThread(apikey) {
272
+ if (this.log) { console.log("creating thread..."); }
273
+ return new Promise( async (resolve, reject) => {
274
+ const url = "https://api.openai.com/v1/threads";
275
+ const headers = {
276
+ "Authorization": apikey,
277
+ "OpenAI-Beta": "assistants=v2"
278
+ }
279
+ const HTTPREQUEST = {
280
+ url: url,
281
+ headers: headers,
282
+ json: '', // no old messages on creation
283
+ method: "POST",
284
+ timeout: this.timeout
285
+ };
286
+ if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
287
+ this.#myrequest(
288
+ HTTPREQUEST, async (err, res) => {
289
+ let status = res.status;
290
+ if (err) {
291
+ if (this.log) {console.error("DirAssistant error:", err);}
292
+ reject(err);
293
+ }
294
+ else if(res.status >= 200 && res.status <= 299) {
295
+ if (this.log) {console.log("got threadid res:", res);}
296
+ let thread = res.data;
297
+ resolve(thread)
298
+ }
299
+ else {
300
+ reject(new Error("Thread creation status != 200:", status));
301
+ }
302
+ }
303
+ );
304
+ });
305
+ }
306
+
307
+ async addMessage(prompt, threadId, apikey) {
308
+
309
+ // POST https://api.openai.com/v1/threads/{{threadID}}/messages
310
+
311
+ // JSON
312
+ /*
313
+ {
314
+ "role": "user",
315
+ "content": {{last_user_text | json}},
316
+ "attachments": [
317
+ {
318
+ "file_id": "file-9rf2OwoLy22Q6bePkO0Zmhlc",
319
+ "tools": [
320
+ {
321
+ "type": "code_interpreter"
322
+ }
323
+ ]
324
+ }
325
+ ]
326
+ }
327
+ */
328
+ const json_payload = {
329
+ "role": "user",
330
+ "content": prompt
331
+ }
332
+
333
+ return new Promise( async (resolve, reject) => {
334
+ const url = `https://api.openai.com/v1/threads/${threadId}/messages`;
335
+ const headers = {
336
+ "Authorization": apikey,
337
+ "OpenAI-Beta": "assistants=v2"
338
+ }
339
+ const HTTPREQUEST = {
340
+ url: url,
341
+ headers: headers,
342
+ json: json_payload,
343
+ method: "POST",
344
+ timeout: this.timeout
345
+ };
346
+ if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
347
+ this.#myrequest(
348
+ HTTPREQUEST, async (err, res) => {
349
+ let status = res.status;
350
+ if (err) {
351
+ if (this.log) {console.error("DirAssistant error:", err);}
352
+ reject(err);
353
+ }
354
+ else if(res.status >= 200 && res.status <= 299) {
355
+ if (this.log) {console.log("got response data:", res.data);}
356
+ // let return_body = res.data;
357
+ resolve();
358
+ }
359
+ else {
360
+ reject(new Error("Message add status != 200:", status));
361
+ }
362
+ }
363
+ );
364
+ });
365
+ }
366
+
367
+ async runThreadOnAssistant(assistantId, threadId, apikey) {
368
+ let _run = await this.createRun(threadId, assistantId, apikey);
369
+ if (this.log) {console.log("Got run:", _run);}
370
+ let runId = _run.id;
371
+ if (this.log) {console.log("runId:", runId);}
372
+ let status = null;
373
+ do {
374
+ if (this.log) {console.log("Getting run...");}
375
+ const wait_for = 2000;
376
+ if (this.log) {console.log("Waiting:", wait_for);}
377
+ await new Promise(resolve => setTimeout(resolve, wait_for));
378
+ let run = await this.getRun(threadId, runId, apikey);
379
+ status = run.status;
380
+ if (this.log) {console.log("Run status:", status);}
381
+ }
382
+ while (status === "queued" || status === "in_progress" || status === "requires_action" && status === "cancelling");
383
+ // while (status != "completed" && status != "cancelled" && status != "failed" && status != "expired");
384
+ // queued, in_progress, requires_action, cancelling
385
+ if (this.log) {console.log("Run end.");}
386
+ }
387
+
388
+ async createRun(threadId, assistantId, apikey) {
389
+ const json_payload = {
390
+ "assistant_id": assistantId
391
+ }
392
+
393
+ return new Promise( async (resolve, reject) => {
394
+ if (this.log) {console.log("adding message to thread...");}
395
+ const url = `https://api.openai.com/v1/threads/${threadId}/runs`;
396
+ const headers = {
397
+ "Authorization": apikey,
398
+ "OpenAI-Beta": "assistants=v2"
399
+ }
400
+ const HTTPREQUEST = {
401
+ url: url,
402
+ headers: headers,
403
+ json: json_payload,
404
+ method: "POST",
405
+ timeout: this.timeout
406
+ };
407
+ if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
408
+ this.#myrequest(
409
+ HTTPREQUEST, async (err, res) => {
410
+ let status = res.status;
411
+ if (err) {
412
+ if (this.log) {console.error("DirAssistant error:", err);}
413
+ reject(err);
414
+ }
415
+ else if(res.status >= 200 && res.status <= 299) {
416
+ if (this.log) {console.log("got response data:", res.data);}
417
+ // let return_body = res.data;
418
+ resolve(res.data);
419
+ }
420
+ else {
421
+ reject(new Error("Message add status != 200:", status));
422
+ }
423
+ }
424
+ );
425
+ });
426
+ }
427
+
428
+ async getRun(threadId, runId, apikey) {
429
+ return new Promise( async (resolve, reject) => {
430
+ const url = `https://api.openai.com/v1/threads/${threadId}/runs/${runId}`;
431
+ const headers = {
432
+ "Authorization": apikey,
433
+ "OpenAI-Beta": "assistants=v2"
434
+ }
435
+ const HTTPREQUEST = {
436
+ url: url,
437
+ headers: headers,
438
+ json: null,
439
+ method: "GET",
440
+ timeout: this.timeout
441
+ };
442
+ if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
443
+ this.#myrequest(
444
+ HTTPREQUEST, async (err, res) => {
445
+ let status = res.status;
446
+ if (err) {
447
+ if (this.log) {console.error("DirAssistant error:", err);}
448
+ reject(err);
449
+ }
450
+ else if(res.status >= 200 && res.status <= 299) {
451
+ if (this.log) {console.log("got response data:", res.data);}
452
+ // let return_body = res.data;
453
+ resolve(res.data);
454
+ }
455
+ else {
456
+ reject(new Error("Message add status != 200:", status));
457
+ }
458
+ }
459
+ );
460
+ });
461
+ }
462
+
463
+ async threadMessages(threadId, apikey) {
464
+ return new Promise( async (resolve, reject) => {
465
+ const url = `https://api.openai.com/v1/threads/${threadId}/messages`;
466
+ const headers = {
467
+ "Authorization": apikey,
468
+ "OpenAI-Beta": "assistants=v2"
469
+ }
470
+ const HTTPREQUEST = {
471
+ url: url,
472
+ headers: headers,
473
+ json: null,
474
+ method: "GET",
475
+ timeout: this.timeout
476
+ };
477
+ if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
478
+ this.#myrequest(
479
+ HTTPREQUEST, async (err, res) => {
480
+ let status = res.status;
481
+ if (err) {
482
+ if (this.log) {console.error("DirAssistant error:", err);}
483
+ reject(err);
484
+ }
485
+ else if(res.status >= 200 && res.status <= 299) {
486
+ if (this.log) {console.log("got response data:", res.data);}
487
+ // let return_body = res.data;
488
+ resolve(res.data);
489
+ }
490
+ else {
491
+ reject(new Error("Message add status != 200:", status));
492
+ }
493
+ }
494
+ );
495
+ });
496
+ }
497
+
498
+ async getKeyFromIntegrations() {
499
+ return new Promise((resolve) => {
500
+
501
+ const INTEGRATIONS_HTTPREQUEST = {
502
+ url: this.API_ENDPOINT + "/" + this.context.projectId + "/integration/name/openai",
503
+ headers: {
504
+ 'Content-Type': 'application/json',
505
+ 'Authorization': 'JWT ' + this.context.token
506
+ },
507
+ method: "GET"
508
+ }
509
+ if (this.log) { console.log("DirAssistant INTEGRATIONS_HTTPREQUEST ", INTEGRATIONS_HTTPREQUEST) }
510
+
511
+ this.#myrequest(
512
+ INTEGRATIONS_HTTPREQUEST, async (err, res) => {
513
+ if (err) {
514
+ resolve(null);
515
+ } else {
516
+ let integration = res.data;
517
+ if (integration &&
518
+ integration.value) {
519
+ resolve(integration.value.apikey)
520
+ }
521
+ else {
522
+ resolve(null)
523
+ }
524
+ }
525
+ })
526
+ })
527
+ }
528
+
529
+ #myrequest(options, callback) {
530
+ try {
531
+ if (this.log) {
532
+ console.log("API URL:", options.url);
533
+ //console.log("** Options:", JSON.stringify(options));
534
+ // Stringify "options". FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
535
+ let cache = [];
536
+ let str_Options = JSON.stringify(options, function(key, value) { // try to use a separate function
537
+ if (typeof value === 'object' && value != null) {
538
+ if (cache.indexOf(value) !== -1) {
539
+ return;
540
+ }
541
+ cache.push(value);
542
+ }
543
+ return value;
544
+ });
545
+ console.log("** Options:", str_Options);
546
+
547
+
548
+ }
549
+ let axios_options = {
550
+ url: options.url,
551
+ method: options.method,
552
+ params: options.params,
553
+ headers: options.headers,
554
+ timeout: options.timeout
555
+ }
556
+
557
+ if (options.json !== null) {
558
+ axios_options.data = options.json
559
+ }
560
+ // if (this.log) {
561
+ // console.log("axios_options:", JSON.stringify(axios_options));
562
+ // }
563
+ if (options.url.startsWith("https:")) {
564
+ const httpsAgent = new https.Agent({
565
+ rejectUnauthorized: false,
566
+ });
567
+ axios_options.httpsAgent = httpsAgent;
568
+ }
569
+
570
+ axios(axios_options)
571
+ .then((res) => {
572
+ if (this.log) {
573
+ // console.log("Success Response:", res);
574
+ console.log("Response for url:", options.url);
575
+ console.log("Response headers:\n", JSON.stringify(res.headers));
576
+ }
577
+ if (callback) {
578
+ callback(null, res);
579
+ }
580
+ })
581
+ .catch( (err) => {
582
+ if (this.log) {
583
+ if (err.response) {
584
+ console.log("Error Response data:", err.response.data);
585
+ }
586
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
587
+ let cache = [];
588
+ let error_log = JSON.stringify(err, function(key, value) { // try to use a separate function
589
+ if (typeof value === 'object' && value != null) {
590
+ if (cache.indexOf(value) !== -1) {
591
+ return;
592
+ }
593
+ cache.push(value);
594
+ }
595
+ return value;
596
+ });
597
+ console.error("(DirAssistant) An error occurred: ", error_log);
598
+ // FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
599
+ // console.error("An error occurred:", JSON.stringify(err));
600
+ }
601
+ if (callback) {
602
+ let status = 1000;
603
+ let cache = [];
604
+ let str_error = JSON.stringify(err, function(key, value) { // try to use a separate function
605
+ if (typeof value === 'object' && value != null) {
606
+ if (cache.indexOf(value) !== -1) {
607
+ return;
608
+ }
609
+ cache.push(value);
610
+ }
611
+ return value;
612
+ });
613
+ let error = JSON.parse(str_error) // "status" disappears without this trick
614
+ let errorMessage = JSON.stringify(error);
615
+ if (error.status) {
616
+ status = error.status;
617
+ }
618
+ if (error.message) {
619
+ errorMessage = error.message;
620
+ }
621
+ let data = null;
622
+ if (err.response) {
623
+ data = err.response.data;
624
+ }
625
+ callback(
626
+ {
627
+ status: status,
628
+ data: data,
629
+ error: errorMessage
630
+ }, data
631
+ );
632
+ }
633
+ });
634
+ }
635
+ catch(error) {
636
+ console.error("Error:", error);
637
+ }
638
+ }
639
+
640
+ }
641
+
642
+
643
+
644
+ module.exports = { DirAssistant };
645
+
646
+ // Messages list response example
647
+
648
+ /*
649
+ {
650
+ "object": "list",
651
+ "data": [
652
+ {
653
+ "id": "msg_FfKaNU82uBYQU9gANFkKJ5Wi",
654
+ "object": "thread.message",
655
+ "created_at": 1721681044,
656
+ "assistant_id": null,
657
+ "thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
658
+ "run_id": null,
659
+ "role": "user",
660
+ "content": [
661
+ {
662
+ "type": "text",
663
+ "text": {
664
+ "value": "vendete sedie di altezza superiore o uguale a 50 cm?",
665
+ "annotations": []
666
+ }
667
+ }
668
+ ],
669
+ "file_ids": [],
670
+ "metadata": {}
671
+ },
672
+ {
673
+ "id": "msg_Ddxnqi7M9vvLdS9YYO4FHjVt",
674
+ "object": "thread.message",
675
+ "created_at": 1721680934,
676
+ "assistant_id": "asst_qNjiwCVxo3kL2mnN1QyP50Zb",
677
+ "thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
678
+ "run_id": "run_k8mPIrZPnsO0hAiezD9y2f1t",
679
+ "role": "assistant",
680
+ "content": [
681
+ {
682
+ "type": "text",
683
+ "text": {
684
+ "value": "Una delle best practices raccomandate per garantire un alto livello di sicurezza informatica per la linea di prodotti \"boss\" è la seguente:\n\n- Aggiornare i dispositivi con l'ultima versione del firmware disponibile. È possibile consultare il portale KSA per verificare la disponibilità degli aggiornamenti【6:0†source】.\n\nSe hai altri dubbi o necessiti di ulteriori informazioni, non esitare a chiedere!",
685
+ "annotations": [
686
+ {
687
+ "type": "file_citation",
688
+ "text": "【6:0†source】",
689
+ "start_index": 305,
690
+ "end_index": 317,
691
+ "file_citation": {
692
+ "file_id": "file-dwR6qSwVUIrhImd9espzExGw",
693
+ "quote": ""
694
+ }
695
+ }
696
+ ]
697
+ }
698
+ }
699
+ ],
700
+ "file_ids": [],
701
+ "metadata": {}
702
+ },
703
+ {
704
+ "id": "msg_ng244T4mymroFWZ912r9DvWZ",
705
+ "object": "thread.message",
706
+ "created_at": 1721680931,
707
+ "assistant_id": null,
708
+ "thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
709
+ "run_id": null,
710
+ "role": "user",
711
+ "content": [
712
+ {
713
+ "type": "text",
714
+ "text": {
715
+ "value": "dimmi una delle best practices che conosci",
716
+ "annotations": []
717
+ }
718
+ }
719
+ ],
720
+ "file_ids": [],
721
+ "metadata": {}
722
+ }
723
+ ],
724
+ "first_id": "msg_FfKaNU82uBYQU9gANFkKJ5Wi",
725
+ "last_id": "msg_ng244T4mymroFWZ912r9DvWZ",
726
+ "has_more": false
727
+ }
728
+ */