wingbot 3.66.0-alpha.1 → 3.66.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 +1 -1
- package/src/BotApp.js +6 -3
- package/src/BuildRouter.js +12 -8
- package/src/Processor.js +15 -6
- package/src/ReturnSender.js +57 -6
- package/src/Tester.js +4 -1
- package/src/responderFactory.js +0 -32
package/package.json
CHANGED
package/src/BotApp.js
CHANGED
|
@@ -39,6 +39,7 @@ const DEFAULT_API_URL = 'https://orchestrator-api.wingbot.ai';
|
|
|
39
39
|
* @prop {Function} [fetch]
|
|
40
40
|
* @prop {ChatLogStorage} [chatLogStorage]
|
|
41
41
|
* @prop {boolean} [preferSynchronousResponse]
|
|
42
|
+
* @prop {boolean} [deferLogs]
|
|
42
43
|
* @prop {AuditLog} [auditLog]
|
|
43
44
|
* @prop {TlsOptions} [tls]
|
|
44
45
|
*
|
|
@@ -91,6 +92,7 @@ class BotApp {
|
|
|
91
92
|
} = options;
|
|
92
93
|
|
|
93
94
|
this._returnSenderOptions = {
|
|
95
|
+
dontWaitForDeferredOps: processorOptions.deferLogs,
|
|
94
96
|
textFilter,
|
|
95
97
|
logStandbyEvents,
|
|
96
98
|
confidentInputFilter
|
|
@@ -312,8 +314,8 @@ class BotApp {
|
|
|
312
314
|
const sender = new ReturnSender(options, senderId, message, this._senderLogger);
|
|
313
315
|
sender.propagatesWaitEvent = true;
|
|
314
316
|
const res = await this._processor.processMessage(message, pageId, sender, { appId });
|
|
315
|
-
|
|
316
|
-
|
|
317
|
+
sender.defer(this._processSenderResponses(sender, senderId, pageId, headers));
|
|
318
|
+
await sender.waitForDeferredOps();
|
|
317
319
|
return {
|
|
318
320
|
status: res.status,
|
|
319
321
|
// yes, it should be just mid
|
|
@@ -337,7 +339,8 @@ class BotApp {
|
|
|
337
339
|
|
|
338
340
|
const sender = await this.createSender(senderId, pageId, message, secret, appId);
|
|
339
341
|
const res = await this._processor.processMessage(message, pageId, sender, { appId });
|
|
340
|
-
|
|
342
|
+
sender.defer(this._processSenderResponses(sender, senderId, pageId, headers));
|
|
343
|
+
await sender.waitForDeferredOps();
|
|
341
344
|
|
|
342
345
|
return {
|
|
343
346
|
status: res.status,
|
package/src/BuildRouter.js
CHANGED
|
@@ -111,17 +111,21 @@ const DUMMY_ROUTE = { id: 0, path: null, resolvers: [] };
|
|
|
111
111
|
* @param {object} state
|
|
112
112
|
* @param {string} pageId
|
|
113
113
|
* @returns {string}
|
|
114
|
-
|
|
114
|
+
*/
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
117
|
* @template {BaseConfiguration} [C=object]
|
|
118
|
-
* @typedef {object}
|
|
118
|
+
* @typedef {object} BuildRouterContext
|
|
119
119
|
* @prop {LinkTranslator} [linksTranslator] - function, that translates links globally
|
|
120
120
|
* @prop {ConfigStorage} [configStorage] - function, that translates links globally
|
|
121
121
|
* @prop {boolean} [allowForbiddenSnippetWords] - disable security rule
|
|
122
122
|
* @prop {Middleware} [defaultPlugin] - to be able to test configurations without plugins
|
|
123
123
|
* @prop {RouteConfig[]} [routeConfigs] - list of disabled routes
|
|
124
124
|
* @prop {C} [configuration] - context data
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @typedef {object} BotContextExtention
|
|
125
129
|
* @prop {LinksMap} [linksMap]
|
|
126
130
|
* @prop {boolean} [isLastIndex]
|
|
127
131
|
* @prop {boolean} [isLastMessage]
|
|
@@ -140,6 +144,11 @@ const DUMMY_ROUTE = { id: 0, path: null, resolvers: [] };
|
|
|
140
144
|
* @prop {string|number} [resolverId] - only for text messages with random characters
|
|
141
145
|
*/
|
|
142
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @template {BaseConfiguration} [C=object]
|
|
149
|
+
* @typedef {BotContextExtention & BuildRouterContext<C>} BotContext
|
|
150
|
+
*/
|
|
151
|
+
|
|
143
152
|
/**
|
|
144
153
|
* Build bot from Wingbot configuration file or snapshot url
|
|
145
154
|
*
|
|
@@ -156,12 +165,7 @@ class BuildRouter extends Router {
|
|
|
156
165
|
* @constructor
|
|
157
166
|
* @param {BotConfig|Block} block
|
|
158
167
|
* @param {Plugins} plugins - custom code blocks resource
|
|
159
|
-
* @param {
|
|
160
|
-
* @param {object} [context.linksTranslator] - function, that translates links globally
|
|
161
|
-
* @param {ConfigStorage} [context.configStorage] - function, that translates links globally
|
|
162
|
-
* @param {boolean} [context.allowForbiddenSnippetWords] - disable security rule
|
|
163
|
-
* @param {RouteConfig[]} [context.routeConfigs] - list of disabled routes
|
|
164
|
-
* @param {C} [context.configuration]
|
|
168
|
+
* @param {BuildRouterContext<C>} context - the building context
|
|
165
169
|
* @param {fetch} [fetchFn] - override a request function
|
|
166
170
|
* @example
|
|
167
171
|
*
|
package/src/Processor.js
CHANGED
|
@@ -403,7 +403,7 @@ class Processor extends EventEmitter {
|
|
|
403
403
|
const result = await this
|
|
404
404
|
._dispatch(message, pageId, messageSender, responderData, preloadPromise);
|
|
405
405
|
|
|
406
|
-
|
|
406
|
+
messageSender.defer(preloadPromise, this.options.log);
|
|
407
407
|
return result;
|
|
408
408
|
}
|
|
409
409
|
|
|
@@ -419,7 +419,7 @@ class Processor extends EventEmitter {
|
|
|
419
419
|
} = await this
|
|
420
420
|
._processMessage(message, pageId, messageSender, responderData, preloadPromise));
|
|
421
421
|
|
|
422
|
-
|
|
422
|
+
messageSender.defer(this._emitInteractionEvent(req, res, messageSender, state, data));
|
|
423
423
|
|
|
424
424
|
return messageSender.finished(req, res, null, errorHandler);
|
|
425
425
|
} catch (e) {
|
|
@@ -579,7 +579,7 @@ class Processor extends EventEmitter {
|
|
|
579
579
|
let req;
|
|
580
580
|
let res;
|
|
581
581
|
|
|
582
|
-
let emitPromise = Promise.resolve();
|
|
582
|
+
// let emitPromise = Promise.resolve();
|
|
583
583
|
|
|
584
584
|
try {
|
|
585
585
|
// ensure the request was not processed
|
|
@@ -776,7 +776,7 @@ class Processor extends EventEmitter {
|
|
|
776
776
|
}
|
|
777
777
|
|
|
778
778
|
if (fromEvent) {
|
|
779
|
-
|
|
779
|
+
messageSender.defer(this._emitEvent(req, res), this.options.log);
|
|
780
780
|
}
|
|
781
781
|
}
|
|
782
782
|
|
|
@@ -822,13 +822,22 @@ class Processor extends EventEmitter {
|
|
|
822
822
|
|
|
823
823
|
} catch (e) {
|
|
824
824
|
await this.stateStorage.saveState(originalState);
|
|
825
|
-
await emitPromise;
|
|
825
|
+
// await emitPromise;
|
|
826
826
|
Object.assign(e, { req, res });
|
|
827
827
|
throw e;
|
|
828
828
|
}
|
|
829
829
|
|
|
830
|
+
if (postbackAcumulator.length === 0) {
|
|
831
|
+
messageSender.defer(this.stateStorage.saveState(stateObject));
|
|
832
|
+
return {
|
|
833
|
+
req, res, data: res.data, state: stateObject.state
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
|
|
830
837
|
try {
|
|
838
|
+
|
|
831
839
|
await this.stateStorage.saveState(stateObject);
|
|
840
|
+
|
|
832
841
|
// process postbacks
|
|
833
842
|
const {
|
|
834
843
|
state = stateObject.state,
|
|
@@ -842,7 +851,7 @@ class Processor extends EventEmitter {
|
|
|
842
851
|
res.senderMeta
|
|
843
852
|
);
|
|
844
853
|
|
|
845
|
-
await emitPromise; // probably has been resolved this time
|
|
854
|
+
// await emitPromise; // probably has been resolved this time
|
|
846
855
|
|
|
847
856
|
return {
|
|
848
857
|
req, res, data, state
|
package/src/ReturnSender.js
CHANGED
|
@@ -31,6 +31,7 @@ const extractText = require('./transcript/extractText');
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* @typedef {object} ReturnSenderOptions
|
|
34
|
+
* @prop {boolean} [dontWaitForDeferredOps]
|
|
34
35
|
* @prop {textFilter} [textFilter] - filter for saving the texts
|
|
35
36
|
* @prop {boolean} [logStandbyEvents] - log the standby events
|
|
36
37
|
* @prop {textFilter} [confidentInputFilter] - filter for confident input (@CONFIDENT)
|
|
@@ -42,6 +43,16 @@ const extractText = require('./transcript/extractText');
|
|
|
42
43
|
* @prop {string|number} [attachmentId]
|
|
43
44
|
*/
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @callback DeferOperation
|
|
48
|
+
* @returns {Promise<any>}
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @typedef {object} ErrorLogger
|
|
53
|
+
* @prop {Function} error
|
|
54
|
+
*/
|
|
55
|
+
|
|
45
56
|
/**
|
|
46
57
|
* Text filter function
|
|
47
58
|
*
|
|
@@ -147,6 +158,44 @@ class ReturnSender {
|
|
|
147
158
|
this._gotAnotherEventDefer = null;
|
|
148
159
|
this._anotherEventPromise = null;
|
|
149
160
|
this._gotAnotherEvent();
|
|
161
|
+
|
|
162
|
+
this._skipWaitForDeferred = options.dontWaitForDeferredOps;
|
|
163
|
+
this._opQueue = new Set();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async waitForDeferredOps () {
|
|
167
|
+
if (this._skipWaitForDeferred) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
await Promise.all(Array.from(this._opQueue.values()));
|
|
171
|
+
if (this._throwAtTheEnd) {
|
|
172
|
+
const e = this._throwAtTheEnd;
|
|
173
|
+
this._throwAtTheEnd = null;
|
|
174
|
+
throw e;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
*
|
|
180
|
+
* @param {DeferOperation|Promise} operation
|
|
181
|
+
* @param {ErrorLogger} logger
|
|
182
|
+
*/
|
|
183
|
+
defer (operation, logger = console) {
|
|
184
|
+
const promise = (typeof operation === 'function'
|
|
185
|
+
? Promise.resolve(operation())
|
|
186
|
+
: operation
|
|
187
|
+
)
|
|
188
|
+
.catch((e) => {
|
|
189
|
+
if (this._skipWaitForDeferred === false) {
|
|
190
|
+
this._throwAtTheEnd = e;
|
|
191
|
+
}
|
|
192
|
+
// eslint-disable-next-line no-console
|
|
193
|
+
logger.error('DEFER# - op failed', e);
|
|
194
|
+
})
|
|
195
|
+
.then(() => {
|
|
196
|
+
this._opQueue.delete(promise);
|
|
197
|
+
});
|
|
198
|
+
this._opQueue.add(promise);
|
|
150
199
|
}
|
|
151
200
|
|
|
152
201
|
set simulatesOptIn (value) {
|
|
@@ -578,27 +627,29 @@ class ReturnSender {
|
|
|
578
627
|
if (!this._logger || meta.flag === ResponseFlag.DO_NOT_LOG) {
|
|
579
628
|
// noop
|
|
580
629
|
} else if (error) {
|
|
581
|
-
|
|
582
|
-
.error(error, this._senderId, sent, incomming, meta));
|
|
630
|
+
this.defer(Promise.resolve(this._logger
|
|
631
|
+
.error(error, this._senderId, sent, incomming, meta)));
|
|
583
632
|
} else if (this._sendLogs) {
|
|
584
633
|
this._sendLogs = false;
|
|
585
|
-
|
|
586
|
-
.log(this._senderId, sent, incomming, meta));
|
|
634
|
+
this.defer(Promise.resolve(this._logger
|
|
635
|
+
.log(this._senderId, sent, incomming, meta)));
|
|
587
636
|
}
|
|
588
637
|
} catch (e) {
|
|
589
638
|
console.log('meta', meta); // eslint-disable-line no-console
|
|
590
|
-
|
|
639
|
+
this.defer(Promise.resolve(reportError(e, this._incommingMessage, this._senderId)));
|
|
591
640
|
}
|
|
592
641
|
|
|
593
642
|
if (error) {
|
|
594
643
|
// @ts-ignore
|
|
595
644
|
const { code = 500, message } = error;
|
|
596
|
-
|
|
645
|
+
this.defer(Promise.resolve(reportError(error, this._incommingMessage, this._senderId)));
|
|
646
|
+
await this.waitForDeferredOps();
|
|
597
647
|
return { status: code, error: message, results: this.results };
|
|
598
648
|
}
|
|
599
649
|
|
|
600
650
|
const somethingSent = this._results.length > 0;
|
|
601
651
|
|
|
652
|
+
await this.waitForDeferredOps();
|
|
602
653
|
return {
|
|
603
654
|
status: somethingSent ? 200 : 204,
|
|
604
655
|
results: this._results
|
package/src/Tester.js
CHANGED
|
@@ -227,7 +227,10 @@ class Tester {
|
|
|
227
227
|
Object.assign(message, { features: this.features });
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
const messageSender = new ReturnSender({
|
|
230
|
+
const messageSender = new ReturnSender({
|
|
231
|
+
dontWaitForDeferredOps: false
|
|
232
|
+
}, senderId, message, this.senderLogger);
|
|
233
|
+
|
|
231
234
|
messageSender.simulatesOptIn = true;
|
|
232
235
|
|
|
233
236
|
const res = await this.processor
|
package/src/responderFactory.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* @author Vašek Strnad
|
|
3
|
-
*/
|
|
4
|
-
'use strict';
|
|
5
|
-
|
|
6
|
-
const Responder = require('./Responder');
|
|
7
|
-
const { senderFactory } = require('./tools');
|
|
8
|
-
|
|
9
|
-
function responderFactory (options = { token: null }, senderLogger = console, sender = undefined) {
|
|
10
|
-
|
|
11
|
-
const senderFnFactory = senderFactory(
|
|
12
|
-
options.token,
|
|
13
|
-
senderLogger,
|
|
14
|
-
undefined,
|
|
15
|
-
sender
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const factoryFn = function factory (
|
|
19
|
-
senderId,
|
|
20
|
-
senderFn = null,
|
|
21
|
-
pageId = undefined,
|
|
22
|
-
senderHandler = undefined
|
|
23
|
-
) {
|
|
24
|
-
|
|
25
|
-
const sendFn = senderFn || senderFnFactory(null, pageId, senderHandler);
|
|
26
|
-
return new Responder(false, senderId, sendFn, options.token, options);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
return factoryFn;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
module.exports = responderFactory;
|