UNPKG

@botonic/react

Version:

Build Chatbots using React

195 lines 8.05 kB
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