wingbot 3.37.3 → 3.38.0-alpha.1

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.37.3",
3
+ "version": "3.38.0-alpha.1",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -5,7 +5,31 @@
5
5
 
6
6
  let handlebars;
7
7
  try {
8
+ // @ts-ignore
8
9
  handlebars = module.require('handlebars');
10
+
11
+ handlebars.registerHelper('lang', function langHelper (content) {
12
+ if (typeof content !== 'object' || !content) {
13
+ return content;
14
+ }
15
+
16
+ const { lang } = this;
17
+
18
+ if (content[lang]) {
19
+ return content[lang];
20
+ }
21
+
22
+ if (Array.isArray(content)) {
23
+ const entry = content.find((c) => c
24
+ && (!lang || c.l === lang || c.lang === lang) && (c.t || c.text));
25
+
26
+ if (entry) {
27
+ return entry.text || entry.t;
28
+ }
29
+ }
30
+
31
+ return content[Object.keys(content)[0]];
32
+ });
9
33
  } catch (er) {
10
34
  handlebars = { compile: (text) => () => text };
11
35
  }
@@ -16,6 +16,7 @@ const button = require('./button');
16
16
  const subscribtions = require('./subscribtions');
17
17
  const setState = require('./setState');
18
18
  const expectedInput = require('./expectedInput');
19
+ const skip = require('./skip');
19
20
 
20
21
  module.exports = {
21
22
  path,
@@ -30,5 +31,6 @@ module.exports = {
30
31
  button,
31
32
  subscribtions,
32
33
  setState,
33
- expectedInput
34
+ expectedInput,
35
+ skip
34
36
  };
@@ -195,9 +195,6 @@ function message (params, context = {}) {
195
195
  * @param {Responder} res
196
196
  */
197
197
  return (req, res) => {
198
- if (condition && !condition(req, res)) {
199
- return ret;
200
- }
201
198
  const data = stateData(req, res, configuration);
202
199
 
203
200
  // filter supported messages
@@ -216,30 +213,51 @@ function message (params, context = {}) {
216
213
  const text = textTemplate(data)
217
214
  .trim();
218
215
 
216
+ res.setData({ $this: text });
217
+ if (condition && !condition(req, res)) {
218
+ res.setData({ $this: null });
219
+ return ret;
220
+ }
221
+ res.setData({ $this: null });
222
+
219
223
  let sendReplies;
220
224
  if (quickReplies) {
221
- const okQuickReplies = quickReplies
222
- .filter((reply) => reply.condition(req, res));
223
-
224
- sendReplies = okQuickReplies
225
+ sendReplies = quickReplies
225
226
  .filter((reply) => reply.title
226
227
  || reply.isLocation
227
228
  || reply.isEmail
228
229
  || reply.isPhone)
229
230
  .map((reply) => {
230
- const rep = (reply.isLocation || reply.isEmail || reply.isPhone)
231
- ? ({ ...reply })
232
- : ({ ...reply, title: reply.title(data) });
231
+ let $this = null;
232
+ let rep;
233
+
234
+ if (reply.isLocation || reply.isEmail || reply.isPhone) {
235
+ rep = { ...reply };
236
+ } else {
237
+ const title = reply.title(data);
238
+ $this = title;
239
+ rep = { ...reply, title };
240
+ }
241
+
242
+ if (typeof rep.condition !== 'function') {
243
+ return rep;
244
+ }
233
245
 
234
- if (typeof rep.condition === 'function') {
235
- delete rep.condition;
246
+ res.setData({ $this });
247
+ if (!rep.condition(req, res)) {
248
+ res.setData({ $this: null });
249
+ return null;
236
250
  }
251
+ res.setData({ $this: null });
252
+
253
+ delete rep.condition;
237
254
 
238
255
  return rep;
239
- });
256
+ })
257
+ .filter((rep) => rep !== null);
240
258
 
241
- okQuickReplies
242
- .filter((reply) => !reply.title && reply.match)
259
+ quickReplies
260
+ .filter((reply) => !reply.title && reply.match && reply.condition(req, res))
243
261
  .forEach(({
244
262
  match, action, data: replyData, setState, aiTitle
245
263
  }) => {
@@ -0,0 +1,57 @@
1
+ /*
2
+ * @author David Menger
3
+ */
4
+ 'use strict';
5
+
6
+ const Router = require('../Router');
7
+ const getCondition = require('../utils/getCondition');
8
+
9
+ /** @typedef {import('../BuildRouter').BotContext} BotContext */
10
+ /** @typedef {import('../Router').Resolver} Resolver */
11
+
12
+ /**
13
+ *
14
+ * @param {object} params
15
+ * @param {BotContext} context
16
+ * @returns {Resolver}
17
+ */
18
+ function skip (params, context = {}) {
19
+ const { isLastIndex } = context;
20
+ const { type } = params;
21
+
22
+ const ret = isLastIndex ? Router.END : Router.CONTINUE;
23
+
24
+ if (['skip', 'end', 'intent'].indexOf(type) === -1) {
25
+ throw new Error(`Unsupported skip type: ${type}`);
26
+ }
27
+
28
+ const condition = getCondition(params, context, 'Skip condition');
29
+
30
+ return (req, res, postBack) => {
31
+ if (condition && !condition(req, res)) {
32
+ return ret;
33
+ }
34
+
35
+ switch (type) {
36
+ case 'end':
37
+ return Router.END;
38
+ case 'skip':
39
+ return Router.BREAK;
40
+ case 'intent': {
41
+ let { lastAiActionsIndex = 0 } = req.actionData();
42
+ const actions = req.aiActions();
43
+ lastAiActionsIndex++;
44
+ if (!actions[lastAiActionsIndex] || !actions[lastAiActionsIndex].aboveConfidence) {
45
+ return Router.BREAK;
46
+ }
47
+ postBack(actions[lastAiActionsIndex].action, { lastAiActionsIndex });
48
+ return Router.END;
49
+ }
50
+
51
+ default:
52
+ return ret;
53
+ }
54
+ };
55
+ }
56
+
57
+ module.exports = skip;
@@ -88,8 +88,23 @@ const ARRAY_LENGTH_OPERATORS = [
88
88
  const compare = (variable, operator, value = undefined) => {
89
89
  const isArrayLengthCompare = ARRAY_LENGTH_OPERATORS.includes(operator);
90
90
  if (Array.isArray(variable) && !isArrayLengthCompare) {
91
- // @todo if value === number && operator === '=='
92
- return variable.some((variableElement) => compare(variableElement, operator, value));
91
+ if (operator === ConditionOperators['==']
92
+ && (typeof value === 'number' || isStringNumber(value))) {
93
+
94
+ const numeric = toNumber(value);
95
+ return numeric === variable.length;
96
+ }
97
+
98
+ if (operator === ConditionOperators['not contains']) {
99
+ return variable
100
+ .every((variableElement) => !compare(variableElement, ConditionOperators['=='], value));
101
+ }
102
+
103
+ const useOperator = operator === ConditionOperators.contains
104
+ ? ConditionOperators['==']
105
+ : operator;
106
+
107
+ return variable.some((variableElement) => compare(variableElement, useOperator, value));
93
108
  }
94
109
 
95
110
  if (variable && typeof variable === 'object' && !isArrayLengthCompare) {
@@ -161,6 +161,8 @@ function getSetState (setState, req, res = null, useState = null, configuration
161
161
  valAsArray.shift();
162
162
  } else if (val._$pop) {
163
163
  valAsArray.pop();
164
+ } else if (val._$pushT) {
165
+ valAsArray.push(req.text());
164
166
  } else {
165
167
  const value = val._$add || val._$rem || val._$push || val._$set;
166
168
  const [, entity, rear] = `${value}`.match(ENTITY_HBS_REGEXP) || [];
@@ -17,11 +17,12 @@ module.exports = function stateData (req, res = null, configuration = null) {
17
17
  const c = configuration || req.configuration;
18
18
 
19
19
  return {
20
+ c,
21
+ configuration: c,
20
22
  ...req.state,
21
23
  ...(res ? res.newState : {}),
22
24
  ...req.actionData(),
23
25
  ...(res ? res.data : {}),
24
- c,
25
- configuration: c
26
+ $input: req.text()
26
27
  };
27
28
  };