@botonic/core
Version:
Build Chatbots using React
175 lines • 7.63 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CoreBot = void 0;
const tslib_1 = require("tslib");
const debug_1 = require("./debug");
const models_1 = require("./models");
const plugins_1 = require("./plugins");
const routing_1 = require("./routing");
class CoreBot {
constructor({ renderer, routes, theme, plugins, appId, defaultTyping = 0.6, defaultDelay = 0.4, defaultRoutes, inspector, }) {
this.renderer = renderer;
this.plugins = plugins || {};
this.theme = theme || {};
this.defaultTyping = defaultTyping;
this.defaultDelay = defaultDelay;
this.appId = appId || undefined;
this.rootElement = null;
this.inspector = inspector || new debug_1.Inspector();
this.routes = routes;
this.defaultRoutes = defaultRoutes || [];
this.router =
this.routes instanceof Function
? null
: new routing_1.Router([...this.routes, ...this.defaultRoutes], this.inspector.routeInspector);
}
setSystemLocale(locale, session) {
session.user.system_locale = locale;
}
setUserLocale(locale, session) {
session.user.locale = locale;
}
setUserCountry(country, session) {
session.user.country = country;
}
input(request) {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const botContext = this.getBotContext(request);
const output = yield this.runInput(botContext);
if ((_a = botContext.session._botonic_action) === null || _a === void 0 ? void 0 : _a.startsWith(models_1.BotonicAction.Redirect)) {
return yield this.runRedirectAction(output, botContext);
}
return output;
});
}
getBotContext(request) {
const { input, session, lastRoutePath } = request;
return {
input,
session,
lastRoutePath,
params: {},
plugins: this.plugins,
defaultTyping: this.defaultTyping,
defaultDelay: this.defaultDelay,
getUserCountry: () => session.user.country,
getUserLocale: () => session.user.locale,
getSystemLocale: () => session.user.system_locale,
setUserCountry: (country) => this.setUserCountry(country, session),
setUserLocale: (locale) => this.setUserLocale(locale, session),
setSystemLocale: (locale) => this.setSystemLocale(locale, session),
};
}
runInput(botContext) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
// After first updateSession, user country locale and system_locale are always defined
this.updateSession(botContext.session);
if (botContext.input.type === models_1.INPUT.CHAT_EVENT) {
return {
input: botContext.input,
session: botContext.session,
lastRoutePath: botContext.lastRoutePath,
response: [],
};
}
yield this.runPrePlugins(botContext);
const output = yield this.getOutput(botContext);
botContext = this.updateRequestFromOutput(botContext, output);
const response = yield this.renderer({
request: botContext,
actions: [output.fallbackAction, output.action, output.emptyAction],
});
yield this.runPostPlugins(botContext, response);
botContext.session.is_first_interaction = false;
return {
input: botContext.input,
response,
session: botContext.session,
lastRoutePath: botContext.lastRoutePath,
};
});
}
updateSession(session) {
var _a, _b;
// set new user fields (country, locale, system_locale) from old fields in extra_data
if (!session.user.country) {
const country = (_a = session.user.extra_data) === null || _a === void 0 ? void 0 : _a.country;
this.setUserCountry(country, session);
}
if (!session.user.locale) {
const language = (_b = session.user.extra_data) === null || _b === void 0 ? void 0 : _b.language;
this.setUserLocale(language, session);
}
if (!session.user.system_locale) {
const locale = session.user.locale;
if (locale) {
this.setSystemLocale(locale, session);
}
}
}
runPrePlugins(botContext) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.plugins) {
yield (0, plugins_1.runPlugins)({ botContext, mode: 'pre' });
}
});
}
getOutput(botContext) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield this.setRouter(botContext);
const output = this.router.processInput(botContext.input, botContext.session, botContext.lastRoutePath);
return output;
});
}
setRouter(botContext) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.routes instanceof Function) {
this.router = new routing_1.Router([
...(yield (0, routing_1.getComputedRoutes)(this.routes, botContext)),
...this.defaultRoutes,
], this.inspector.routeInspector);
}
});
}
updateRequestFromOutput(botContext, output) {
return Object.assign(Object.assign({}, botContext), { params: output.params || {}, lastRoutePath: output.lastRoutePath });
}
runPostPlugins(botContext, response) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.plugins) {
yield (0, plugins_1.runPlugins)({
botContext,
mode: 'post',
response,
});
}
});
}
runRedirectAction(previousResponse, botContext, numOfRedirects = 0) {
var _a, _b;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (numOfRedirects > 10) {
throw new Error('Maximum BotAction recursive calls reached (10)');
}
const nextPayload = (_a = botContext.session._botonic_action) === null || _a === void 0 ? void 0 : _a.split(`${models_1.BotonicAction.Redirect}:`)[1];
const inputWithBotActionPayload = Object.assign(Object.assign({}, botContext.input), { payload: nextPayload, type: models_1.INPUT.POSTBACK, data: undefined, text: undefined });
botContext.session._botonic_action = undefined;
botContext.input = inputWithBotActionPayload;
const followUp = yield this.runInput(botContext);
const response = {
input: followUp.input,
response: previousResponse.response.concat(followUp.response),
session: botContext.session,
lastRoutePath: followUp.lastRoutePath,
};
// Recursive call to handle multiple bot actions in a row
if ((_b = response.session._botonic_action) === null || _b === void 0 ? void 0 : _b.startsWith(models_1.BotonicAction.Redirect)) {
return yield this.runRedirectAction(response, botContext, numOfRedirects + 1);
}
return response;
});
}
}
exports.CoreBot = CoreBot;
//# sourceMappingURL=core-bot.js.map