UNPKG

@upscopeio/twilio-flex-component

Version:

Upscope Co-browsing component for Twilio Flex

357 lines (326 loc) 17.2 kB
require("./UpscopeWidget.css"); var $iA2ta$reactjsxruntime = require("react/jsx-runtime"); var $iA2ta$react = require("react"); var $iA2ta$sentryreact = require("@sentry/react"); var $iA2ta$twilioflexui = require("@twilio/flex-ui"); var $iA2ta$debug = require("debug"); var $iA2ta$axios = require("axios"); var $iA2ta$caseconverter = require("case-converter"); function $parcel$interopDefault(a) { return a && a.__esModule ? a.default : a; } function $parcel$defineInteropFlag(a) { Object.defineProperty(a, '__esModule', {value: true, configurable: true}); } function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } $parcel$defineInteropFlag(module.exports); $parcel$export(module.exports, "default", () => $9233cea927cb9637$export$2e2bcd8739ae039); var $1572597be94ce13f$exports = {}; $1572597be94ce13f$exports = JSON.parse('{"name":"@upscopeio/twilio-flex-component","version":"2025.2.24","description":"Upscope Co-browsing component for Twilio Flex","main":"./dist/UpscopeWidget.js","license":"MIT","scripts":{"component:build":"yarn build && jq \'.main = \\"./UpscopeWidget.js\\"\' package.json > dist/package.json","build":"rm -rf .parcel-cache; parcel build src/index.tsx","dev:watch":"parcel watch src/index.tsx"},"keywords":["Upscope","Cobrowse","Twilio"],"author":"dev@upscope.io","dependencies":{"@sentry/browser":"^7.112.2","@sentry/react":"^7.44.2","@sentry/tracing":"^7.44.2","@twilio/flex-ui":"^2.8.2","axios":"^1.6.8","case-converter":"^1.0.1","debug":"^4.3.4","react":"^18.2.0","react-dom":"^18.2.0","react-timeago":"^7.1.0"},"devDependencies":{"@parcel/optimizer-data-url":"^2.12.0","@parcel/transformer-css":"^2.12.0","@parcel/transformer-inline-string":"^2.12.0","@parcel/transformer-svg-react":"^2.8.3","@types/axios":"^0.14.0","@types/debug":"^4.1.12","@types/react":"^18.2.14","@types/react-dom":"^18.2.14","@types/react-timeago":"^4.1.7","parcel":"^2.8.3","typescript":"5.0.4"},"@parcel/transformer-css":{"cssModules":{"global":true}}}'); class $4e0fc80ff36c942b$export$2e2bcd8739ae039 extends Error { constructor({ message: message, response: response, status: status }){ super(); this.message = message; this.response = response; this.status = status; } } const $20660adb77b18d0d$var$debug = (0, ($parcel$interopDefault($iA2ta$debug)))("upscope:cache"); const $20660adb77b18d0d$var$MINUTES_TO_EXPIRE_CACHE = 5; function $20660adb77b18d0d$export$75a0f4a65be4542c(cacheKey) { if (!cacheKey) return; const key = $20660adb77b18d0d$var$storageKey(cacheKey); const cache = sessionStorage.getItem(key); if (!cache) { $20660adb77b18d0d$var$debug("Cache not found, will fetch the visitor..."); return; } $20660adb77b18d0d$var$debug("Visitor found in cache: %o", JSON.parse(cache)); const parsedResponse = JSON.parse(cache); if (parsedResponse.expiresAt < new Date().getTime()) { $20660adb77b18d0d$var$debug("Cache expired, removing..."); sessionStorage.removeItem(key); return; } return parsedResponse; } function $20660adb77b18d0d$export$1cd522512d0e0bcf(cacheKey, response) { sessionStorage.setItem($20660adb77b18d0d$var$storageKey(cacheKey), JSON.stringify({ ...response, expiresAt: new Date().getTime() + $20660adb77b18d0d$var$MINUTES_TO_EXPIRE_CACHE * 60000 })); $20660adb77b18d0d$var$debug("Visitor cached, will expire in 5 minutes: %o", response); } function $20660adb77b18d0d$var$storageKey(cacheKey) { return `upscope:watchLinks:${cacheKey}`; } function $9ba0f9a5c47c04f2$export$b70aabe880331950(upscopeEnv) { if (upscopeEnv === "production") return "https://integrations.userview.com"; if (upscopeEnv === "staging") return "https://integrations.userview.xyz"; return "http://integrations.userview.local"; } const $8963e835ba2cb6ae$var$debug = (0, ($parcel$interopDefault($iA2ta$debug)))("upscope:upscope_client"); async function $8963e835ba2cb6ae$export$96162cf08faeeb3c({ request: request, searchMethod: searchMethod, integrationToken: integrationToken, upscopeEnv: upscopeEnv }) { const { conversationId: conversationId } = request; const visitorFromCache = (0, $20660adb77b18d0d$export$75a0f4a65be4542c)(conversationId); if (visitorFromCache) return visitorFromCache; try { const { data: data } = await (0, ($parcel$interopDefault($iA2ta$axios))).post(`${(0, $9ba0f9a5c47c04f2$export$b70aabe880331950)(upscopeEnv)}/twilioFlex/${searchMethod}`, (0, $iA2ta$caseconverter.toSnakeCase)(request), { headers: { "X-Api-Key": integrationToken, "Content-Type": "application/json" } }); const response = (0, $iA2ta$caseconverter.toCamelCase)(data); if (conversationId) (0, $20660adb77b18d0d$export$1cd522512d0e0bcf)(conversationId, response); return response; } catch (error) { $8963e835ba2cb6ae$var$debug("Error with request: %o", error); let errorResponse; if ((0, ($parcel$interopDefault($iA2ta$axios))).isAxiosError(error)) { if (error.response && typeof error.response.data !== "undefined") errorResponse = (0, $iA2ta$caseconverter.toCamelCase)(error.response.data); } else errorResponse = { error: "unknown", status: "error" }; const customError = new (0, $4e0fc80ff36c942b$export$2e2bcd8739ae039)({ message: error.message, status: error.status, response: errorResponse }); $8963e835ba2cb6ae$var$debug("Upscope search error: %o", customError); throw customError; } } async function $8963e835ba2cb6ae$export$d7f5377eac794d6(authUrl) { const twilioAuthToken = (0, $iA2ta$twilioflexui.Manager).getInstance().user.token; try { const { data: data } = await (0, ($parcel$interopDefault($iA2ta$axios))).post(authUrl, { Token: twilioAuthToken }); const response = (0, $iA2ta$caseconverter.toCamelCase)(data); return response; } catch (error) { $8963e835ba2cb6ae$var$debug("Error with request auth (%O)", error); const serverError = new Error(error.response?.data?.message ?? "Unknown request auth error"); serverError.statusCode = error.response?.status; serverError.response = error.response; throw serverError; } } var $d7ec9a077a206342$export$a851f5232a518044; var $d7ec9a077a206342$export$4f723fecf35d9bb1; var $d7ec9a077a206342$export$ad7e230961880cff; var $d7ec9a077a206342$export$84a93a92d5727e8b; var $d7ec9a077a206342$export$9dcbe3d4e8db3dc9; var $d7ec9a077a206342$export$d76ae9d5882572c9; var $d7ec9a077a206342$export$ea133318a29f7212; $d7ec9a077a206342$export$a851f5232a518044 = `pHDwTG_UpscopeWidget__Alert`; $d7ec9a077a206342$export$4f723fecf35d9bb1 = `pHDwTG_UpscopeWidget__Alert__Error`; $d7ec9a077a206342$export$ad7e230961880cff = `pHDwTG_UpscopeWidget__Button`; $d7ec9a077a206342$export$84a93a92d5727e8b = `pHDwTG_UpscopeWidget__Container`; $d7ec9a077a206342$export$9dcbe3d4e8db3dc9 = `pHDwTG_UpscopeWidget__Input`; $d7ec9a077a206342$export$d76ae9d5882572c9 = `pHDwTG_UpscopeWidget__Logo`; $d7ec9a077a206342$export$ea133318a29f7212 = `pHDwTG_UpscopeWidget__Screenshare__Container`; const $9233cea927cb9637$var$debug = (0, ($parcel$interopDefault($iA2ta$debug)))("upscope:widget"); function $9233cea927cb9637$var$UpscopeWidget({ authUrl: authUrl, upscopeEnv: upscopeEnv }) { const [errorMessage, setErrorMessage] = (0, $iA2ta$react.useState)(); const [lookupCodeInput, setLookupCodeInput] = (0, $iA2ta$react.useState)(); const [lookupCodeErrorMessage, setLookupCodeErrorMessage] = (0, $iA2ta$react.useState)(); const [showLookupCodeInput, setShowLookupCodeInput] = (0, $iA2ta$react.useState)(false); const [triedVisitorSearch, setTriedVisitorSearch] = (0, $iA2ta$react.useState)(false); const [visitor, setVisitor] = (0, $iA2ta$react.useState)(); const [watchLink, setWatchLink] = (0, $iA2ta$react.useState)(); const [conversationSid, setConversationSid] = (0, $iA2ta$react.useState)(); const [loading, setLoading] = (0, $iA2ta$react.useState)(false); const [integrationToken, setIntegrationToken] = (0, $iA2ta$react.useState)(); (0, $iA2ta$react.useEffect)(()=>{ (0, $8963e835ba2cb6ae$export$d7f5377eac794d6)(authUrl).then(({ integrationToken: integrationToken })=>setIntegrationToken(integrationToken)); }, [ authUrl ]); if ([ "staging", "production" ].includes(upscopeEnv)) $iA2ta$sentryreact.init({ dsn: "https://e96ba443f2d74485ae84af150dd77253@o73137.ingest.sentry.io/4504889193136128", integrations: [ $iA2ta$sentryreact.browserTracingIntegration() ], environment: upscopeEnv, release: (0, (/*@__PURE__*/$parcel$interopDefault($1572597be94ce13f$exports))).version }); function onScreenShare(event) { event.preventDefault(); window.open(watchLink ?? undefined); } const onSuccessRequest = ({ watchLink: watchLink, visitor: visitor })=>{ $9233cea927cb9637$var$debug("Got watch link: %s and visitor: %o", watchLink, visitor); setWatchLink(watchLink); setVisitor(visitor); setLoading(false); }; const onErrorRequest = (error)=>{ setLoading(false); $9233cea927cb9637$var$debug("Error request: %o", error); if (typeof error.response === "undefined") { $9233cea927cb9637$var$debug("Upscope internal error: %O", error); setErrorMessage("Upscope is currently not available"); $iA2ta$sentryreact.captureException(error); return; } if (error.response.error === "integration_not_found") { $9233cea927cb9637$var$debug("Upscope unauthorized error response: %o", error.response); setErrorMessage("Contact your team admin to setup the integration"); return; } if (error.response.error === "not_found") { $9233cea927cb9637$var$debug("Error with search: %o", error.response); const { message: message, tryLookupCode: tryLookupCode } = error.response; setShowLookupCodeInput(tryLookupCode); setErrorMessage(tryLookupCode ? undefined : message); setLookupCodeErrorMessage(tryLookupCode ? message : undefined); } else { setErrorMessage("An unexpected error occured"); $iA2ta$sentryreact.captureException(error); } }; async function onLookupCodeSearch(event) { event.preventDefault(); if (loading) return; if (lookupCodeInput && conversationSid && integrationToken) (0, $8963e835ba2cb6ae$export$96162cf08faeeb3c)({ searchMethod: "from_lookup_code", request: { lookupCode: lookupCodeInput, conversationId: conversationSid }, integrationToken: integrationToken, upscopeEnv: upscopeEnv }).then(({ watchLink: watchLink, visitor: visitor })=>{ onSuccessRequest({ watchLink: watchLink, visitor: visitor }); window.open(watchLink); }).catch(onErrorRequest); } function onLookupCodeInput(event) { setLookupCodeInput(event.target.value.replace(/\D/g, "")); } const newAppInstance = (0, $iA2ta$react.useCallback)(async (payload)=>{ setLoading(true); if ("task" in payload && typeof payload.task === "undefined") return; const conversationData = payload.task._task.attributes; const workerData = payload.task._task._worker.attributes; const customerEmail = conversationData.customerEmail; setConversationSid(()=>conversationData.conversationSid); const agentName = workerData.full_name; const agentEmail = workerData.email; if (conversationSid && integrationToken) (0, $8963e835ba2cb6ae$export$96162cf08faeeb3c)({ searchMethod: "from_visitor_details", request: { email: customerEmail, integrationId: `twilio_flex:${conversationSid}`, agentName: agentName, agentEmail: agentEmail, conversationId: conversationSid }, integrationToken: integrationToken, upscopeEnv: upscopeEnv }).then(onSuccessRequest).catch(onErrorRequest); }, [ conversationSid, integrationToken, upscopeEnv ]); (0, $iA2ta$react.useEffect)(()=>{ (0, $iA2ta$twilioflexui.Actions).replaceAction("WrapupTask", async (payload, original)=>{ setTriedVisitorSearch(false); setWatchLink(""); setShowLookupCodeInput(false); setLookupCodeInput(""); setErrorMessage(""); setLookupCodeErrorMessage(""); setVisitor(undefined); await original(payload); }); (0, $iA2ta$twilioflexui.Actions).addListener("afterSelectTask", newAppInstance); }, [ newAppInstance ]); return /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsxs)("div", { className: "UpscopeWidget__Container", children: [ /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { className: "UpscopeWidget__Logo" }), (()=>{ if (!triedVisitorSearch) return /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { className: "UpscopeWidget__Alert", children: /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("p", { children: "Please, select a conversation to start Upscope." }) }); if (watchLink && visitor) return /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsxs)("div", { className: "UpscopeWidget__Screenshare__Container", children: [ /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { children: "Screen share available" }), /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("button", { className: "UpscopeWidget__Button", onClick: onScreenShare, children: "Screen Share now" }) ] }); if (showLookupCodeInput) return /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsxs)("div", { children: [ lookupCodeErrorMessage && /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { className: "UpscopeWidget__Alert", children: /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("p", { children: lookupCodeErrorMessage }) }), /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsxs)("form", { onSubmit: onLookupCodeSearch, children: [ /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("input", { className: "UpscopeWidget__Input", autoFocus: true, type: "text", placeholder: "1234", value: lookupCodeInput ?? undefined, onChange: onLookupCodeInput }), /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("button", { className: "UpscopeWidget__Button", type: "submit", children: "Screen share" }) ] }), errorMessage && /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { className: "UpscopeWidget__Alert UpscopeWidget__Alert__Error", children: /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("p", { children: errorMessage }) }) ] }); if (errorMessage) return /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { children: /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("div", { className: "UpscopeWidget__Alert UpscopeWidget__Alert__Error", children: /*#__PURE__*/ (0, $iA2ta$reactjsxruntime.jsx)("p", { children: errorMessage }) }) }); })() ] }); } var $9233cea927cb9637$export$2e2bcd8739ae039 = $9233cea927cb9637$var$UpscopeWidget; //# sourceMappingURL=UpscopeWidget.js.map