wingbot 3.44.0 → 3.44.2

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": "wingbot",
3
- "version": "3.44.0",
3
+ "version": "3.44.2",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/BotApp.js CHANGED
@@ -28,6 +28,8 @@ const DEFAULT_API_URL = 'https://orchestrator-api.wingbot.ai';
28
28
 
29
29
  /** @typedef {import('./analytics/onInteractionHandler').IAnalyticsStorage} IAnalyticsStorage */
30
30
  /** @typedef {import('./analytics/onInteractionHandler').HandlerConfig} HandlerConfig */
31
+ /** @typedef {import('./analytics/onInteractionHandler').OnEventHandler} OnEventHandler */
32
+ /** @typedef {import('./analytics/onInteractionHandler').Event} Event */
31
33
 
32
34
  /**
33
35
  * @typedef {object} BotAppOptions
@@ -123,6 +125,9 @@ class BotApp {
123
125
 
124
126
  this._processor.plugin(BotApp.plugin());
125
127
  this._preferSynchronousResponse = preferSynchronousResponse;
128
+
129
+ /** @type {OnEventHandler[]} */
130
+ this._eventHandlers = [];
126
131
  }
127
132
 
128
133
  /**
@@ -195,16 +200,43 @@ class BotApp {
195
200
 
196
201
  analyticsStorage.setDefaultLogger(log);
197
202
 
198
- const handler = onInteractionHandler({
203
+ const { onInteraction, onEvent } = onInteractionHandler({
199
204
  log,
200
205
  anonymize: this._textFilter,
201
206
  ...options
202
207
  }, analyticsStorage);
203
208
 
204
- this.processor.on('interaction', handler);
209
+ this._eventHandlers.push(onEvent);
210
+ this.processor.on('interaction', onInteraction);
205
211
  return this;
206
212
  }
207
213
 
214
+ /**
215
+ * Method for tracking special events
216
+ *
217
+ * @param {string} pageId
218
+ * @param {string} senderId
219
+ * @param {Event} event
220
+ * @param {number} [ts]
221
+ * @param {boolean} [nonInteractive]
222
+ */
223
+ async trackEvent (pageId, senderId, event, ts = Date.now(), nonInteractive = false) {
224
+ const state = this._processor.stateStorage.getState(senderId, pageId);
225
+
226
+ if (!state) {
227
+ throw new Error(`State ${pageId}:${senderId} not found. Ensure the #trackEvent() method was called after the conversation has started`);
228
+ }
229
+
230
+ await Promise.all(this._eventHandlers.map((handler) => handler(
231
+ pageId,
232
+ senderId,
233
+ state.state,
234
+ event,
235
+ ts,
236
+ nonInteractive
237
+ )));
238
+ }
239
+
208
240
  _errorResponse (message, status) {
209
241
  return {
210
242
  statusCode: status,
@@ -11,7 +11,7 @@ const Ai = require('../Ai');
11
11
 
12
12
  /**
13
13
  * @typedef {object} GAUser
14
- * @prop {string} id
14
+ * @prop {string} [id]
15
15
  */
16
16
 
17
17
  /**
@@ -55,6 +55,8 @@ const Ai = require('../Ai');
55
55
  * @param {Event[]} events
56
56
  * @param {GAUser} [user]
57
57
  * @param {number} [ts]
58
+ * @param {boolean} [nonInteractive]
59
+ * @param {boolean} [sessionStarted]
58
60
  * @returns {Promise}
59
61
  */
60
62
 
@@ -72,9 +74,9 @@ const Ai = require('../Ai');
72
74
  */
73
75
 
74
76
  /**
75
- * @callback MetadataExtractor
76
- * @param {Request} req
77
- * @returns {object}
77
+ * @callback UserExtractor
78
+ * @param {object} state
79
+ * @returns {object & GAUser}
78
80
  */
79
81
 
80
82
  /**
@@ -99,7 +101,7 @@ const Ai = require('../Ai');
99
101
  * @prop {boolean} [throwException] - default false
100
102
  * @prop {IGALogger} [log] - console like logger
101
103
  * @prop {Anonymizer} [anonymize] - text anonymization function
102
- * @prop {MetadataExtractor} [extractMetadata] - text anonymization function
104
+ * @prop {UserExtractor} [userExtractor] - text anonymization function
103
105
  */
104
106
 
105
107
  /**
@@ -108,12 +110,29 @@ const Ai = require('../Ai');
108
110
  * @returns {Promise}
109
111
  */
110
112
 
113
+ /**
114
+ * @typedef {object} Handlers
115
+ * @prop {IInteractionHandler} onInteraction
116
+ * @prop {OnEventHandler} onEvent
117
+ */
118
+
119
+ /**
120
+ * @callback OnEventHandler
121
+ * @param {string} pageId
122
+ * @param {string} senderId
123
+ * @param {object} state
124
+ * @param {Event} event
125
+ * @param {number} [timestamp]
126
+ * @param {boolean} [nonInteractive]
127
+ * @returns {Promise}
128
+ */
129
+
111
130
  /**
112
131
  *
113
132
  * @param {HandlerConfig} config
114
133
  * @param {IAnalyticsStorage} analyticsStorage
115
134
  * @param {IConfidenceProvider} [ai]
116
- * @returns {IInteractionHandler}
135
+ * @returns {Handlers}
117
136
  */
118
137
  function onInteractionHandler (
119
138
  {
@@ -121,7 +140,7 @@ function onInteractionHandler (
121
140
  throwException = false,
122
141
  log = console,
123
142
  anonymize = (x) => x,
124
- extractMetadata = (req) => ({}) // eslint-disable-line no-unused-vars
143
+ userExtractor = (state) => null // eslint-disable-line no-unused-vars
125
144
  },
126
145
  analyticsStorage,
127
146
  ai = Ai.ai
@@ -163,9 +182,7 @@ function onInteractionHandler (
163
182
  const metadata = {
164
183
  sessionCount,
165
184
  lang,
166
- action,
167
- cd1: (req.state.user && req.state.user.department) || 'unknown',
168
- ...extractMetadata(req)
185
+ action
169
186
  };
170
187
 
171
188
  await analyticsStorage.createUserSession(
@@ -366,7 +383,7 @@ function onInteractionHandler (
366
383
  });
367
384
  }
368
385
 
369
- const user = null;
386
+ const user = userExtractor(req.state);
370
387
 
371
388
  await analyticsStorage.storeEvents(
372
389
  pageId,
@@ -375,7 +392,9 @@ function onInteractionHandler (
375
392
  // @ts-ignore
376
393
  events,
377
394
  user,
378
- timestamp
395
+ timestamp,
396
+ nonInteractive,
397
+ createSession
379
398
  );
380
399
  } catch (e) {
381
400
  if (throwException) {
@@ -385,7 +404,61 @@ function onInteractionHandler (
385
404
  }
386
405
  }
387
406
 
388
- return onInteraction;
407
+ /**
408
+ *
409
+ * @param {string} pageId
410
+ * @param {string} senderId
411
+ * @param {object} state
412
+ * @param {Event} event
413
+ * @param {number} [timestamp]
414
+ * @param {boolean} [nonInteractive]
415
+ */
416
+ const onEvent = async (
417
+ pageId,
418
+ senderId,
419
+ state,
420
+ event,
421
+ timestamp = Date.now(),
422
+ nonInteractive = false
423
+ ) => {
424
+ try {
425
+ const {
426
+ _sid: sessionId,
427
+ lang,
428
+ lastAction
429
+ } = state;
430
+
431
+ const user = userExtractor(state);
432
+
433
+ await analyticsStorage.storeEvents(
434
+ pageId,
435
+ senderId,
436
+ sessionId,
437
+ [{
438
+ // @ts-ignore
439
+ lastAction,
440
+ ...(analyticsStorage.hasExtendedEvents
441
+ ? { lang }
442
+ : { cd1: lang }),
443
+ ...event
444
+ }],
445
+ user,
446
+ timestamp,
447
+ nonInteractive,
448
+ false
449
+ );
450
+ } catch (e) {
451
+ if (throwException) {
452
+ throw e;
453
+ }
454
+ log.error('failed sending logs', e);
455
+ }
456
+ };
457
+
458
+ return {
459
+ onInteraction,
460
+ onEvent
461
+ };
389
462
  }
390
463
 
391
464
  module.exports = onInteractionHandler;