wingbot 3.44.1 → 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.1",
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,
@@ -75,7 +75,7 @@ const Ai = require('../Ai');
75
75
 
76
76
  /**
77
77
  * @callback UserExtractor
78
- * @param {Request} req
78
+ * @param {object} state
79
79
  * @returns {object & GAUser}
80
80
  */
81
81
 
@@ -110,12 +110,29 @@ const Ai = require('../Ai');
110
110
  * @returns {Promise}
111
111
  */
112
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
+
113
130
  /**
114
131
  *
115
132
  * @param {HandlerConfig} config
116
133
  * @param {IAnalyticsStorage} analyticsStorage
117
134
  * @param {IConfidenceProvider} [ai]
118
- * @returns {IInteractionHandler}
135
+ * @returns {Handlers}
119
136
  */
120
137
  function onInteractionHandler (
121
138
  {
@@ -123,7 +140,7 @@ function onInteractionHandler (
123
140
  throwException = false,
124
141
  log = console,
125
142
  anonymize = (x) => x,
126
- userExtractor = (req) => null // eslint-disable-line no-unused-vars
143
+ userExtractor = (state) => null // eslint-disable-line no-unused-vars
127
144
  },
128
145
  analyticsStorage,
129
146
  ai = Ai.ai
@@ -366,7 +383,7 @@ function onInteractionHandler (
366
383
  });
367
384
  }
368
385
 
369
- const user = userExtractor(req);
386
+ const user = userExtractor(req.state);
370
387
 
371
388
  await analyticsStorage.storeEvents(
372
389
  pageId,
@@ -387,7 +404,61 @@ function onInteractionHandler (
387
404
  }
388
405
  }
389
406
 
390
- 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
+ };
391
462
  }
392
463
 
393
464
  module.exports = onInteractionHandler;