@tiledesk/tiledesk-tybot-connector 2.0.9-rc1 → 2.0.10-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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-tybot-connector",
3
- "version": "2.0.9-rc1",
3
+ "version": "2.0.10-rc1",
4
4
  "description": "Tiledesk Tybot connector",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -59,6 +59,7 @@ const { DirWebResponse } = require('./directives/DirWebResponse');
59
59
  const { DirConnectBlock } = require('./directives/DirConnectBlock');
60
60
 
61
61
  const winston = require('../utils/winston');
62
+ const { DirFlowLog } = require('./directives/DirFlowLog');
62
63
 
63
64
  class DirectivesChatbotPlug {
64
65
 
@@ -714,6 +715,12 @@ class DirectivesChatbotPlug {
714
715
  this.process(next_dir);
715
716
  });
716
717
  }
718
+ else if (directive_name === Directives.FLOW_LOG) {
719
+ new DirFlowLog(context).execute(directive, async () => {
720
+ let next_dir = await this.nextDirective(this.directives);
721
+ this.process(next_dir);
722
+ })
723
+ }
717
724
  else {
718
725
  let next_dir = await this.nextDirective(this.directives);
719
726
  this.process(next_dir);
@@ -8,6 +8,7 @@ const { TiledeskChatbotUtil } = require("../../utils/TiledeskChatbotUtil");
8
8
  const req = require("express/lib/request");
9
9
  const { update } = require("../../models/faq");
10
10
  const { TiledeskClient } = require("@tiledesk/tiledesk-client");
11
+ const { Logger } = require("../../Logger");
11
12
  require('dotenv').config();
12
13
  const winston = require('../../utils/winston');
13
14
  const httpUtils = require("../../utils/HttpUtils");
@@ -23,6 +24,8 @@ class DirAddTags {
23
24
  this.tdcache = this.context.tdcache;
24
25
  this.requestId = this.context.requestId;
25
26
  this.API_ENDPOINT = this.context.API_ENDPOINT;
27
+ this.log = context.log;
28
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
26
29
 
27
30
  this.tdClient = new TiledeskClient({
28
31
  projectId: this.context.projectId,
@@ -33,17 +36,20 @@ class DirAddTags {
33
36
  }
34
37
 
35
38
  execute(directive, callback) {
36
- winston.verbose("Execute AddTags directive");
39
+ winston.verbose("Execute AddTags action");
40
+ this.logger.error("Execute AddTags directive")
37
41
  let action;
38
42
  if (directive.action) {
39
43
  action = directive.action;
40
44
  }
41
45
  else {
42
- winston.warn("Incorrect directive: ", directive);
46
+ this.logger.error("Incorrect action for ", directive.name, directive)
47
+ winston.debug("Incorrect directive: ", directive);
43
48
  callback();
44
49
  return;
45
50
  }
46
51
  this.go(action, (stop) => {
52
+ this.logger.info("Acion AddTag completed");
47
53
  callback(stop);
48
54
  })
49
55
  }
@@ -64,6 +70,7 @@ class DirAddTags {
64
70
  pushToList = action.pushToList
65
71
 
66
72
  if (!action.tags || action.tags === '') {
73
+ this.logger.error("Add tags Error: tags attribute is mandatory");
67
74
  winston.error("(DirAddTags) Error: tags attribute is mandatory")
68
75
  await this.chatbot.addParameter("flowError", "Add tags Error: tags attribute is mandatory");
69
76
  callback();
@@ -84,6 +91,7 @@ class DirAddTags {
84
91
  if(target === 'request'){
85
92
 
86
93
  let newTags = filled_tags.split(',').filter(tag => tag !== '').map(el => el.trim())
94
+ this.logger.debug("Adding following tags to conversation: ", newTags)
87
95
 
88
96
  if(action.pushToList){
89
97
  newTags.forEach(async (tag) => {
@@ -97,6 +105,7 @@ class DirAddTags {
97
105
 
98
106
  winston.debug('(DirAddTags) UPDATE request with newTags', newTags)
99
107
  let updatedRequest = await this.updateRequestWithTags(newTags)
108
+ this.logger.info("Tags added to conversation")
100
109
  if(!updatedRequest){
101
110
  callback();
102
111
  return;
@@ -107,6 +116,7 @@ class DirAddTags {
107
116
  /** use case: LEAD */
108
117
  if(target === 'lead'){
109
118
  let newTags = filled_tags.split(',').filter(tag => tag !== '').map(el => el.trim())
119
+ this.logger.debug("Adding following tags to lead: ", newTags)
110
120
 
111
121
  let request = await this.tdClient.getRequestById(this.requestId);
112
122
  winston.debug('(DirAddTags) request detail: ', request)
@@ -128,6 +138,7 @@ class DirAddTags {
128
138
 
129
139
  winston.debug('(DirAddTags) UPDATE lead with newTags ', newTags)
130
140
  let updatedLead = await this.updateLeadWithTags(request.lead._id, newTags)
141
+ this.logger.info("Tags added to lead")
131
142
  if(!updatedLead){
132
143
  callback();
133
144
  return;
@@ -172,6 +183,7 @@ class DirAddTags {
172
183
  httpUtils.request(
173
184
  HTTPREQUEST, async (err, resbody) => {
174
185
  if (err) {
186
+ this.logger.error("Add tags to list error ", err?.response?.data)
175
187
  winston.error("(httprequest) DirAddTags add tags to list err: ", err);
176
188
  resolve(true)
177
189
  } else {
@@ -206,6 +218,7 @@ class DirAddTags {
206
218
  httpUtils.request(
207
219
  HTTPREQUEST, async (err, resbody) => {
208
220
  if (err) {
221
+ this.logger.error("Add tag to conversation error ", err?.response?.data);
209
222
  winston.error("(httprequest) DirAddTags patch request with new tags err: ", err);
210
223
  resolve(true)
211
224
  } else {
@@ -235,6 +248,7 @@ class DirAddTags {
235
248
  httpUtils.request(
236
249
  HTTPREQUEST, async (err, resbody) => {
237
250
  if (err) {
251
+ this.logger.error("Add tag to lead error ", err?.response?.data);
238
252
  winston.error("(httprequest) DirAddTags put lead with new tags err: ", err);
239
253
  resolve(true)
240
254
  } else {
@@ -11,6 +11,7 @@ const Utils = require("../../utils/HttpUtils");
11
11
  const utils = require("../../utils/HttpUtils");
12
12
  const httpUtils = require("../../utils/HttpUtils");
13
13
  const integrationService = require("../../services/IntegrationService");
14
+ const { Logger } = require("../../Logger");
14
15
 
15
16
 
16
17
  class DirAiPrompt {
@@ -27,20 +28,25 @@ class DirAiPrompt {
27
28
  this.token = this.context.token;
28
29
  this.intentDir = new DirIntent(context);
29
30
  this.API_ENDPOINT = this.context.API_ENDPOINT;
31
+ this.log = context.log;
32
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
30
33
  }
31
34
 
32
35
  execute(directive, callback) {
33
36
  winston.verbose("Execute AiPrompt directive");
37
+ this.logger.error("AiPrompt: executing action");
34
38
  let action;
35
39
  if (directive.action) {
36
40
  action = directive.action;
37
41
  }
38
42
  else {
43
+ this.logger.error("AiPrompt incorrect action ", directive)
39
44
  winston.debug("DirAiPrompt Incorrect directive: ", directive);
40
45
  callback();
41
46
  return;
42
47
  }
43
48
  this.go(action, (stop) => {
49
+ this.logger.info("AiPrompt: action completed");
44
50
  callback(stop);
45
51
  })
46
52
  }
@@ -64,6 +70,7 @@ class DirAiPrompt {
64
70
  winston.debug("DirAskGPTV2 falseIntent", falseIntent)
65
71
 
66
72
  await this.checkMandatoryParameters(action).catch( async (missing_param) => {
73
+ this.logger.error(`AiPrompt: missing attribute '${missing_param}'`);
67
74
  await this.chatbot.addParameter("flowError", "AiPrompt Error: '" + missing_param + "' attribute is undefined");
68
75
  if (falseIntent) {
69
76
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -85,6 +92,7 @@ class DirAiPrompt {
85
92
  const filled_context = filler.fill(action.context, requestVariables);
86
93
 
87
94
  if (action.history) {
95
+ this.logger.info("AiPrompt: using chat transcript");
88
96
  let transcript_string = await TiledeskChatbot.getParameterStatic(
89
97
  this.context.tdcache,
90
98
  this.context.requestId,
@@ -95,6 +103,7 @@ class DirAiPrompt {
95
103
  transcript = await TiledeskChatbotUtil.transcriptJSON(transcript_string);
96
104
  winston.debug("DirAiPrompt transcript: ", transcript)
97
105
  } else {
106
+ this.logger.warn("AiPrompt: no chat transcript found, skipping history translation");
98
107
  winston.verbose("DirAiPrompt transcript_string is undefined. Skip JSON translation for chat history")
99
108
  }
100
109
  }
@@ -111,6 +120,7 @@ class DirAiPrompt {
111
120
 
112
121
  if (action.llm === 'ollama') {
113
122
  ollama_integration = await integrationService.getIntegration(this.projectId, action.llm, this.token).catch( async (err) => {
123
+ this.logger.error("AiPrompt: Error getting ollama integration.")
114
124
  winston.error("DirAiPrompt Error getting ollama integration: ", err);
115
125
  await this.chatbot.addParameter("flowError", "Ollama integration not found");
116
126
  if (falseIntent) {
@@ -126,6 +136,7 @@ class DirAiPrompt {
126
136
  key = await integrationService.getKeyFromIntegrations(this.projectId, action.llm, this.token);
127
137
 
128
138
  if (!key) {
139
+ this.logger.error("AiPrompt: llm key not found in integrations");
129
140
  winston.error("Error: DirAiPrompt llm key not found in integrations");
130
141
  await this.chatbot.addParameter("flowError", "AiPrompt Error: missing key for llm " + action.llm);
131
142
  if (falseIntent) {
@@ -188,6 +199,7 @@ class DirAiPrompt {
188
199
  } else {
189
200
  error = JSON.stringify(err.response.data);
190
201
  }
202
+ this.logger.error("AiPrompt: error executing action: ", error);
191
203
  if (falseIntent) {
192
204
  await this.chatbot.addParameter("flowError", "AiPrompt Error: " + error);
193
205
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -200,6 +212,7 @@ class DirAiPrompt {
200
212
 
201
213
  winston.debug("DirAiPrompt resbody: ", resbody);
202
214
  answer = resbody.answer;
215
+ this.logger.info("AiPrompt: answer: ", answer);
203
216
 
204
217
  await this.#assignAttributes(action, answer);
205
218
 
@@ -287,6 +300,7 @@ class DirAiPrompt {
287
300
  }
288
301
  if (result === true) {
289
302
  if (trueIntentDirective) {
303
+ this.logger.info("AiPrompt: executing true condition");
290
304
  this.intentDir.execute(trueIntentDirective, () => {
291
305
  if (callback) {
292
306
  callback();
@@ -294,6 +308,7 @@ class DirAiPrompt {
294
308
  })
295
309
  }
296
310
  else {
311
+ this.logger.info("AiPrompt: no block connected to true condition");
297
312
  winston.debug("DirAiPrompt No trueIntentDirective specified");
298
313
  if (callback) {
299
314
  callback();
@@ -302,6 +317,7 @@ class DirAiPrompt {
302
317
  }
303
318
  else {
304
319
  if (falseIntentDirective) {
320
+ this.logger.info("AiPrompt: executing false condition");
305
321
  this.intentDir.execute(falseIntentDirective, () => {
306
322
  if (callback) {
307
323
  callback();
@@ -309,6 +325,7 @@ class DirAiPrompt {
309
325
  });
310
326
  }
311
327
  else {
328
+ this.logger.info("AiPrompt: no block connected to false condition");
312
329
  winston.debug("DirAiPrompt No falseIntentDirective specified");
313
330
  if (callback) {
314
331
  callback();
@@ -10,6 +10,7 @@ require('dotenv').config();
10
10
  const winston = require('../../utils/winston');
11
11
  const httpUtils = require("../../utils/HttpUtils");
12
12
  const integrationService = require("../../services/IntegrationService");
13
+ const { Logger } = require("../../Logger");
13
14
 
14
15
  class DirAskGPTV2 {
15
16
 
@@ -25,20 +26,25 @@ class DirAskGPTV2 {
25
26
  this.token = this.context.token;
26
27
  this.intentDir = new DirIntent(context);
27
28
  this.API_ENDPOINT = this.context.API_ENDPOINT;
29
+ this.log = context.log;
30
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
28
31
  }
29
32
 
30
33
  execute(directive, callback) {
34
+ this.logger.error("Execute AskKnowledgeBase action")
31
35
  winston.debug("DirAskGPTV2 directive: ", directive);
32
36
  let action;
33
37
  if (directive.action) {
34
38
  action = directive.action;
35
39
  }
36
40
  else {
41
+ this.logger.error("Incorrect action for ", directive.name, directive)
37
42
  winston.debug("DirAskGPTV2 Incorrect directive: ", directive);
38
43
  callback();
39
44
  return;
40
45
  }
41
46
  this.go(action, (stop) => {
47
+ this.logger.info("Acion AskKnowledgeBase completed");
42
48
  callback(stop);
43
49
  })
44
50
  }
@@ -86,6 +92,7 @@ class DirAskGPTV2 {
86
92
  let source = null;
87
93
 
88
94
  if (!action.question || action.question === '') {
95
+ this.logger.error("AskKnowledgeBase question attribute is mandatory");
89
96
  winston.error("DirAskGPTV2 Error: question attribute is mandatory. Executing condition false...");
90
97
  await this.#assignAttributes(action, answer, source);
91
98
  if (falseIntent) {
@@ -129,6 +136,7 @@ class DirAskGPTV2 {
129
136
  const filled_context = filler.fill(action.context, requestVariables)
130
137
 
131
138
  if (action.history) {
139
+ this.logger.info("AskKnowledgeBase: use chat transcript")
132
140
  let transcript_string = await TiledeskChatbot.getParameterStatic(
133
141
  this.context.tdcache,
134
142
  this.context.requestId,
@@ -140,6 +148,7 @@ class DirAskGPTV2 {
140
148
  transcript = await TiledeskChatbotUtil.transcriptJSON(transcript_string);
141
149
  winston.debug("DirAskGPTV2 transcript ", transcript)
142
150
  } else {
151
+ this.logger.warn("AskKnowledgeBase: chat transcript is undefined. Skip JSON translation for chat history.");
143
152
  winston.verbose("DirAskGPT transcript_string is undefined. Skip JSON translation for chat history")
144
153
  }
145
154
  }
@@ -149,6 +158,7 @@ class DirAskGPTV2 {
149
158
 
150
159
  let key = await integrationService.getKeyFromIntegrations(this.projectId, 'openai', this.token);
151
160
  if (!key) {
161
+ this.logger.debug("AskKnowledgeBase OpenAI key not found in Integration. Using shared OpenAI key");
152
162
  winston.verbose("DirAskGPTV2 - Key not found in Integrations. Searching in kb settings...");
153
163
  key = await this.getKeyFromKbSettings();
154
164
  }
@@ -157,6 +167,8 @@ class DirAskGPTV2 {
157
167
  winston.verbose("DirAskGPTV2 - Retrieve public gptkey")
158
168
  key = process.env.GPTKEY;
159
169
  publicKey = true;
170
+ } else {
171
+ this.logger.debug("AskKnowledgeBase use your own OpenAI key")
160
172
  }
161
173
 
162
174
  if (!key) {
@@ -174,6 +186,7 @@ class DirAskGPTV2 {
174
186
  if (publicKey === true) {
175
187
  let keep_going = await this.checkQuoteAvailability();
176
188
  if (keep_going === false) {
189
+ this.logger.warn("AskKnowledgeBase Tokens quota exceeded. Skip the action")
177
190
  winston.verbose("DirAskGPTV2 - Quota exceeded for tokens. Skip the action")
178
191
  await this.chatbot.addParameter("flowError", "AskGPT Error: tokens quota exceeded");
179
192
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -187,14 +200,17 @@ class DirAskGPTV2 {
187
200
  if (action.namespaceAsName) {
188
201
  // Namespace could be an attribute
189
202
  const filled_namespace = filler.fill(action.namespace, requestVariables)
203
+ this.logger.debug("AskKnowledgeBase Searching namespace by name ", filled_namespace);
190
204
  ns = await this.getNamespace(filled_namespace, null);
191
205
  namespace = ns?.id;
192
206
  winston.verbose("DirAskGPTV2 - Retrieved namespace id from name " + namespace);
193
207
  } else {
208
+ this.logger.debug("AskKnowledgeBase Searching namespace by id ", namespace);
194
209
  ns = await this.getNamespace(null, namespace);
195
210
  }
196
211
 
197
212
  if (!ns) {
213
+ this.logger.error("AskKnowledgeBase Namespace not found")
198
214
  await this.#assignAttributes(action, answer);
199
215
  await this.chatbot.addParameter("flowError", "AskGPT Error: namespace not found");
200
216
  if (falseIntent) {
@@ -213,6 +229,7 @@ class DirAskGPTV2 {
213
229
  }
214
230
 
215
231
  if (!namespace) {
232
+ this.logger.error("AskKnowledgeBase Namespace is undefined")
216
233
  winston.verbose("DirAskGPTV2 - Error: namespace is undefined")
217
234
  if (falseIntent) {
218
235
  await this.chatbot.addParameter("flowError", "AskGPT Error: namespace is undefined");
@@ -0,0 +1,76 @@
1
+
2
+
3
+ const { Logger } = require('../../Logger');
4
+ const winston = require('../../utils/winston');
5
+ let levels = ['error', 'warn', 'info', 'debug'];
6
+
7
+ class DirFlowLog {
8
+
9
+ constructor(context) {
10
+ if (!context) {
11
+ throw new Error('context object is mandatory.');
12
+ }
13
+ this.context = context;
14
+ this.chatbot = context.chatbot;
15
+ this.tdcache = context.tdcache;
16
+ this.requestId = context.requestId;
17
+ this.log = context.log;
18
+
19
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
20
+ }
21
+
22
+ execute(directive, callback) {
23
+ winston.verbose("Execute FlowLog directive");
24
+ let action;
25
+ if (directive.action) {
26
+ action = directive.action;
27
+ }
28
+ else {
29
+ winston.warn("DirGptTask Incorrect directive: ", directive);
30
+ callback();
31
+ return;
32
+ }
33
+
34
+ this.go(action, () => {
35
+ callback();
36
+ })
37
+ }
38
+
39
+ async go(action, callback) {
40
+ winston.debug("(DirFlowLog) Action: ", action);
41
+ console.log("(DirFlowLog) Action: ", action);
42
+
43
+ let level = action.level || 'info';
44
+ if (!levels.includes(level)) {
45
+ winston.warn("Invalid log level " + level);
46
+ this.logger.error("Invalid log level: " + level);
47
+ callback();
48
+ }
49
+
50
+ if (!action.log) {
51
+ winston.debug("Log text is empty");
52
+ callback();
53
+ }
54
+
55
+ if (level === 'error') {
56
+ winston.info("Adding log " + action.log + " with level " + level);
57
+ this.logger.error(action.log);
58
+ }
59
+ else if (level === 'warn') {
60
+ winston.info("Adding log " + action.log + " with level " + level);
61
+ this.logger.warn(action.log);
62
+ }
63
+ else if (level === 'info') {
64
+ winston.info("Adding log " + action.log + " with level " + level);
65
+ this.logger.info(action.log);
66
+ }
67
+ else if (level === 'debug') {
68
+ winston.info("Adding log " + action.log + " with level " + level);
69
+ this.logger.debug(action.log);
70
+ }
71
+
72
+ callback();
73
+ }
74
+ }
75
+
76
+ module.exports = { DirFlowLog };
@@ -4,6 +4,7 @@ const { Filler } = require('../Filler');
4
4
  const { TiledeskChatbot } = require('../../engine/TiledeskChatbot');
5
5
  const { DirIntent } = require('./DirIntent');
6
6
  const winston = require('../../utils/winston');
7
+ const { Logger } = require('../../Logger');
7
8
 
8
9
  class DirWebRequestV2 {
9
10
 
@@ -16,6 +17,8 @@ class DirWebRequestV2 {
16
17
  this.requestId = context.requestId;
17
18
  this.chatbot = context.chatbot;
18
19
  this.intentDir = new DirIntent(context);
20
+ this.log = context.log;
21
+ this.logger = new Logger({ request_id: this.requestId, dev: this.context.supportRequest.draft });
19
22
  }
20
23
 
21
24
  execute(directive, callback) {
@@ -29,7 +32,9 @@ class DirWebRequestV2 {
29
32
  callback();
30
33
  return;
31
34
  }
35
+ this.logger.info("Executing WebRequest action ", directive.action)
32
36
  this.go(action, (stop) => {
37
+ this.logger.info("WebRequest action terminated")
33
38
  callback(stop);
34
39
  }).catch((err) => {
35
40
  // do not nothing
@@ -64,6 +69,7 @@ class DirWebRequestV2 {
64
69
  const url = filler.fill(action.url, requestAttributes);
65
70
 
66
71
  let headers = await this.getHeadersFromAction(action, filler, requestAttributes).catch( async (err) => {
72
+ this.logger.error("WebRequest: error getting headers");
67
73
  await this.chatbot.addParameter("flowError", "Error getting headers");
68
74
  if (falseIntent) {
69
75
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -75,6 +81,7 @@ class DirWebRequestV2 {
75
81
  });
76
82
 
77
83
  let json = await this.getJsonFromAction(action, filler, requestAttributes).catch( async (err) => {
84
+ this.logger.error("WebRequest: error parsing json body");
78
85
  await this.chatbot.addParameter("flowError", "Error parsing json body");
79
86
  if (falseIntent) {
80
87
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
@@ -106,8 +113,10 @@ class DirWebRequestV2 {
106
113
  let error = res.error;
107
114
  await this.#assignAttributes(action, resbody, status, error)
108
115
  winston.debug("DirWebRequestV2 resbody:", resbody);
116
+ this.logger.info("WebRequest resbody: ", resbody);
109
117
 
110
118
  if (err) {
119
+ this.logger.error("WebRequest error: ", err);
111
120
  winston.log("webRequest error: ", err);
112
121
  if (callback) {
113
122
  if (falseIntent) {
@@ -129,6 +138,7 @@ class DirWebRequestV2 {
129
138
  return;
130
139
  }
131
140
  else {
141
+ this.logger.warn("WebRequest status ", status);
132
142
  if (falseIntent) {
133
143
  await this.#executeCondition(false, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes);
134
144
  callback(true);
@@ -227,6 +237,7 @@ class DirWebRequestV2 {
227
237
  }
228
238
  if (result === true) {
229
239
  if (trueIntentDirective) {
240
+ this.logger.info("WebRequest: executing true condition");
230
241
  this.intentDir.execute(trueIntentDirective, () => {
231
242
  if (callback) {
232
243
  callback();
@@ -234,6 +245,7 @@ class DirWebRequestV2 {
234
245
  });
235
246
  }
236
247
  else {
248
+ this.logger.info("WebRequest: no block connected to true condition");
237
249
  winston.debug("DirWebRequestV2 No trueIntentDirective specified");
238
250
  if (callback) {
239
251
  callback();
@@ -242,6 +254,7 @@ class DirWebRequestV2 {
242
254
  }
243
255
  else {
244
256
  if (falseIntentDirective) {
257
+ this.logger.info("WebRequest: executing false condition");
245
258
  this.intentDir.execute(falseIntentDirective, () => {
246
259
  if (callback) {
247
260
  callback();
@@ -249,6 +262,7 @@ class DirWebRequestV2 {
249
262
  });
250
263
  }
251
264
  else {
265
+ this.logger.info("WebRequest: no block connected to false condition");
252
266
  winston.debug("DirWebRequestV2 No falseIntentDirective specified");
253
267
  if (callback) {
254
268
  callback();
@@ -60,6 +60,7 @@ class Directives {
60
60
  static ADD_TAGS = 'add_tags'
61
61
  static WEBHOOK = 'webhook';
62
62
  static WEB_RESPONSE = "web_response";
63
+ static FLOW_LOG = "flow_log";
63
64
 
64
65
  // static WHEN_ONLINE_MOVE_TO_AGENT = "whenonlinemovetoagent"; // DEPRECATED?
65
66
  // static WHEN_OFFLINE_HOURS = "whenofflinehours"; // DEPRECATED // adds a message on top of the original message when offline hours opts: --replace