@botonic/plugin-flow-builder
Version:
Use Flow Builder to show your contents
200 lines • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowBuilderJSONVersion = exports.trackFlowContent = void 0;
const tslib_1 = require("tslib");
const uuid_1 = require("uuid");
const api_1 = require("./api");
const constants_1 = require("./constants");
const content_fields_1 = require("./content-fields");
const hubtype_fields_1 = require("./content-fields/hubtype-fields");
const functions_1 = require("./functions");
const types_1 = require("./types");
const user_input_1 = require("./user-input");
const utils_1 = require("./utils");
// TODO: Create a proper service to wrap all calls and allow api versioning
class BotonicPluginFlowBuilder {
constructor(options) {
var _a, _b, _c;
this.apiUrl = options.apiUrl || constants_1.FLOW_BUILDER_API_URL_PROD;
this.jsonVersion = options.jsonVersion || types_1.FlowBuilderJSONVersion.LATEST;
this.flow = options.flow;
this.getAccessToken = (0, utils_1.resolveGetAccessToken)(options.getAccessToken);
this.trackEvent = options.trackEvent;
this.getKnowledgeBaseResponse = options.getKnowledgeBaseResponse;
this.getAiAgentResponse = options.getAiAgentResponse;
this.smartIntentsConfig = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.smartIntentsConfig), { useLatest: this.jsonVersion === types_1.FlowBuilderJSONVersion.LATEST });
const customFunctions = options.customFunctions || {};
this.functions = Object.assign(Object.assign({}, functions_1.DEFAULT_FUNCTIONS), customFunctions);
this.inShadowing = {
allowKeywords: ((_a = options.inShadowing) === null || _a === void 0 ? void 0 : _a.allowKeywords) || false,
allowSmartIntents: ((_b = options.inShadowing) === null || _b === void 0 ? void 0 : _b.allowSmartIntents) || false,
allowKnowledgeBases: ((_c = options.inShadowing) === null || _c === void 0 ? void 0 : _c.allowKnowledgeBases) || false,
};
this.contentFilters = options.contentFilters || [];
this.customRatingMessageEnabled =
options.customRatingMessageEnabled || false;
}
resolveFlowUrl(request) {
if (request.session.is_test_integration) {
return `${this.apiUrl}/v1/bot_flows/{bot_id}/versions/${types_1.FlowBuilderJSONVersion.DRAFT}/`;
}
return `${this.apiUrl}/v1/bot_flows/{bot_id}/versions/${this.jsonVersion}/`;
}
pre(request) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.currentRequest = request;
this.cmsApi = yield api_1.FlowBuilderApi.create({
flowUrl: this.resolveFlowUrl(request),
url: this.apiUrl,
flow: this.flow,
accessToken: this.getAccessToken(request.session),
request: this.currentRequest,
});
const checkUserTextInput = (0, utils_1.inputHasTextData)(request.input) && !request.input.payload;
if (checkUserTextInput) {
const resolvedLocale = this.cmsApi.getResolvedLocale();
const nodeByUserInput = yield (0, user_input_1.getNodeByUserInput)(this.cmsApi, resolvedLocale, request, this.smartIntentsConfig);
request.input.payload = this.cmsApi.getPayload(nodeByUserInput === null || nodeByUserInput === void 0 ? void 0 : nodeByUserInput.target);
}
this.updateRequestBeforeRoutes(request);
});
}
updateRequestBeforeRoutes(request) {
if (request.input.payload) {
request.input.payload = this.removeSourceSuffix(request.input.payload);
if (this.cmsApi.isBotAction(request.input.payload)) {
const cmsBotAction = this.cmsApi.getNodeById(request.input.payload);
request.input.payload =
this.cmsApi.createPayloadWithParams(cmsBotAction);
}
}
}
removeSourceSuffix(payload) {
return payload.split(constants_1.SOURCE_INFO_SEPARATOR)[0];
}
post(request) {
request.input.nluResolution = undefined;
}
getContentsByContentID(contentID, prevContents) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const node = this.cmsApi.getNodeByContentID(contentID);
return yield this.getContentsByNode(node, prevContents);
});
}
getUUIDByContentID(contentID) {
const node = this.cmsApi.getNodeByContentID(contentID);
return node.id;
}
getContentsById(id, prevContents) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const node = this.cmsApi.getNodeById(id);
return yield this.getContentsByNode(node, prevContents);
});
}
getStartContents() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const startNode = this.cmsApi.getStartNode();
this.currentRequest.session.flow_thread_id = (0, uuid_1.v7)();
return yield this.getContentsByNode(startNode);
});
}
getContentsByNode(node, prevContents) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const contents = prevContents || [];
const resolvedLocale = this.cmsApi.getResolvedLocale();
if (node.type === hubtype_fields_1.HtNodeWithContentType.FUNCTION) {
const targetId = yield this.callFunction(node, resolvedLocale);
return this.getContentsById(targetId, contents);
}
const content = this.getFlowContent(node, resolvedLocale);
if (content) {
contents.push(content);
}
// If node is BOT_ACTION not add more contents to render, next nodes render after execute action
if (node.type === hubtype_fields_1.HtNodeWithContentType.BOT_ACTION) {
return contents;
}
// TODO: prevent infinite recursive calls
if (node.follow_up) {
return this.getContentsById(node.follow_up.id, contents);
}
return contents;
});
}
getFlowContent(hubtypeContent, locale) {
switch (hubtypeContent.type) {
case hubtype_fields_1.HtNodeWithContentType.TEXT:
return content_fields_1.FlowText.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
case hubtype_fields_1.HtNodeWithContentType.IMAGE:
return content_fields_1.FlowImage.fromHubtypeCMS(hubtypeContent, locale);
case hubtype_fields_1.HtNodeWithContentType.CAROUSEL:
return content_fields_1.FlowCarousel.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
case hubtype_fields_1.HtNodeWithContentType.VIDEO:
return content_fields_1.FlowVideo.fromHubtypeCMS(hubtypeContent, locale);
case hubtype_fields_1.HtNodeWithContentType.WHATSAPP_BUTTON_LIST:
return content_fields_1.FlowWhatsappButtonList.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
case hubtype_fields_1.HtNodeWithContentType.WHATSAPP_CTA_URL_BUTTON:
return content_fields_1.FlowWhatsappCtaUrlButtonNode.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
case hubtype_fields_1.HtNodeWithContentType.HANDOFF:
return content_fields_1.FlowHandoff.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
case hubtype_fields_1.HtNodeWithContentType.KNOWLEDGE_BASE:
return content_fields_1.FlowKnowledgeBase.fromHubtypeCMS(hubtypeContent);
case hubtype_fields_1.HtNodeWithContentType.AI_AGENT:
return content_fields_1.FlowAiAgent.fromHubtypeCMS(hubtypeContent);
case hubtype_fields_1.HtNodeWithContentType.RATING:
return content_fields_1.FlowRating.fromHubtypeCMS(hubtypeContent, locale);
case hubtype_fields_1.HtNodeWithContentType.BOT_ACTION:
return content_fields_1.FlowBotAction.fromHubtypeCMS(hubtypeContent, locale, this.cmsApi);
default:
return undefined;
}
}
callFunction(functionNode, locale) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const functionNodeId = functionNode.id;
const functionArguments = this.getArgumentsByLocale(functionNode.content.arguments, locale);
const nameValues = functionArguments.map(arg => {
return { [arg.name]: arg.value };
});
const args = Object.assign({
request: this.currentRequest,
results: functionNode.content.result_mapping.map(r => r.result),
}, ...nameValues);
const functionResult = yield this.functions[functionNode.content.action](args);
// TODO define result_mapping per locale??
const result = functionNode.content.result_mapping.find(r => r.result === functionResult);
if (!(result === null || result === void 0 ? void 0 : result.target)) {
throw new Error(`No result found for result_mapping for node with id: ${functionNodeId}`);
}
return result.target.id;
});
}
getArgumentsByLocale(args, locale) {
let resultArguments = [];
for (const arg of args) {
if ('locale' in arg && arg.locale === locale) {
resultArguments = [...resultArguments, ...arg.values];
}
if ('type' in arg) {
resultArguments = [...resultArguments, arg];
}
}
return resultArguments;
}
getPayloadParams(payload) {
const payloadParams = JSON.parse(payload.split(constants_1.SEPARATOR)[1] || '{}');
return payloadParams;
}
getFlowName(flowId) {
return this.cmsApi.getFlowName(flowId);
}
}
exports.default = BotonicPluginFlowBuilder;
tslib_1.__exportStar(require("./action"), exports);
tslib_1.__exportStar(require("./content-fields"), exports);
var tracking_1 = require("./tracking");
Object.defineProperty(exports, "trackFlowContent", { enumerable: true, get: function () { return tracking_1.trackFlowContent; } });
var types_2 = require("./types");
Object.defineProperty(exports, "FlowBuilderJSONVersion", { enumerable: true, get: function () { return types_2.FlowBuilderJSONVersion; } });
tslib_1.__exportStar(require("./webview"), exports);
//# sourceMappingURL=index.js.map