@mailoo/chat 0.0.0-stage → 1.32.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +16 -0
- package/README.md +150 -2
- package/dist/chat-message-Dw6tKBEb.d.cts +10 -0
- package/dist/chat-message-Dw6tKBEb.d.ts +10 -0
- package/dist/chunk-2Y37RYEL.js +141 -0
- package/dist/chunk-2Y37RYEL.js.map +1 -0
- package/dist/chunk-4TNHJERE.js +19 -0
- package/dist/chunk-4TNHJERE.js.map +1 -0
- package/dist/chunk-77E6HUHY.js +41 -0
- package/dist/chunk-77E6HUHY.js.map +1 -0
- package/dist/chunk-AU6EFFLV.js +431 -0
- package/dist/chunk-AU6EFFLV.js.map +1 -0
- package/dist/chunk-QZ7HWQDO.js +839 -0
- package/dist/chunk-QZ7HWQDO.js.map +1 -0
- package/dist/client/index.cjs +1658 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +33 -0
- package/dist/client/index.d.ts +33 -0
- package/dist/client/index.js +597 -0
- package/dist/client/index.js.map +1 -0
- package/dist/hooks/index.cjs +751 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +79 -0
- package/dist/hooks/index.d.ts +79 -0
- package/dist/hooks/index.js +32 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.cjs +213 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +53 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/mailoo-site-chat-widget-C7B797Lu.d.ts +130 -0
- package/dist/mailoo-site-chat-widget-h_cBqsJw.d.cts +130 -0
- package/dist/routes/index.cjs +204 -0
- package/dist/routes/index.cjs.map +1 -0
- package/dist/routes/index.d.cts +30 -0
- package/dist/routes/index.d.ts +30 -0
- package/dist/routes/index.js +174 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/shared-glVmghqk.d.cts +40 -0
- package/dist/shared-glVmghqk.d.ts +40 -0
- package/dist/styles/widget.css +122 -0
- package/dist/welcome-presets/index.cjs +479 -0
- package/dist/welcome-presets/index.cjs.map +1 -0
- package/dist/welcome-presets/index.d.cts +53 -0
- package/dist/welcome-presets/index.d.ts +53 -0
- package/dist/welcome-presets/index.js +38 -0
- package/dist/welcome-presets/index.js.map +1 -0
- package/dist/welcome-presets/parse.cjs +44 -0
- package/dist/welcome-presets/parse.cjs.map +1 -0
- package/dist/welcome-presets/parse.d.cts +11 -0
- package/dist/welcome-presets/parse.d.ts +11 -0
- package/dist/welcome-presets/parse.js +9 -0
- package/dist/welcome-presets/parse.js.map +1 -0
- package/dist/widget-config-B5Tf7gqn.d.cts +32 -0
- package/dist/widget-config-B5Tf7gqn.d.ts +32 -0
- package/package.json +85 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/index.ts","../../src/lib/chat-message.ts","../../src/hooks/shared.ts","../../src/hooks/use-mailoo-chat-session.ts","../../src/lib/guest-copy.ts","../../src/lib/visitor-ws-url.ts"],"sourcesContent":["'use client'\n\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n parseChatMessages,\n type MailooChatMessage,\n} from '../lib/chat-message.js'\nimport {\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_STATUS_ENDPOINT,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n messageFromPayload,\n type MailooChatStatus,\n type MailooChatSubmitResult,\n} from './shared.js'\n\nexport type { MailooChatMessage }\nexport {\n classifyChatFault,\n DEFAULT_CHAT_GUEST_PROFILE_KEY,\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_POLL_INTERVAL_MS,\n DEFAULT_CHAT_SESSION_STORAGE_KEY,\n DEFAULT_CHAT_STATUS_ENDPOINT,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n isChatSessionNotFound,\n messageFromPayload,\n type MailooChatConnectionState,\n type MailooChatFault,\n type MailooChatFaultKind,\n type MailooChatStatus,\n type MailooChatSubmitResult,\n} from './shared.js'\nexport {\n useMailooChatSession,\n type UseMailooChatSessionOptions,\n} from './use-mailoo-chat-session.js'\n\nexport function useMailooChatSubmit(options?: { endpoint?: string }) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_SUBMIT_ENDPOINT\n const [pending, setPending] = useState(false)\n\n const submit = useCallback(\n async (body: Record<string, unknown>): Promise<MailooChatSubmitResult> => {\n setPending(true)\n try {\n const res = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n return {\n ok: false,\n status: res.status,\n message: messageFromPayload(data, 'Send failed'),\n }\n }\n return { ok: true, status: res.status, data }\n } catch {\n return { ok: false, status: 0, message: 'Network error' }\n } finally {\n setPending(false)\n }\n },\n [endpoint]\n )\n\n return { submit, pending }\n}\n\nexport function useMailooChatMessages(options?: { endpoint?: string }) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_MESSAGES_ENDPOINT\n const [pending, setPending] = useState(false)\n\n const refresh = useCallback(\n async (\n sessionPublicId: string,\n since?: string\n ): Promise<MailooChatSubmitResult & { messages?: MailooChatMessage[] }> => {\n setPending(true)\n try {\n const params = new URLSearchParams({ sessionPublicId })\n if (since) params.set('since', since)\n const res = await fetch(`${endpoint}?${params.toString()}`)\n const data = await res.json().catch(() => ({}))\n if (!res.ok) {\n return {\n ok: false,\n status: res.status,\n message: messageFromPayload(data, 'Fetch failed'),\n }\n }\n const rows = Array.isArray((data as { data?: unknown[] }).data)\n ? (data as { data: unknown[] }).data\n : []\n return {\n ok: true,\n status: res.status,\n data,\n messages: parseChatMessages(rows),\n }\n } catch {\n return { ok: false, status: 0, message: 'Network error' }\n } finally {\n setPending(false)\n }\n },\n [endpoint]\n )\n\n return { refresh, pending }\n}\n\nexport function useMailooChatStatus(options?: {\n endpoint?: string\n enabled?: boolean\n}) {\n const endpoint = options?.endpoint ?? DEFAULT_CHAT_STATUS_ENDPOINT\n const enabled = options?.enabled ?? true\n const [status, setStatus] = useState<MailooChatStatus | null>(null)\n const [pending, setPending] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const refresh = useCallback(async () => {\n setPending(true)\n setError(null)\n try {\n const res = await fetch(endpoint)\n const data = (await res\n .json()\n .catch(() => ({}))) as Partial<MailooChatStatus> & {\n message?: string\n error?: string\n }\n if (!res.ok) {\n setError(messageFromPayload(data, 'Status fetch failed'))\n return null\n }\n if (\n typeof data.status !== 'string' ||\n typeof data.name !== 'string' ||\n typeof data.type !== 'string' ||\n typeof data.lastActivity !== 'string'\n ) {\n setError('Invalid status payload')\n return null\n }\n const parsed: MailooChatStatus = {\n status: data.status,\n name: data.name,\n type: data.type,\n lastActivity: data.lastActivity,\n }\n setStatus(parsed)\n return parsed\n } catch {\n setError('Network error')\n return null\n } finally {\n setPending(false)\n }\n }, [endpoint])\n\n useEffect(() => {\n if (!enabled) return\n void refresh()\n }, [enabled, refresh])\n\n return { status, pending, error, refresh }\n}\n","export type MailooChatMessage = {\n id: string\n messageType: string\n content: string\n senderEmail?: string | null\n senderName?: string | null\n createdAt: string\n}\n\nexport function parseChatMessages(rows: unknown[]): MailooChatMessage[] {\n const parsed: MailooChatMessage[] = []\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue\n const r = row as Record<string, unknown>\n if (typeof r.id !== 'string' || typeof r.content !== 'string') continue\n parsed.push({\n id: r.id,\n messageType:\n typeof r.messageType === 'string' ? r.messageType : 'INBOUND',\n content: r.content,\n senderEmail: typeof r.senderEmail === 'string' ? r.senderEmail : null,\n senderName: typeof r.senderName === 'string' ? r.senderName : null,\n createdAt:\n typeof r.createdAt === 'string'\n ? r.createdAt\n : new Date().toISOString(),\n })\n }\n return parsed\n}\n\nfunction messagesEqual(\n a: MailooChatMessage[],\n b: MailooChatMessage[]\n): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x = a[i]\n const y = b[i]\n if (\n x.id !== y.id ||\n x.content !== y.content ||\n x.messageType !== y.messageType ||\n x.createdAt !== y.createdAt ||\n x.senderEmail !== y.senderEmail ||\n x.senderName !== y.senderName\n ) {\n return false\n }\n }\n return true\n}\n\nexport function mergeChatMessages(\n prev: MailooChatMessage[],\n incoming: MailooChatMessage[]\n): MailooChatMessage[] {\n if (incoming.length === 0) return prev\n\n const byId = new Map<string, MailooChatMessage>()\n for (const m of prev) byId.set(m.id, m)\n for (const m of incoming) byId.set(m.id, m)\n const next = Array.from(byId.values()).sort(\n (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()\n )\n return messagesEqual(prev, next) ? prev : next\n}\n\nexport function latestMessageCreatedAt(\n messages: MailooChatMessage[]\n): string | undefined {\n if (messages.length === 0) return undefined\n let latest = messages[0].createdAt\n for (const m of messages) {\n if (new Date(m.createdAt).getTime() > new Date(latest).getTime()) {\n latest = m.createdAt\n }\n }\n return latest\n}\n","export const DEFAULT_CHAT_SUBMIT_ENDPOINT = '/api/v1/webhooks/chat/submit'\nexport const DEFAULT_CHAT_MESSAGES_ENDPOINT = '/api/v1/webhooks/chat/messages'\nexport const DEFAULT_CHAT_STATUS_ENDPOINT = '/api/v1/webhooks/chat/status'\nexport const DEFAULT_CHAT_SESSION_STORAGE_KEY =\n 'mailoo_site_chat_session_public_id'\nexport const DEFAULT_CHAT_GUEST_PROFILE_KEY = 'mailoo_site_chat_guest_profile'\nexport const DEFAULT_CHAT_POLL_INTERVAL_MS = 5000\n\nexport type MailooChatConnectionState =\n 'idle' | 'connecting' | 'open' | 'closed'\n\nexport type MailooChatFaultKind = 'rate_limited' | 'unavailable'\n\n/** Classified chat transport/service fault (not validation or session lifecycle). */\nexport type MailooChatFault = {\n kind: MailooChatFaultKind\n status: number\n message: string\n}\n\nexport type MailooChatSubmitResult =\n | { ok: true; status: number; data: unknown }\n | { ok: false; status: number; message: string }\n\nexport type MailooChatStatus = {\n status: string\n name: string\n type: string\n lastActivity: string\n}\n\nexport function messageFromPayload(data: unknown, fallback: string): string {\n if (!data || typeof data !== 'object') return fallback\n const d = data as { message?: unknown; error?: unknown }\n if (typeof d.message === 'string') return d.message\n if (typeof d.error === 'string') return d.error\n return fallback\n}\n\n/**\n * Classify HTTP/network failures that should show the unavailable panel.\n * Status-based only (no English string parsing). Returns null for validation,\n * 4xx client errors other than 429, and session-not-found (handled separately).\n */\nexport function classifyChatFault(\n status: number,\n payload: unknown,\n fallbackMessage = 'Request failed'\n): MailooChatFault | null {\n if (status === 429) {\n return {\n kind: 'rate_limited',\n status,\n message: messageFromPayload(payload, fallbackMessage),\n }\n }\n // Network failure (fetch throw mapped to 0) or gateway / service errors\n if (status === 0 || status === 502 || status === 503 || status >= 500) {\n return {\n kind: 'unavailable',\n status,\n message: messageFromPayload(payload, fallbackMessage),\n }\n }\n return null\n}\n\n/** Upstream 404 after DB reset / expired sessionStorage id. */\nexport function isChatSessionNotFound(\n status: number,\n data: unknown\n): boolean {\n if (status !== 404) return false\n const text = messageFromPayload(data, '').toLowerCase()\n return text.includes('chat session not found')\n}\n\nexport function persistSessionPublicId(\n id: string,\n storageKey: string,\n ctx: {\n sessionPublicIdRef: { current: string | null }\n setSessionPublicId: (id: string) => void\n onCreated?: (sessionPublicId: string) => void\n }\n) {\n const created = !ctx.sessionPublicIdRef.current\n ctx.setSessionPublicId(id)\n ctx.sessionPublicIdRef.current = id\n try {\n sessionStorage.setItem(storageKey, id)\n } catch {\n /* ignore */\n }\n if (created) ctx.onCreated?.(id)\n}\n","'use client'\n\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport {\n latestMessageCreatedAt,\n mergeChatMessages,\n parseChatMessages,\n type MailooChatMessage,\n} from '../lib/chat-message.js'\nimport { isValidEmail } from '../lib/guest-copy.js'\nimport { buildVisitorWsUrl } from '../lib/visitor-ws-url.js'\nimport {\n classifyChatFault,\n DEFAULT_CHAT_GUEST_PROFILE_KEY,\n DEFAULT_CHAT_MESSAGES_ENDPOINT,\n DEFAULT_CHAT_POLL_INTERVAL_MS,\n DEFAULT_CHAT_SESSION_STORAGE_KEY,\n DEFAULT_CHAT_SUBMIT_ENDPOINT,\n isChatSessionNotFound,\n messageFromPayload,\n persistSessionPublicId,\n type MailooChatConnectionState,\n type MailooChatFault,\n} from './shared.js'\n\nexport type UseMailooChatSessionOptions = {\n apiOrigin: string\n projectUid: string\n integrationId: string\n isAuthenticated: boolean\n submitEndpoint?: string\n messagesEndpoint?: string\n storageKey?: string\n guestProfileKey?: string\n pollIntervalMs?: number\n enableRealtime?: boolean\n enablePolling?: boolean\n enableWebSocket?: boolean\n enabled?: boolean\n onSessionCreated?: (sessionPublicId: string) => void\n onMessageSent?: (content: string) => void\n onError?: (error: string) => void\n onFault?: (fault: MailooChatFault) => void\n}\n\nexport function useMailooChatSession(options: UseMailooChatSessionOptions) {\n const {\n apiOrigin,\n projectUid,\n integrationId,\n isAuthenticated,\n submitEndpoint = DEFAULT_CHAT_SUBMIT_ENDPOINT,\n messagesEndpoint = DEFAULT_CHAT_MESSAGES_ENDPOINT,\n storageKey = DEFAULT_CHAT_SESSION_STORAGE_KEY,\n guestProfileKey = DEFAULT_CHAT_GUEST_PROFILE_KEY,\n pollIntervalMs = DEFAULT_CHAT_POLL_INTERVAL_MS,\n enableRealtime = true,\n enablePolling = true,\n enableWebSocket = true,\n enabled = true,\n onSessionCreated,\n onMessageSent,\n onError,\n onFault,\n } = options\n\n const [sessionPublicId, setSessionPublicId] = useState<string | null>(null)\n const [messages, setMessages] = useState<MailooChatMessage[]>([])\n const [sending, setSending] = useState(false)\n const [error, setError] = useState<string | null>(null)\n const [fault, setFault] = useState<MailooChatFault | null>(null)\n const [connectionState, setConnectionState] =\n useState<MailooChatConnectionState>('idle')\n\n const [guestEmail, setGuestEmail] = useState('')\n const [guestName, setGuestName] = useState('')\n const [guestContactOk, setGuestContactOk] = useState(isAuthenticated)\n const [guestProfileHydrated, setGuestProfileHydrated] = useState(false)\n\n const wsRef = useRef<WebSocket | null>(null)\n const pollRef = useRef<ReturnType<typeof setInterval> | null>(null)\n const sessionPublicIdRef = useRef<string | null>(null)\n const sinceRef = useRef<string | undefined>(undefined)\n const faultRef = useRef<MailooChatFault | null>(null)\n const onSessionCreatedRef = useRef(onSessionCreated)\n const onMessageSentRef = useRef(onMessageSent)\n const onErrorRef = useRef(onError)\n const onFaultRef = useRef(onFault)\n\n sessionPublicIdRef.current = sessionPublicId\n faultRef.current = fault\n onSessionCreatedRef.current = onSessionCreated\n onMessageSentRef.current = onMessageSent\n onErrorRef.current = onError\n onFaultRef.current = onFault\n\n const clearFault = useCallback(() => {\n faultRef.current = null\n setFault(null)\n }, [])\n\n const reportFault = useCallback((next: MailooChatFault) => {\n faultRef.current = next\n setFault(next)\n setError(null)\n onFaultRef.current?.(next)\n onErrorRef.current?.(next.message)\n }, [])\n\n const reportError = useCallback((message: string | null) => {\n setError(message)\n if (message) {\n clearFault()\n onErrorRef.current?.(message)\n }\n }, [clearFault])\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n const existing = sessionStorage.getItem(storageKey)\n if (existing) setSessionPublicId(existing)\n }, [storageKey])\n\n useEffect(() => {\n if (typeof window === 'undefined' || isAuthenticated) {\n setGuestProfileHydrated(true)\n return\n }\n try {\n const raw = sessionStorage.getItem(guestProfileKey)\n if (raw) {\n const j = JSON.parse(raw) as { email?: unknown; name?: unknown }\n const em =\n typeof j.email === 'string' ? j.email.trim().toLowerCase() : ''\n if (em && isValidEmail(em)) {\n setGuestEmail(em)\n setGuestName(typeof j.name === 'string' ? j.name.trim() : '')\n setGuestContactOk(true)\n }\n }\n } catch {\n /* ignore */\n }\n setGuestProfileHydrated(true)\n }, [isAuthenticated, guestProfileKey])\n\n useEffect(() => {\n if (isAuthenticated) {\n setGuestContactOk(true)\n }\n }, [isAuthenticated])\n\n const persistGuestProfile = useCallback(\n (email: string, name: string) => {\n try {\n sessionStorage.setItem(\n guestProfileKey,\n JSON.stringify({\n email: email.trim().toLowerCase(),\n name: name.trim(),\n })\n )\n } catch {\n /* ignore */\n }\n },\n [guestProfileKey]\n )\n\n const confirmGuestContact = useCallback(\n (invalidEmailMessage?: string): boolean => {\n reportError(null)\n if (isAuthenticated) {\n setGuestContactOk(true)\n return true\n }\n if (!isValidEmail(guestEmail)) {\n reportError(\n invalidEmailMessage ?? 'Please enter a valid email address.'\n )\n return false\n }\n persistGuestProfile(guestEmail, guestName)\n setGuestContactOk(true)\n return true\n },\n [\n isAuthenticated,\n guestEmail,\n guestName,\n persistGuestProfile,\n reportError,\n ]\n )\n\n const resetGuestContact = useCallback(() => {\n setGuestContactOk(false)\n reportError(null)\n }, [reportError])\n\n const mergeIncoming = useCallback((rows: unknown[]) => {\n const parsed = parseChatMessages(rows)\n setMessages((prev) => {\n const next = mergeChatMessages(prev, parsed)\n sinceRef.current = latestMessageCreatedAt(next)\n return next\n })\n }, [])\n\n const mergeMessage = useCallback((message: MailooChatMessage) => {\n setMessages((prev) => {\n const next = mergeChatMessages(prev, [message])\n sinceRef.current = latestMessageCreatedAt(next)\n return next\n })\n }, [])\n\n const clearSession = useCallback(() => {\n try {\n sessionStorage.removeItem(storageKey)\n } catch {\n /* ignore */\n }\n setSessionPublicId(null)\n sessionPublicIdRef.current = null\n setMessages([])\n sinceRef.current = undefined\n }, [storageKey])\n\n const stopRealtime = useCallback(() => {\n if (pollRef.current) {\n clearInterval(pollRef.current)\n pollRef.current = null\n }\n wsRef.current?.close()\n wsRef.current = null\n setConnectionState('closed')\n }, [])\n\n const refreshMessages = useCallback(\n async (sid?: string, opts?: { full?: boolean }) => {\n const id = sid ?? sessionPublicIdRef.current\n if (!id) return\n if (faultRef.current) return\n const params = new URLSearchParams({ sessionPublicId: id })\n if (!opts?.full && sinceRef.current) {\n params.set('since', sinceRef.current)\n }\n let res: Response\n try {\n res = await fetch(`${messagesEndpoint}?${params.toString()}`)\n } catch {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return\n }\n const data = (await res.json().catch(() => ({}))) as {\n data?: unknown[]\n message?: unknown\n error?: unknown\n }\n if (!res.ok) {\n if (isChatSessionNotFound(res.status, data)) {\n clearSession()\n reportError(null)\n return\n }\n const classified = classifyChatFault(\n res.status,\n data,\n 'Failed to load messages'\n )\n if (classified) {\n reportFault(classified)\n stopRealtime()\n return\n }\n reportError(messageFromPayload(data, 'Failed to load messages'))\n return\n }\n if (Array.isArray(data.data)) {\n mergeIncoming(data.data)\n }\n },\n [\n messagesEndpoint,\n mergeIncoming,\n clearSession,\n reportError,\n reportFault,\n stopRealtime,\n ]\n )\n\n useEffect(() => {\n const realtimeOn =\n enabled && enableRealtime && guestContactOk && !fault\n if (!realtimeOn || !sessionPublicId) {\n return\n }\n\n const connectWs = () => {\n if (!enableWebSocket || !apiOrigin || !projectUid || !integrationId) {\n return\n }\n try {\n const url = buildVisitorWsUrl(\n apiOrigin,\n projectUid,\n integrationId,\n sessionPublicId\n )\n setConnectionState('connecting')\n const ws = new WebSocket(url)\n wsRef.current = ws\n ws.onopen = () => setConnectionState('open')\n ws.onmessage = (ev) => {\n try {\n const msg = JSON.parse(ev.data as string) as {\n type?: string\n payload?: {\n messageId?: unknown\n content?: unknown\n messageType?: unknown\n senderEmail?: unknown\n senderName?: unknown\n createdAt?: unknown\n }\n }\n if (msg.type !== 'chat.message') return\n const p = msg.payload\n if (\n p &&\n typeof p.messageId === 'string' &&\n typeof p.content === 'string'\n ) {\n mergeMessage({\n id: p.messageId,\n content: p.content,\n messageType:\n typeof p.messageType === 'string'\n ? p.messageType\n : 'OUTBOUND',\n senderEmail:\n typeof p.senderEmail === 'string' ? p.senderEmail : null,\n senderName:\n typeof p.senderName === 'string' ? p.senderName : null,\n createdAt:\n typeof p.createdAt === 'string'\n ? p.createdAt\n : new Date().toISOString(),\n })\n }\n void refreshMessages(sessionPublicId)\n } catch {\n /* ignore */\n }\n }\n ws.onclose = () => {\n wsRef.current = null\n setConnectionState('closed')\n }\n } catch {\n setConnectionState('closed')\n }\n }\n\n connectWs()\n void refreshMessages(sessionPublicId, { full: true })\n\n if (enablePolling) {\n pollRef.current = setInterval(() => {\n void refreshMessages(sessionPublicId)\n }, pollIntervalMs)\n }\n\n return () => {\n if (pollRef.current) clearInterval(pollRef.current)\n pollRef.current = null\n wsRef.current?.close()\n wsRef.current = null\n setConnectionState('idle')\n }\n }, [\n enabled,\n enableRealtime,\n enablePolling,\n enableWebSocket,\n guestContactOk,\n fault,\n sessionPublicId,\n apiOrigin,\n projectUid,\n integrationId,\n pollIntervalMs,\n refreshMessages,\n mergeMessage,\n ])\n\n const sendMessage = useCallback(\n async (\n content: string,\n opts?: {\n pageUrl?: string\n invalidEmailMessage?: string\n topicId?: string\n }\n ): Promise<boolean> => {\n const text = content.trim()\n if (!text || sending) return false\n if (faultRef.current) return false\n if (!isAuthenticated && !isValidEmail(guestEmail)) {\n reportError(\n opts?.invalidEmailMessage ?? 'Please enter a valid email address.'\n )\n return false\n }\n setSending(true)\n reportError(null)\n clearFault()\n try {\n const buildBody = (includeSession: boolean) => {\n const body: Record<string, string> = { content: text }\n const pageUrl =\n opts?.pageUrl ??\n (typeof window !== 'undefined' ? window.location.href : undefined)\n if (pageUrl) body.pageUrl = pageUrl\n const sid = includeSession ? sessionPublicIdRef.current : null\n if (sid) body.sessionPublicId = sid\n else if (opts?.topicId?.trim()) {\n body.topicId = opts.topicId.trim()\n }\n if (!isAuthenticated) {\n body.senderEmail = guestEmail.trim().toLowerCase()\n if (guestName.trim()) body.senderName = guestName.trim()\n }\n return body\n }\n\n const post = async (includeSession: boolean) => {\n let res: Response\n try {\n res = await fetch(submitEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(buildBody(includeSession)),\n })\n } catch {\n return {\n res: null as Response | null,\n data: {} as {\n sessionPublicId?: string\n messageId?: string\n message?: unknown\n error?: unknown\n },\n networkError: true as const,\n }\n }\n const data = (await res.json().catch(() => ({}))) as {\n sessionPublicId?: string\n messageId?: string\n message?: unknown\n error?: unknown\n }\n return { res, data, networkError: false as const }\n }\n\n let result = await post(true)\n if (result.networkError) {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return false\n }\n let { res, data } = result\n if (!res) return false\n if (!res.ok && isChatSessionNotFound(res.status, data)) {\n clearSession()\n result = await post(false)\n if (result.networkError) {\n const next = classifyChatFault(0, null, 'Network error')\n if (next) {\n reportFault(next)\n stopRealtime()\n }\n return false\n }\n ;({ res, data } = result)\n if (!res) return false\n }\n if (!res.ok) {\n const classified = classifyChatFault(\n res.status,\n data,\n 'Send failed'\n )\n if (classified) {\n reportFault(classified)\n stopRealtime()\n return false\n }\n reportError(messageFromPayload(data, 'Send failed'))\n return false\n }\n if (data.sessionPublicId) {\n persistSessionPublicId(data.sessionPublicId, storageKey, {\n sessionPublicIdRef,\n setSessionPublicId,\n onCreated: onSessionCreatedRef.current,\n })\n }\n if (!isAuthenticated) {\n persistGuestProfile(guestEmail, guestName)\n }\n if (typeof data.messageId === 'string' && data.messageId) {\n mergeMessage({\n id: data.messageId,\n content: text,\n messageType: 'INBOUND',\n senderEmail: isAuthenticated\n ? null\n : guestEmail.trim().toLowerCase(),\n senderName: isAuthenticated\n ? null\n : guestName.trim() || null,\n createdAt: new Date().toISOString(),\n })\n }\n const nextSid = data.sessionPublicId ?? sessionPublicIdRef.current\n if (nextSid) {\n await refreshMessages(nextSid, { full: true })\n }\n onMessageSentRef.current?.(text)\n return true\n } catch (e) {\n reportError(e instanceof Error ? e.message : 'Send failed')\n return false\n } finally {\n setSending(false)\n }\n },\n [\n sending,\n isAuthenticated,\n guestEmail,\n guestName,\n submitEndpoint,\n storageKey,\n persistGuestProfile,\n mergeMessage,\n refreshMessages,\n clearSession,\n reportError,\n reportFault,\n clearFault,\n stopRealtime,\n ]\n )\n\n const retryAfterFault = useCallback(() => {\n clearFault()\n reportError(null)\n }, [clearFault, reportError])\n\n const canCompose = isAuthenticated || (guestProfileHydrated && guestContactOk)\n\n return {\n sessionPublicId,\n messages,\n sending,\n error,\n fault,\n setError: reportError,\n clearFault,\n retryAfterFault,\n connectionState,\n guestEmail,\n guestName,\n setGuestEmail,\n setGuestName,\n guestContactOk,\n guestProfileHydrated,\n confirmGuestContact,\n resetGuestContact,\n canCompose,\n sendMessage,\n refreshMessages,\n clearSession,\n }\n}\n","export type GuestUiCopy = {\n intro: string\n emailLabel: string\n nameLabel: string\n emailPlaceholder: string\n namePlaceholder: string\n continueCta: string\n changeContact: string\n backToTopics: string\n emailInvalid: string\n threadHint: string\n threadHintIconLabel: string\n threadHintCollapse: string\n emptyThreadGuest: string\n loadingProfile: string\n}\n\nexport type MailooChatUnavailableCopy = {\n rateLimitedTitle: string\n rateLimitedBody: string\n unavailableTitle: string\n unavailableBody: string\n retryCta: string\n contactCta: string\n}\n\nexport type MailooChatUiLabels = GuestUiCopy &\n MailooChatUnavailableCopy & {\n title: string\n launcherOpen: string\n launcherClose: string\n send: string\n composerPlaceholder: string\n emptyThreadAuthenticated: string\n }\n\nexport function isValidEmail(s: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(s.trim())\n}\n\nfunction unavailableCopy(locale: string): MailooChatUnavailableCopy {\n switch (locale) {\n case 'ru':\n return {\n rateLimitedTitle: 'Чат временно недоступен',\n rateLimitedBody:\n 'Слишком много запросов. Подождите немного и попробуйте снова или свяжитесь с нами другим способом.',\n unavailableTitle: 'Чат временно недоступен',\n unavailableBody:\n 'Не удалось связаться с чатом. Попробуйте ещё раз или напишите нам другим способом.',\n retryCta: 'Повторить',\n contactCta: 'Связаться с нами',\n }\n case 'de':\n return {\n rateLimitedTitle: 'Chat vorübergehend nicht verfügbar',\n rateLimitedBody:\n 'Zu viele Anfragen. Bitte warten Sie kurz und versuchen Sie es erneut, oder kontaktieren Sie uns auf anderem Wege.',\n unavailableTitle: 'Chat vorübergehend nicht verfügbar',\n unavailableBody:\n 'Der Chat ist gerade nicht erreichbar. Bitte versuchen Sie es erneut oder kontaktieren Sie uns auf anderem Wege.',\n retryCta: 'Erneut versuchen',\n contactCta: 'Kontakt aufnehmen',\n }\n case 'es':\n return {\n rateLimitedTitle: 'Chat temporalmente no disponible',\n rateLimitedBody:\n 'Hay demasiadas solicitudes. Espera un momento e inténtalo de nuevo, o contáctanos de otra forma.',\n unavailableTitle: 'Chat temporalmente no disponible',\n unavailableBody:\n 'No pudimos conectar con el chat. Inténtalo de nuevo o contáctanos de otra forma.',\n retryCta: 'Reintentar',\n contactCta: 'Contactarnos',\n }\n default:\n return {\n rateLimitedTitle: 'Chat temporarily unavailable',\n rateLimitedBody:\n 'Too many requests right now. Please wait a moment and try again, or reach us another way.',\n unavailableTitle: 'Chat temporarily unavailable',\n unavailableBody:\n 'We could not reach chat right now. Please try again, or contact us another way.',\n retryCta: 'Try again',\n contactCta: 'Contact us',\n }\n }\n}\n\nexport function guestCopy(locale: string): GuestUiCopy {\n switch (locale) {\n case 'ru':\n return {\n intro:\n 'Чтобы мы могли с вами связаться, укажите адрес электронной почты (обязательно) и при желании — имя.',\n emailLabel: 'Электронная почта',\n nameLabel: 'Имя',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Необязательно',\n continueCta: 'Продолжить',\n changeContact: 'Изменить контакты',\n backToTopics: 'К списку тем',\n emailInvalid: 'Пожалуйста, введите корректный адрес электронной почты.',\n threadHint:\n 'Переписка отображается ниже. Мы продублируем переписку на указанный email в случае обрыва связи.',\n threadHintIconLabel: 'Подсказка: переписка и дублирование на email',\n threadHintCollapse: 'Свернуть',\n emptyThreadGuest: 'Напишите первое сообщение в поле ниже.',\n loadingProfile: 'Загрузка…',\n }\n case 'de':\n return {\n intro:\n 'Damit wir antworten können, geben Sie bitte Ihre E-Mail-Adresse an (Pflichtfeld) und optional Ihren Namen.',\n emailLabel: 'E-Mail',\n nameLabel: 'Name',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Optional',\n continueCta: 'Weiter',\n changeContact: 'Kontakt ändern',\n backToTopics: 'Zurück zu den Themen',\n emailInvalid: 'Bitte geben Sie eine gültige E-Mail-Adresse ein.',\n threadHint:\n 'Der Chatverlauf erscheint unten. Wir antworten per E-Mail.',\n threadHintIconLabel: 'Hinweis zu Chat und E-Mail',\n threadHintCollapse: 'Einklappen',\n emptyThreadGuest: 'Schreiben Sie Ihre erste Nachricht unten.',\n loadingProfile: 'Wird geladen…',\n }\n case 'es':\n return {\n intro:\n 'Para poder responderte, indica tu correo electrónico (obligatorio) y, si quieres, tu nombre.',\n emailLabel: 'Correo electrónico',\n nameLabel: 'Nombre',\n emailPlaceholder: 'tu@ejemplo.com',\n namePlaceholder: 'Opcional',\n continueCta: 'Continuar',\n changeContact: 'Cambiar datos',\n backToTopics: 'Volver a los temas',\n emailInvalid: 'Introduce un correo electrónico válido.',\n threadHint: 'Los mensajes aparecen abajo. Te responderemos por correo.',\n threadHintIconLabel: 'Aviso sobre el chat y el correo',\n threadHintCollapse: 'Ocultar',\n emptyThreadGuest: 'Escribe tu primer mensaje abajo.',\n loadingProfile: 'Cargando…',\n }\n default:\n return {\n intro:\n 'So we can reach you, please enter your email address (required) and your name if you’d like (optional).',\n emailLabel: 'Email',\n nameLabel: 'Name',\n emailPlaceholder: 'you@example.com',\n namePlaceholder: 'Optional',\n continueCta: 'Continue',\n changeContact: 'Change contact details',\n backToTopics: 'Back to topics',\n emailInvalid: 'Please enter a valid email address.',\n threadHint:\n 'Your conversation appears below. We’ll reply to your email.',\n threadHintIconLabel: 'Note about chat and email',\n threadHintCollapse: 'Collapse',\n emptyThreadGuest: 'Write your first message in the box below.',\n loadingProfile: 'Loading…',\n }\n }\n}\n\nexport function defaultChatUiLabels(locale: string): MailooChatUiLabels {\n return {\n ...guestCopy(locale),\n ...unavailableCopy(locale),\n title: 'Chat',\n launcherOpen: 'Open chat',\n launcherClose: 'Close chat',\n send: 'Send',\n composerPlaceholder: 'Type a message…',\n emptyThreadAuthenticated: 'Say hello to start a conversation.',\n }\n}\n","export function buildVisitorWsUrl(\n apiOrigin: string,\n projectUid: string,\n integrationId: string,\n sessionPublicId: string\n): string {\n const u = new URL(apiOrigin)\n const wsProto = u.protocol === 'https:' ? 'wss:' : 'ws:'\n const qs = new URLSearchParams({\n projectUid,\n integrationId,\n sessionPublicId,\n })\n return `${wsProto}//${u.host}/api/v1/chat/visitor-ws?${qs.toString()}`\n}\n"],"mappings":"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","names":["import_react","res","data"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { M as MailooChatMessage } from '../chat-message-Dw6tKBEb.cjs';
|
|
2
|
+
import { M as MailooChatFault, a as MailooChatConnectionState, b as MailooChatSubmitResult, c as MailooChatStatus } from '../shared-glVmghqk.cjs';
|
|
3
|
+
export { D as DEFAULT_CHAT_GUEST_PROFILE_KEY, e as DEFAULT_CHAT_MESSAGES_ENDPOINT, f as DEFAULT_CHAT_POLL_INTERVAL_MS, g as DEFAULT_CHAT_SESSION_STORAGE_KEY, h as DEFAULT_CHAT_STATUS_ENDPOINT, i as DEFAULT_CHAT_SUBMIT_ENDPOINT, k as MailooChatFaultKind, d as classifyChatFault, j as isChatSessionNotFound, m as messageFromPayload } from '../shared-glVmghqk.cjs';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
|
|
6
|
+
type UseMailooChatSessionOptions = {
|
|
7
|
+
apiOrigin: string;
|
|
8
|
+
projectUid: string;
|
|
9
|
+
integrationId: string;
|
|
10
|
+
isAuthenticated: boolean;
|
|
11
|
+
submitEndpoint?: string;
|
|
12
|
+
messagesEndpoint?: string;
|
|
13
|
+
storageKey?: string;
|
|
14
|
+
guestProfileKey?: string;
|
|
15
|
+
pollIntervalMs?: number;
|
|
16
|
+
enableRealtime?: boolean;
|
|
17
|
+
enablePolling?: boolean;
|
|
18
|
+
enableWebSocket?: boolean;
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
onSessionCreated?: (sessionPublicId: string) => void;
|
|
21
|
+
onMessageSent?: (content: string) => void;
|
|
22
|
+
onError?: (error: string) => void;
|
|
23
|
+
onFault?: (fault: MailooChatFault) => void;
|
|
24
|
+
};
|
|
25
|
+
declare function useMailooChatSession(options: UseMailooChatSessionOptions): {
|
|
26
|
+
sessionPublicId: string | null;
|
|
27
|
+
messages: MailooChatMessage[];
|
|
28
|
+
sending: boolean;
|
|
29
|
+
error: string | null;
|
|
30
|
+
fault: MailooChatFault | null;
|
|
31
|
+
setError: (message: string | null) => void;
|
|
32
|
+
clearFault: () => void;
|
|
33
|
+
retryAfterFault: () => void;
|
|
34
|
+
connectionState: MailooChatConnectionState;
|
|
35
|
+
guestEmail: string;
|
|
36
|
+
guestName: string;
|
|
37
|
+
setGuestEmail: react.Dispatch<react.SetStateAction<string>>;
|
|
38
|
+
setGuestName: react.Dispatch<react.SetStateAction<string>>;
|
|
39
|
+
guestContactOk: boolean;
|
|
40
|
+
guestProfileHydrated: boolean;
|
|
41
|
+
confirmGuestContact: (invalidEmailMessage?: string) => boolean;
|
|
42
|
+
resetGuestContact: () => void;
|
|
43
|
+
canCompose: boolean;
|
|
44
|
+
sendMessage: (content: string, opts?: {
|
|
45
|
+
pageUrl?: string;
|
|
46
|
+
invalidEmailMessage?: string;
|
|
47
|
+
topicId?: string;
|
|
48
|
+
}) => Promise<boolean>;
|
|
49
|
+
refreshMessages: (sid?: string, opts?: {
|
|
50
|
+
full?: boolean;
|
|
51
|
+
}) => Promise<void>;
|
|
52
|
+
clearSession: () => void;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
declare function useMailooChatSubmit(options?: {
|
|
56
|
+
endpoint?: string;
|
|
57
|
+
}): {
|
|
58
|
+
submit: (body: Record<string, unknown>) => Promise<MailooChatSubmitResult>;
|
|
59
|
+
pending: boolean;
|
|
60
|
+
};
|
|
61
|
+
declare function useMailooChatMessages(options?: {
|
|
62
|
+
endpoint?: string;
|
|
63
|
+
}): {
|
|
64
|
+
refresh: (sessionPublicId: string, since?: string) => Promise<MailooChatSubmitResult & {
|
|
65
|
+
messages?: MailooChatMessage[];
|
|
66
|
+
}>;
|
|
67
|
+
pending: boolean;
|
|
68
|
+
};
|
|
69
|
+
declare function useMailooChatStatus(options?: {
|
|
70
|
+
endpoint?: string;
|
|
71
|
+
enabled?: boolean;
|
|
72
|
+
}): {
|
|
73
|
+
status: MailooChatStatus | null;
|
|
74
|
+
pending: boolean;
|
|
75
|
+
error: string | null;
|
|
76
|
+
refresh: () => Promise<MailooChatStatus | null>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { MailooChatConnectionState, MailooChatFault, MailooChatMessage, MailooChatStatus, MailooChatSubmitResult, type UseMailooChatSessionOptions, useMailooChatMessages, useMailooChatSession, useMailooChatStatus, useMailooChatSubmit };
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { M as MailooChatMessage } from '../chat-message-Dw6tKBEb.js';
|
|
2
|
+
import { M as MailooChatFault, a as MailooChatConnectionState, b as MailooChatSubmitResult, c as MailooChatStatus } from '../shared-glVmghqk.js';
|
|
3
|
+
export { D as DEFAULT_CHAT_GUEST_PROFILE_KEY, e as DEFAULT_CHAT_MESSAGES_ENDPOINT, f as DEFAULT_CHAT_POLL_INTERVAL_MS, g as DEFAULT_CHAT_SESSION_STORAGE_KEY, h as DEFAULT_CHAT_STATUS_ENDPOINT, i as DEFAULT_CHAT_SUBMIT_ENDPOINT, k as MailooChatFaultKind, d as classifyChatFault, j as isChatSessionNotFound, m as messageFromPayload } from '../shared-glVmghqk.js';
|
|
4
|
+
import * as react from 'react';
|
|
5
|
+
|
|
6
|
+
type UseMailooChatSessionOptions = {
|
|
7
|
+
apiOrigin: string;
|
|
8
|
+
projectUid: string;
|
|
9
|
+
integrationId: string;
|
|
10
|
+
isAuthenticated: boolean;
|
|
11
|
+
submitEndpoint?: string;
|
|
12
|
+
messagesEndpoint?: string;
|
|
13
|
+
storageKey?: string;
|
|
14
|
+
guestProfileKey?: string;
|
|
15
|
+
pollIntervalMs?: number;
|
|
16
|
+
enableRealtime?: boolean;
|
|
17
|
+
enablePolling?: boolean;
|
|
18
|
+
enableWebSocket?: boolean;
|
|
19
|
+
enabled?: boolean;
|
|
20
|
+
onSessionCreated?: (sessionPublicId: string) => void;
|
|
21
|
+
onMessageSent?: (content: string) => void;
|
|
22
|
+
onError?: (error: string) => void;
|
|
23
|
+
onFault?: (fault: MailooChatFault) => void;
|
|
24
|
+
};
|
|
25
|
+
declare function useMailooChatSession(options: UseMailooChatSessionOptions): {
|
|
26
|
+
sessionPublicId: string | null;
|
|
27
|
+
messages: MailooChatMessage[];
|
|
28
|
+
sending: boolean;
|
|
29
|
+
error: string | null;
|
|
30
|
+
fault: MailooChatFault | null;
|
|
31
|
+
setError: (message: string | null) => void;
|
|
32
|
+
clearFault: () => void;
|
|
33
|
+
retryAfterFault: () => void;
|
|
34
|
+
connectionState: MailooChatConnectionState;
|
|
35
|
+
guestEmail: string;
|
|
36
|
+
guestName: string;
|
|
37
|
+
setGuestEmail: react.Dispatch<react.SetStateAction<string>>;
|
|
38
|
+
setGuestName: react.Dispatch<react.SetStateAction<string>>;
|
|
39
|
+
guestContactOk: boolean;
|
|
40
|
+
guestProfileHydrated: boolean;
|
|
41
|
+
confirmGuestContact: (invalidEmailMessage?: string) => boolean;
|
|
42
|
+
resetGuestContact: () => void;
|
|
43
|
+
canCompose: boolean;
|
|
44
|
+
sendMessage: (content: string, opts?: {
|
|
45
|
+
pageUrl?: string;
|
|
46
|
+
invalidEmailMessage?: string;
|
|
47
|
+
topicId?: string;
|
|
48
|
+
}) => Promise<boolean>;
|
|
49
|
+
refreshMessages: (sid?: string, opts?: {
|
|
50
|
+
full?: boolean;
|
|
51
|
+
}) => Promise<void>;
|
|
52
|
+
clearSession: () => void;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
declare function useMailooChatSubmit(options?: {
|
|
56
|
+
endpoint?: string;
|
|
57
|
+
}): {
|
|
58
|
+
submit: (body: Record<string, unknown>) => Promise<MailooChatSubmitResult>;
|
|
59
|
+
pending: boolean;
|
|
60
|
+
};
|
|
61
|
+
declare function useMailooChatMessages(options?: {
|
|
62
|
+
endpoint?: string;
|
|
63
|
+
}): {
|
|
64
|
+
refresh: (sessionPublicId: string, since?: string) => Promise<MailooChatSubmitResult & {
|
|
65
|
+
messages?: MailooChatMessage[];
|
|
66
|
+
}>;
|
|
67
|
+
pending: boolean;
|
|
68
|
+
};
|
|
69
|
+
declare function useMailooChatStatus(options?: {
|
|
70
|
+
endpoint?: string;
|
|
71
|
+
enabled?: boolean;
|
|
72
|
+
}): {
|
|
73
|
+
status: MailooChatStatus | null;
|
|
74
|
+
pending: boolean;
|
|
75
|
+
error: string | null;
|
|
76
|
+
refresh: () => Promise<MailooChatStatus | null>;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { MailooChatConnectionState, MailooChatFault, MailooChatMessage, MailooChatStatus, MailooChatSubmitResult, type UseMailooChatSessionOptions, useMailooChatMessages, useMailooChatSession, useMailooChatStatus, useMailooChatSubmit };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_CHAT_GUEST_PROFILE_KEY,
|
|
4
|
+
DEFAULT_CHAT_MESSAGES_ENDPOINT,
|
|
5
|
+
DEFAULT_CHAT_POLL_INTERVAL_MS,
|
|
6
|
+
DEFAULT_CHAT_SESSION_STORAGE_KEY,
|
|
7
|
+
DEFAULT_CHAT_STATUS_ENDPOINT,
|
|
8
|
+
DEFAULT_CHAT_SUBMIT_ENDPOINT,
|
|
9
|
+
classifyChatFault,
|
|
10
|
+
isChatSessionNotFound,
|
|
11
|
+
messageFromPayload,
|
|
12
|
+
useMailooChatMessages,
|
|
13
|
+
useMailooChatSession,
|
|
14
|
+
useMailooChatStatus,
|
|
15
|
+
useMailooChatSubmit
|
|
16
|
+
} from "../chunk-QZ7HWQDO.js";
|
|
17
|
+
export {
|
|
18
|
+
DEFAULT_CHAT_GUEST_PROFILE_KEY,
|
|
19
|
+
DEFAULT_CHAT_MESSAGES_ENDPOINT,
|
|
20
|
+
DEFAULT_CHAT_POLL_INTERVAL_MS,
|
|
21
|
+
DEFAULT_CHAT_SESSION_STORAGE_KEY,
|
|
22
|
+
DEFAULT_CHAT_STATUS_ENDPOINT,
|
|
23
|
+
DEFAULT_CHAT_SUBMIT_ENDPOINT,
|
|
24
|
+
classifyChatFault,
|
|
25
|
+
isChatSessionNotFound,
|
|
26
|
+
messageFromPayload,
|
|
27
|
+
useMailooChatMessages,
|
|
28
|
+
useMailooChatSession,
|
|
29
|
+
useMailooChatStatus,
|
|
30
|
+
useMailooChatSubmit
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
MAILOO_CHAT_LAUNCHER_POSITIONS: () => MAILOO_CHAT_LAUNCHER_POSITIONS,
|
|
24
|
+
chatWidgetCssVariables: () => chatWidgetCssVariables,
|
|
25
|
+
fetchMailooChatIntegrationStatus: () => fetchMailooChatIntegrationStatus,
|
|
26
|
+
fetchMailooChatWidgetConfig: () => fetchMailooChatWidgetConfig,
|
|
27
|
+
getMailooChatIntegrationConfig: () => getMailooChatIntegrationConfig,
|
|
28
|
+
getMailooChatWebSocketOrigin: () => getMailooChatWebSocketOrigin,
|
|
29
|
+
isMailooChatLauncherPosition: () => isMailooChatLauncherPosition,
|
|
30
|
+
mailooChatLauncherRootClassNames: () => mailooChatLauncherRootClassNames,
|
|
31
|
+
resolveMailooChatHostConfig: () => resolveMailooChatHostConfig,
|
|
32
|
+
resolveMailooChatLauncherPosition: () => resolveMailooChatLauncherPosition
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(src_exports);
|
|
35
|
+
|
|
36
|
+
// src/config.ts
|
|
37
|
+
var import_navigation = require("next/navigation");
|
|
38
|
+
var import_next_core = require("@mailoo/next-core");
|
|
39
|
+
|
|
40
|
+
// src/lib/widget-config.ts
|
|
41
|
+
var MAILOO_CHAT_LAUNCHER_POSITIONS = [
|
|
42
|
+
"bottom-right",
|
|
43
|
+
"bottom-left",
|
|
44
|
+
"top-right",
|
|
45
|
+
"top-left",
|
|
46
|
+
"middle-right",
|
|
47
|
+
"middle-left"
|
|
48
|
+
];
|
|
49
|
+
function isMailooChatLauncherPosition(value) {
|
|
50
|
+
return typeof value === "string" && MAILOO_CHAT_LAUNCHER_POSITIONS.includes(value);
|
|
51
|
+
}
|
|
52
|
+
function resolveMailooChatLauncherPosition(prop, config) {
|
|
53
|
+
if (prop) return prop;
|
|
54
|
+
if (config?.position && isMailooChatLauncherPosition(config.position)) {
|
|
55
|
+
return config.position;
|
|
56
|
+
}
|
|
57
|
+
return "bottom-right";
|
|
58
|
+
}
|
|
59
|
+
function mailooChatLauncherRootClassNames(position) {
|
|
60
|
+
const parts = ["mailoo-chat-root"];
|
|
61
|
+
if (position.endsWith("-left")) parts.push("mailoo-chat-root--left");
|
|
62
|
+
if (position.startsWith("top-")) parts.push("mailoo-chat-root--top");
|
|
63
|
+
if (position.startsWith("middle-")) parts.push("mailoo-chat-root--middle");
|
|
64
|
+
return parts.join(" ");
|
|
65
|
+
}
|
|
66
|
+
function chatWidgetCssVariables(config) {
|
|
67
|
+
return {
|
|
68
|
+
["--mailoo-chat-brand"]: config?.brandPrimary ?? "#2563EB",
|
|
69
|
+
["--mailoo-chat-brand-on"]: config?.brandOnPrimary ?? "#FFFFFF"
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/config.ts
|
|
74
|
+
function getMailooChatIntegrationConfig() {
|
|
75
|
+
return (0, import_next_core.readMailooIntegrationConfig)({
|
|
76
|
+
prefix: "MAILOO_CHAT_INTEGRATION",
|
|
77
|
+
allowApiBaseUrlFallback: true
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function getMailooChatWebSocketOrigin() {
|
|
81
|
+
const explicit = process.env.MAILOO_CHAT_WS_ORIGIN?.trim();
|
|
82
|
+
if (explicit) {
|
|
83
|
+
return explicit.replace(/\/$/, "");
|
|
84
|
+
}
|
|
85
|
+
const chatCfg = getMailooChatIntegrationConfig();
|
|
86
|
+
if (chatCfg?.apiBaseUrl) {
|
|
87
|
+
return chatCfg.apiBaseUrl.replace(/\/$/, "");
|
|
88
|
+
}
|
|
89
|
+
const chatApi = process.env.MAILOO_CHAT_INTEGRATION_API?.trim();
|
|
90
|
+
if (chatApi) {
|
|
91
|
+
return chatApi.replace(/\/$/, "");
|
|
92
|
+
}
|
|
93
|
+
const api = process.env.API_BASE_URL?.trim();
|
|
94
|
+
if (api) {
|
|
95
|
+
return api.replace(/\/$/, "");
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
async function fetchMailooChatIntegrationStatus() {
|
|
100
|
+
const cfg = getMailooChatIntegrationConfig();
|
|
101
|
+
if (!cfg) return null;
|
|
102
|
+
try {
|
|
103
|
+
const url = `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/status`;
|
|
104
|
+
const response = await fetch(url, {
|
|
105
|
+
method: "GET",
|
|
106
|
+
headers: {
|
|
107
|
+
"Content-Type": "application/json",
|
|
108
|
+
"X-API-Key": cfg.apiKey
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (!response.ok) return null;
|
|
112
|
+
const data = await response.json();
|
|
113
|
+
if (typeof data.status !== "string" || typeof data.name !== "string" || typeof data.type !== "string" || typeof data.lastActivity !== "string") {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
status: data.status,
|
|
118
|
+
name: data.name,
|
|
119
|
+
type: data.type,
|
|
120
|
+
lastActivity: data.lastActivity
|
|
121
|
+
};
|
|
122
|
+
} catch (error) {
|
|
123
|
+
(0, import_navigation.unstable_rethrow)(error);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function fetchMailooChatWidgetConfig(locale) {
|
|
128
|
+
const cfg = getMailooChatIntegrationConfig();
|
|
129
|
+
if (!cfg) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const url = new URL(
|
|
134
|
+
`${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/widget-config`
|
|
135
|
+
);
|
|
136
|
+
url.searchParams.set("locale", locale);
|
|
137
|
+
const response = await fetch(url.toString(), {
|
|
138
|
+
method: "GET",
|
|
139
|
+
headers: {
|
|
140
|
+
"Content-Type": "application/json",
|
|
141
|
+
"X-API-Key": cfg.apiKey
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
if (!response.ok) {
|
|
145
|
+
import_next_core.defaultMailooLogger.warn?.(
|
|
146
|
+
`Failed to fetch chat widget config: HTTP ${response.status}`
|
|
147
|
+
);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
const data = await response.json();
|
|
151
|
+
if (!data.widget || !Array.isArray(data.widget.topics)) {
|
|
152
|
+
import_next_core.defaultMailooLogger.warn?.(
|
|
153
|
+
"Failed to fetch chat widget config: invalid response (missing widget.topics)"
|
|
154
|
+
);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
...data.widget,
|
|
159
|
+
topics: data.widget.topics,
|
|
160
|
+
operators: Array.isArray(data.widget.operators) ? data.widget.operators : []
|
|
161
|
+
};
|
|
162
|
+
} catch (error) {
|
|
163
|
+
(0, import_navigation.unstable_rethrow)(error);
|
|
164
|
+
import_next_core.defaultMailooLogger.logException?.(
|
|
165
|
+
error,
|
|
166
|
+
"Failed to fetch chat widget config"
|
|
167
|
+
);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async function resolveMailooChatHostConfig(opts) {
|
|
172
|
+
try {
|
|
173
|
+
const server = getMailooChatIntegrationConfig();
|
|
174
|
+
if (!server) return null;
|
|
175
|
+
const apiOrigin = getMailooChatWebSocketOrigin();
|
|
176
|
+
if (!apiOrigin) return null;
|
|
177
|
+
const locale = opts.locale.trim() || "en";
|
|
178
|
+
const widgetConfig = await fetchMailooChatWidgetConfig(locale);
|
|
179
|
+
if (!widgetConfig) return null;
|
|
180
|
+
const welcomeOverride = process.env.MAILOO_CHAT_WELCOME_MESSAGE?.trim();
|
|
181
|
+
const welcomeMessage = welcomeOverride || widgetConfig.welcomeTagline?.trim() || "";
|
|
182
|
+
return {
|
|
183
|
+
apiOrigin,
|
|
184
|
+
projectUid: server.projectUid,
|
|
185
|
+
integrationId: server.integrationId,
|
|
186
|
+
welcomeMessage,
|
|
187
|
+
locale,
|
|
188
|
+
isAuthenticated: Boolean(opts.isAuthenticated),
|
|
189
|
+
widgetConfig
|
|
190
|
+
};
|
|
191
|
+
} catch (error) {
|
|
192
|
+
(0, import_navigation.unstable_rethrow)(error);
|
|
193
|
+
import_next_core.defaultMailooLogger.logException?.(
|
|
194
|
+
error,
|
|
195
|
+
"resolveMailooChatHostConfig failed"
|
|
196
|
+
);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
201
|
+
0 && (module.exports = {
|
|
202
|
+
MAILOO_CHAT_LAUNCHER_POSITIONS,
|
|
203
|
+
chatWidgetCssVariables,
|
|
204
|
+
fetchMailooChatIntegrationStatus,
|
|
205
|
+
fetchMailooChatWidgetConfig,
|
|
206
|
+
getMailooChatIntegrationConfig,
|
|
207
|
+
getMailooChatWebSocketOrigin,
|
|
208
|
+
isMailooChatLauncherPosition,
|
|
209
|
+
mailooChatLauncherRootClassNames,
|
|
210
|
+
resolveMailooChatHostConfig,
|
|
211
|
+
resolveMailooChatLauncherPosition
|
|
212
|
+
});
|
|
213
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/lib/widget-config.ts"],"sourcesContent":["export {\n getMailooChatIntegrationConfig,\n getMailooChatWebSocketOrigin,\n fetchMailooChatIntegrationStatus,\n fetchMailooChatWidgetConfig,\n resolveMailooChatHostConfig,\n type MailooChatIntegrationConfig,\n type MailooChatIntegrationStatus,\n type MailooChatHostConfig,\n} from './config.js'\nexport {\n chatWidgetCssVariables,\n isMailooChatLauncherPosition,\n mailooChatLauncherRootClassNames,\n resolveMailooChatLauncherPosition,\n MAILOO_CHAT_LAUNCHER_POSITIONS,\n type MailooChatLauncherPosition,\n type MailooChatWidgetConfig,\n type MailooChatWidgetOperator,\n type MailooChatWidgetTopic,\n} from './lib/widget-config.js'\n","import { unstable_rethrow } from 'next/navigation'\nimport {\n defaultMailooLogger,\n readMailooIntegrationConfig,\n type MailooIntegrationConfig,\n} from '@mailoo/next-core'\nimport type { MailooChatWidgetConfig } from './lib/widget-config.js'\n\nexport type MailooChatIntegrationConfig = MailooIntegrationConfig\n\nexport function getMailooChatIntegrationConfig(): MailooChatIntegrationConfig | null {\n return readMailooIntegrationConfig({\n prefix: 'MAILOO_CHAT_INTEGRATION',\n allowApiBaseUrlFallback: true,\n })\n}\n\n/**\n * Base URL the browser uses for Mailoo chat WebSockets (ws/wss).\n * Precedence: MAILOO_CHAT_WS_ORIGIN → chat API base → API_BASE_URL.\n * The host must expose WebSocket upgrade on the public API hostname.\n */\nexport function getMailooChatWebSocketOrigin(): string | null {\n const explicit = process.env.MAILOO_CHAT_WS_ORIGIN?.trim()\n if (explicit) {\n return explicit.replace(/\\/$/, '')\n }\n const chatCfg = getMailooChatIntegrationConfig()\n if (chatCfg?.apiBaseUrl) {\n return chatCfg.apiBaseUrl.replace(/\\/$/, '')\n }\n const chatApi = process.env.MAILOO_CHAT_INTEGRATION_API?.trim()\n if (chatApi) {\n return chatApi.replace(/\\/$/, '')\n }\n const api = process.env.API_BASE_URL?.trim()\n if (api) {\n return api.replace(/\\/$/, '')\n }\n return null\n}\n\nexport type MailooChatIntegrationStatus = {\n status: string\n name: string\n type: string\n lastActivity: string\n}\n\nexport type { MailooChatWidgetConfig } from './lib/widget-config.js'\nexport {\n chatWidgetCssVariables,\n isMailooChatLauncherPosition,\n mailooChatLauncherRootClassNames,\n resolveMailooChatLauncherPosition,\n MAILOO_CHAT_LAUNCHER_POSITIONS,\n type MailooChatLauncherPosition,\n type MailooChatWidgetOperator,\n type MailooChatWidgetTopic,\n} from './lib/widget-config.js'\n\n/**\n * Server-side status check against Mailoo (API key from env).\n * Returns null when chat is not configured or the request fails.\n */\nexport async function fetchMailooChatIntegrationStatus(): Promise<MailooChatIntegrationStatus | null> {\n const cfg = getMailooChatIntegrationConfig()\n if (!cfg) return null\n try {\n const url = `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/status`\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': cfg.apiKey,\n },\n })\n if (!response.ok) return null\n const data = (await response.json()) as Partial<MailooChatIntegrationStatus>\n if (\n typeof data.status !== 'string' ||\n typeof data.name !== 'string' ||\n typeof data.type !== 'string' ||\n typeof data.lastActivity !== 'string'\n ) {\n return null\n }\n return {\n status: data.status,\n name: data.name,\n type: data.type,\n lastActivity: data.lastActivity,\n }\n } catch (error) {\n unstable_rethrow(error)\n return null\n }\n}\n\n/**\n * Server-side widget config from Mailoo API (brand, operators, topics, privacy).\n * Returns null when env is missing, the request fails, or the payload is invalid.\n * Never throws — hosts must not 500 the page when chat bootstrap fails.\n */\nexport async function fetchMailooChatWidgetConfig(\n locale: string\n): Promise<MailooChatWidgetConfig | null> {\n const cfg = getMailooChatIntegrationConfig()\n if (!cfg) {\n return null\n }\n try {\n const url = new URL(\n `${cfg.apiBaseUrl}/api/v1/webhooks/chat/${cfg.projectUid}/${cfg.integrationId}/widget-config`\n )\n url.searchParams.set('locale', locale)\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n 'X-API-Key': cfg.apiKey,\n },\n })\n if (!response.ok) {\n defaultMailooLogger.warn?.(\n `Failed to fetch chat widget config: HTTP ${response.status}`\n )\n return null\n }\n const data = (await response.json()) as {\n widget?: MailooChatWidgetConfig\n }\n if (!data.widget || !Array.isArray(data.widget.topics)) {\n defaultMailooLogger.warn?.(\n 'Failed to fetch chat widget config: invalid response (missing widget.topics)'\n )\n return null\n }\n return {\n ...data.widget,\n topics: data.widget.topics,\n operators: Array.isArray(data.widget.operators)\n ? data.widget.operators\n : [],\n }\n } catch (error) {\n unstable_rethrow(error)\n defaultMailooLogger.logException?.(\n error,\n 'Failed to fetch chat widget config'\n )\n return null\n }\n}\n\n/** Props for {@link MailooSiteChatShell} / floating widget host. */\nexport type MailooChatHostConfig = {\n apiOrigin: string\n projectUid: string\n integrationId: string\n welcomeMessage: string\n locale: string\n isAuthenticated: boolean\n /** Always present when resolve succeeds — brand, topics, position, etc. */\n widgetConfig: MailooChatWidgetConfig\n}\n\n/**\n * Default host resolve: env + public JSBOX widget-config.\n * Returns null when chat env is incomplete or widget-config cannot load\n * (do not mount the widget). Never throws — page hosts must stay HTTP 200.\n */\nexport async function resolveMailooChatHostConfig(opts: {\n locale: string\n isAuthenticated?: boolean\n}): Promise<MailooChatHostConfig | null> {\n try {\n const server = getMailooChatIntegrationConfig()\n if (!server) return null\n\n const apiOrigin = getMailooChatWebSocketOrigin()\n if (!apiOrigin) return null\n\n const locale = opts.locale.trim() || 'en'\n const widgetConfig = await fetchMailooChatWidgetConfig(locale)\n if (!widgetConfig) return null\n\n const welcomeOverride = process.env.MAILOO_CHAT_WELCOME_MESSAGE?.trim()\n const welcomeMessage =\n welcomeOverride || widgetConfig.welcomeTagline?.trim() || ''\n\n return {\n apiOrigin,\n projectUid: server.projectUid,\n integrationId: server.integrationId,\n welcomeMessage,\n locale,\n isAuthenticated: Boolean(opts.isAuthenticated),\n widgetConfig,\n }\n } catch (error) {\n unstable_rethrow(error)\n defaultMailooLogger.logException?.(\n error,\n 'resolveMailooChatHostConfig failed'\n )\n return null\n }\n}\n","import type { CSSProperties } from 'react'\n\nexport type MailooChatWidgetTopic = {\n id: string\n label: string\n action: 'start_chat' | 'external_url'\n externalUrl?: string\n}\n\nexport type MailooChatWidgetOperator = {\n userId: string\n name: string | null\n image: string | null\n online: boolean\n}\n\nexport const MAILOO_CHAT_LAUNCHER_POSITIONS = [\n 'bottom-right',\n 'bottom-left',\n 'top-right',\n 'top-left',\n 'middle-right',\n 'middle-left',\n] as const\n\nexport type MailooChatLauncherPosition =\n (typeof MAILOO_CHAT_LAUNCHER_POSITIONS)[number]\n\nexport type MailooChatWidgetConfig = {\n brandPrimary?: string\n brandOnPrimary?: string\n welcomeTitle?: string\n welcomeTagline?: string\n privacyPolicyUrl?: string\n position?: MailooChatLauncherPosition\n topics: MailooChatWidgetTopic[]\n operators: MailooChatWidgetOperator[]\n}\n\nexport function isMailooChatLauncherPosition(\n value: unknown\n): value is MailooChatLauncherPosition {\n return (\n typeof value === 'string' &&\n (MAILOO_CHAT_LAUNCHER_POSITIONS as readonly string[]).includes(value)\n )\n}\n\nexport function resolveMailooChatLauncherPosition(\n prop: MailooChatLauncherPosition | undefined,\n config: Pick<MailooChatWidgetConfig, 'position'> | null | undefined\n): MailooChatLauncherPosition {\n if (prop) return prop\n if (config?.position && isMailooChatLauncherPosition(config.position)) {\n return config.position\n }\n return 'bottom-right'\n}\n\nexport function mailooChatLauncherRootClassNames(\n position: MailooChatLauncherPosition\n): string {\n const parts = ['mailoo-chat-root']\n if (position.endsWith('-left')) parts.push('mailoo-chat-root--left')\n if (position.startsWith('top-')) parts.push('mailoo-chat-root--top')\n if (position.startsWith('middle-')) parts.push('mailoo-chat-root--middle')\n return parts.join(' ')\n}\n\nexport function chatWidgetCssVariables(\n config: Pick<\n MailooChatWidgetConfig,\n 'brandPrimary' | 'brandOnPrimary'\n > | null | undefined\n): CSSProperties {\n return {\n ['--mailoo-chat-brand' as string]: config?.brandPrimary ?? '#2563EB',\n ['--mailoo-chat-brand-on' as string]: config?.brandOnPrimary ?? '#FFFFFF',\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { MailooIntegrationConfig } from '@mailoo/next-core';
|
|
2
|
+
import { M as MailooChatWidgetConfig } from './widget-config-B5Tf7gqn.cjs';
|
|
3
|
+
export { b as MAILOO_CHAT_LAUNCHER_POSITIONS, a as MailooChatLauncherPosition, d as MailooChatWidgetOperator, e as MailooChatWidgetTopic, c as chatWidgetCssVariables, i as isMailooChatLauncherPosition, m as mailooChatLauncherRootClassNames, r as resolveMailooChatLauncherPosition } from './widget-config-B5Tf7gqn.cjs';
|
|
4
|
+
import 'react';
|
|
5
|
+
|
|
6
|
+
type MailooChatIntegrationConfig = MailooIntegrationConfig;
|
|
7
|
+
declare function getMailooChatIntegrationConfig(): MailooChatIntegrationConfig | null;
|
|
8
|
+
/**
|
|
9
|
+
* Base URL the browser uses for Mailoo chat WebSockets (ws/wss).
|
|
10
|
+
* Precedence: MAILOO_CHAT_WS_ORIGIN → chat API base → API_BASE_URL.
|
|
11
|
+
* The host must expose WebSocket upgrade on the public API hostname.
|
|
12
|
+
*/
|
|
13
|
+
declare function getMailooChatWebSocketOrigin(): string | null;
|
|
14
|
+
type MailooChatIntegrationStatus = {
|
|
15
|
+
status: string;
|
|
16
|
+
name: string;
|
|
17
|
+
type: string;
|
|
18
|
+
lastActivity: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Server-side status check against Mailoo (API key from env).
|
|
23
|
+
* Returns null when chat is not configured or the request fails.
|
|
24
|
+
*/
|
|
25
|
+
declare function fetchMailooChatIntegrationStatus(): Promise<MailooChatIntegrationStatus | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Server-side widget config from Mailoo API (brand, operators, topics, privacy).
|
|
28
|
+
* Returns null when env is missing, the request fails, or the payload is invalid.
|
|
29
|
+
* Never throws — hosts must not 500 the page when chat bootstrap fails.
|
|
30
|
+
*/
|
|
31
|
+
declare function fetchMailooChatWidgetConfig(locale: string): Promise<MailooChatWidgetConfig | null>;
|
|
32
|
+
/** Props for {@link MailooSiteChatShell} / floating widget host. */
|
|
33
|
+
type MailooChatHostConfig = {
|
|
34
|
+
apiOrigin: string;
|
|
35
|
+
projectUid: string;
|
|
36
|
+
integrationId: string;
|
|
37
|
+
welcomeMessage: string;
|
|
38
|
+
locale: string;
|
|
39
|
+
isAuthenticated: boolean;
|
|
40
|
+
/** Always present when resolve succeeds — brand, topics, position, etc. */
|
|
41
|
+
widgetConfig: MailooChatWidgetConfig;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Default host resolve: env + public JSBOX widget-config.
|
|
45
|
+
* Returns null when chat env is incomplete or widget-config cannot load
|
|
46
|
+
* (do not mount the widget). Never throws — page hosts must stay HTTP 200.
|
|
47
|
+
*/
|
|
48
|
+
declare function resolveMailooChatHostConfig(opts: {
|
|
49
|
+
locale: string;
|
|
50
|
+
isAuthenticated?: boolean;
|
|
51
|
+
}): Promise<MailooChatHostConfig | null>;
|
|
52
|
+
|
|
53
|
+
export { type MailooChatHostConfig, type MailooChatIntegrationConfig, type MailooChatIntegrationStatus, MailooChatWidgetConfig, fetchMailooChatIntegrationStatus, fetchMailooChatWidgetConfig, getMailooChatIntegrationConfig, getMailooChatWebSocketOrigin, resolveMailooChatHostConfig };
|