@botonic/react
Version:
Build Chatbots using React
195 lines • 8.05 kB
JavaScript
import { __awaiter } from "tslib";
import { jsx as _jsx } from "react/jsx-runtime";
// @ts-nocheck
import { params2queryString, PROVIDER } from '@botonic/core';
import axios from 'axios';
import React from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter, Route } from 'react-router-dom';
import { WebviewRequestContext, } from './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.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 __awaiter(this, void 0, void 0, function* () {
yield this.initializeApp();
});
}
initializeApp() {
return __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 __awaiter(this, void 0, void 0, function* () {
const url = `${hubtypeApiUrl}/external/v2/conversational_apps/${botId}/users/${userId}/context/`;
const response = yield axios.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 __awaiter(this, void 0, void 0, function* () {
const { user } = session;
switch (provider) {
case PROVIDER.WHATSAPP:
location.href = `https://wa.me/${user.unformatted_phone_number}`;
break;
case PROVIDER.TELEGRAM:
location.href = `https://t.me/${user.imp_id}`;
break;
case PROVIDER.APPLE:
location.href = `https://bcrw.apple.com/urn:biz:${user.imp_id}`;
break;
case PROVIDER.TWITTER:
location.href = `https://twitter.com/messages/compose?recipient_id=${user.imp_id}`;
break;
case PROVIDER.INSTAGRAM:
window.close();
break;
case PROVIDER.FACEBOOK:
try {
window.MessengerExtensions.requestCloseBrowser(() => { }, // success callback
() => window.close() // error callback
);
}
catch (error) {
window.close();
}
break;
case 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 __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}?${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.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 (_jsx(WebviewRequestContext.Provider, Object.assign({ value: webviewRequestContext }, { children: this.props.webviews.map((Webview, i) => (_jsx(Route, { path: `/${Webview.name}`, component: Webview }, i))) })));
}
}
export class WebviewApp {
constructor({ webviews, locales }) {
this.webviews = webviews;
this.locales = locales;
}
render(dest) {
const component = (_jsx(BrowserRouter, { children: _jsx(App, { webviews: this.webviews, locales: this.locales }) }));
const reactRoot = createRoot(dest);
reactRoot.render(component);
}
}
//# sourceMappingURL=webview-app.js.map