@botonic/react
Version:
Build Chatbots using React
199 lines • 8.48 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebviewApp = void 0;
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
// @ts-nocheck
const core_1 = require("@botonic/core");
const axios_1 = tslib_1.__importDefault(require("axios"));
const react_1 = tslib_1.__importDefault(require("react"));
const client_1 = require("react-dom/client");
const react_router_dom_1 = require("react-router-dom");
const contexts_1 = require("./contexts");
var WebviewUrlParams;
(function (WebviewUrlParams) {
WebviewUrlParams["Context"] = "context";
WebviewUrlParams["BotId"] = "bot_id";
WebviewUrlParams["UserId"] = "user_id";
WebviewUrlParams["HubtypeApiUrl"] = "hubtype_api_url";
})(WebviewUrlParams || (WebviewUrlParams = {}));
const DEFAULT_HUBTYPE_API_URL = 'https://api.hubtype.com';
class App extends react_1.default.Component {
constructor(props) {
super(props);
this.hubtypeApiUrl = DEFAULT_HUBTYPE_API_URL;
this.url = new URL(window.location.href);
this.state = {
session: null,
params: {},
};
}
componentDidMount() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
yield this.initializeApp();
});
}
initializeApp() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
const botId = this.url.searchParams.get(WebviewUrlParams.BotId);
const chatId = this.url.searchParams.get(WebviewUrlParams.UserId);
const hubtypeApiUrl = this.url.searchParams.get(WebviewUrlParams.HubtypeApiUrl);
if (botId && chatId && hubtypeApiUrl) {
const session = yield this.getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, chatId);
this.hubtypeApiUrl = hubtypeApiUrl;
this.setState({
session,
params: this.getParamsFromUrl(),
});
}
else {
const session = this.getBotSessionContextFromUrl();
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
this.setState({
session,
params: this.getParamsFromUrl(),
});
}
}
catch (error) {
console.error('Failed to initialize app:', error);
const session = this.getBotSessionContextFromUrl();
this.hubtypeApiUrl = session._hubtype_api || DEFAULT_HUBTYPE_API_URL;
this.setState({
session,
params: this.getParamsFromUrl(),
});
}
});
}
getBotSessionContextFromExternalApi(hubtypeApiUrl, botId, userId) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const url = `${hubtypeApiUrl}/external/v2/conversational_apps/${botId}/users/${userId}/context/`;
const response = yield axios_1.default.get(url);
return response.data;
});
}
getBotSessionContextFromUrl() {
const urlContext = this.url.searchParams.get(WebviewUrlParams.Context);
try {
return JSON.parse(urlContext || '{}');
}
catch (error) {
console.error('Failed to parse session context from URL:', error);
return {};
}
}
getParamsFromUrl() {
const keysToExclude = [
WebviewUrlParams.Context,
WebviewUrlParams.BotId,
WebviewUrlParams.UserId,
WebviewUrlParams.HubtypeApiUrl,
];
return Array.from(this.url.searchParams.entries())
.filter(([key]) => !keysToExclude.includes(key))
.reduce((params, [key, value]) => {
params[key] = value;
return params;
}, {});
}
closeWebviewForProvider(provider, session, payload) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const { user } = session;
switch (provider) {
case core_1.PROVIDER.WHATSAPP:
location.href = `https://wa.me/${user.unformatted_phone_number}`;
break;
case core_1.PROVIDER.TELEGRAM:
location.href = `https://t.me/${user.imp_id}`;
break;
case core_1.PROVIDER.APPLE:
location.href = `https://bcrw.apple.com/urn:biz:${user.imp_id}`;
break;
case core_1.PROVIDER.TWITTER:
location.href = `https://twitter.com/messages/compose?recipient_id=${user.imp_id}`;
break;
case core_1.PROVIDER.INSTAGRAM:
window.close();
break;
case core_1.PROVIDER.FACEBOOK:
try {
window.MessengerExtensions.requestCloseBrowser(() => { }, // success callback
() => window.close() // error callback
);
}
catch (error) {
window.close();
}
break;
case core_1.PROVIDER.WEBCHAT:
try {
yield parent.postMessage('botonicCloseWebview', '*');
}
catch (error) {
console.error('Failed to send close message to parent:', error);
}
break;
default:
console.warn(`Unknown provider: ${provider}`);
}
});
}
close(options) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!this.state.session) {
console.error('No session available for closing webview');
return;
}
let payload = (options === null || options === void 0 ? void 0 : options.payload) || null;
if (options === null || options === void 0 ? void 0 : options.path) {
payload = `__PATH_PAYLOAD__${options.path}`;
}
if (payload) {
if (options === null || options === void 0 ? void 0 : options.params) {
payload = `${payload}?${(0, core_1.params2queryString)(options.params)}`;
}
try {
const url = `${this.hubtypeApiUrl}/v1/bots/${this.state.session.bot.id}/send_postback/`;
const data = {
payload,
chat_id: this.state.session.user.id,
};
yield axios_1.default.post(url, data);
}
catch (error) {
console.error('Failed to send postback:', error);
}
}
yield this.closeWebviewForProvider(this.state.session.user.provider, this.state.session, payload);
});
}
render() {
if (!this.state.session) {
return null;
}
const webviewRequestContext = {
params: this.state.params,
session: this.state.session,
getUserCountry: () => this.state.session.user.country,
getUserLocale: () => this.state.session.user.locale,
getSystemLocale: () => this.state.session.user.system_locale,
closeWebview: this.close.bind(this),
};
return ((0, jsx_runtime_1.jsx)(contexts_1.WebviewRequestContext.Provider, Object.assign({ value: webviewRequestContext }, { children: this.props.webviews.map((Webview, i) => ((0, jsx_runtime_1.jsx)(react_router_dom_1.Route, { path: `/${Webview.name}`, component: Webview }, i))) })));
}
}
class WebviewApp {
constructor({ webviews, locales }) {
this.webviews = webviews;
this.locales = locales;
}
render(dest) {
const component = ((0, jsx_runtime_1.jsx)(react_router_dom_1.BrowserRouter, { children: (0, jsx_runtime_1.jsx)(App, { webviews: this.webviews, locales: this.locales }) }));
const reactRoot = (0, client_1.createRoot)(dest);
reactRoot.render(component);
}
}
exports.WebviewApp = WebviewApp;
//# sourceMappingURL=webview-app.js.map