import type { SoluCXKey, WidgetData, WidgetOptions } from "../domain"; import { WIDGET_API_BASE_URL } from "../constants/Constants"; import { getClientVersion } from "../hooks/useClientVersionCollector"; import { getDeviceInfo } from "../hooks/useDeviceInfoCollector"; import { SDK_NAME, SDK_VERSION } from "../constants/Constants"; import { URLSearchParams } from "react-native-url-polyfill"; type UrlRequestPayload = { available: boolean; url?: string; reason?: string; }; const DEFAULT_WIDGET_OPTIONS: WidgetOptions = { height: 600, }; const buildRequestParams = (requestParams: WidgetData): URLSearchParams => { const params = new URLSearchParams(); Object.entries(requestParams).forEach(([key, value]) => { if (value === undefined || value === null) return; params.append(key, typeof value === "number" ? value.toString() : String(value)); }); return params; }; const buildRequestHeaders = (instanceKey: SoluCXKey, userId: string): Record => { const deviceInfo = getDeviceInfo(); const appVersion = getClientVersion(); const isMobile = deviceInfo.deviceType === "phone" ? "?1" : "?0"; const userAgent = `${SDK_NAME}/${SDK_VERSION} (${deviceInfo.platform}; OS ${deviceInfo.osVersion}; ${deviceInfo.model}) App/${appVersion}`; return { accept: "application/json, text/plain, */*", "x-solucx-api-key": instanceKey, "x-solucx-device-id": userId, "x-client-id": userId, "x-sdk-name": SDK_NAME, "x-sdk-version": SDK_VERSION, "x-solucx-app-version": appVersion, "x-solucx-client-platform": deviceInfo.platform, "Sec-CH-UA": `"${SDK_NAME}";v="${SDK_VERSION}", "app";v="${appVersion}"`, "Sec-CH-UA-Platform": `"${deviceInfo.platform}"`, "Sec-CH-UA-Mobile": isMobile, "Sec-CH-UA-Platform-Version": `"${deviceInfo.osVersion}"`, "Sec-CH-UA-Model": `"${deviceInfo.model}"`, "User-Agent": userAgent, }; }; export async function requestWidgetUrl(instanceKey: SoluCXKey, requestParams: WidgetData, userId: string): Promise { if (typeof fetch !== "function") { throw new Error("Fetch is not available"); } const params = buildRequestParams(requestParams); const url = `${WIDGET_API_BASE_URL}/widget/available?${params.toString()}`; const headers = buildRequestHeaders(instanceKey, userId); const response = await fetch(url, { method: "GET", headers }); if (!response.ok) { if (!response.json) throw new Error(`Failed to get error response: ${response?.status} ${response.statusText}`); const errorPayload: { error: string; message: string; statusCode: number } = await response?.json(); throw new Error(`status=${response?.status} message=${errorPayload?.message}`); } const payload: UrlRequestPayload = await response?.json(); return payload; } export async function requestWidgetOptions(instanceKey: SoluCXKey, journey?: string): Promise { if (typeof fetch !== "function") { console.warn("[WidgetBootstrap] Fetch is not available, using default options"); return DEFAULT_WIDGET_OPTIONS; } const params = new URLSearchParams(); if (journey) { params.append("journey", journey); } const url = `${WIDGET_API_BASE_URL}/widget/parameters${params.toString() ? `?${params.toString()}` : ""}`; const headers = { "x-solucx-api-key": instanceKey, accept: "application/json", }; const response = await fetch(url, { method: "GET", headers }); if (!response.ok) { console.warn(`[WidgetBootstrap] Failed to fetch widget options: ${response.status} ${response.statusText}`); return DEFAULT_WIDGET_OPTIONS; } const options: WidgetOptions = await response.json(); return options || DEFAULT_WIDGET_OPTIONS; } export { buildRequestParams };