// @ts-nocheck type GhlMirrorConfig = { token: string locationId: string baseUrl: string version: string } function normalizeBaseUrl(value?: string) { return String(value || "https://services.leadconnectorhq.com").replace( /\/+$/, "" ) } export function readGhlMirrorConfig() { const token = String( process.env.GHL_PRIVATE_INTEGRATION_TOKEN || process.env.GHL_API_TOKEN || "" ).trim() const locationId = String(process.env.GHL_LOCATION_ID || "").trim() const baseUrl = normalizeBaseUrl(process.env.GHL_API_BASE_URL) const version = String(process.env.GHL_API_VERSION || "2021-07-28").trim() if (!token || !locationId) { return null } return { token, locationId, baseUrl, version, } satisfies GhlMirrorConfig } export async function fetchGhlMirrorJson( config: GhlMirrorConfig, pathname: string, init?: RequestInit ) { const response = await fetch(`${config.baseUrl}${pathname}`, { ...init, headers: { Authorization: `Bearer ${config.token}`, Version: config.version, Accept: "application/json", "Content-Type": "application/json", ...(init?.headers || {}), }, cache: "no-store", }) const text = await response.text() let body: any = null if (text) { try { body = JSON.parse(text) } catch { body = null } } if (!response.ok) { throw new Error( `GHL request failed (${response.status}) for ${pathname}: ${body?.message || text || "Unknown error"}` ) } return body } export async function fetchGhlContactsPage( config: GhlMirrorConfig, args?: { limit?: number cursor?: string } ) { const searchParams = new URLSearchParams({ locationId: config.locationId, limit: String(Math.min(100, Math.max(1, args?.limit || 100))), }) if (args?.cursor) { searchParams.set("startAfterId", args.cursor) } const payload = await fetchGhlMirrorJson( config, `/contacts/?${searchParams.toString()}` ) const contacts = Array.isArray(payload?.contacts) ? payload.contacts : Array.isArray(payload?.data?.contacts) ? payload.data.contacts : [] const nextCursor = contacts.length > 0 ? String(contacts[contacts.length - 1]?.id || "") : "" return { items: contacts, nextCursor: nextCursor || undefined, } } export async function fetchGhlMessagesPage( config: GhlMirrorConfig, args?: { limit?: number cursor?: string channel?: "Call" | "SMS" } ) { const url = new URL(`${config.baseUrl}/conversations/messages/export`) url.searchParams.set("locationId", config.locationId) url.searchParams.set("limit", String(Math.min(100, Math.max(1, args?.limit || 100)))) url.searchParams.set("channel", args?.channel || "SMS") if (args?.cursor) { url.searchParams.set("cursor", args.cursor) } const payload = await fetchGhlMirrorJson(config, url.pathname + url.search) return { items: Array.isArray(payload?.messages) ? payload.messages : [], nextCursor: typeof payload?.nextCursor === "string" && payload.nextCursor ? payload.nextCursor : undefined, } } export async function fetchGhlConversationsPage( config: GhlMirrorConfig, args?: { limit?: number } ) { const url = new URL(`${config.baseUrl}/conversations/search`) url.searchParams.set("locationId", config.locationId) url.searchParams.set("limit", String(Math.min(100, Math.max(1, args?.limit || 100)))) const payload = await fetchGhlMirrorJson(config, url.pathname + url.search) return { items: Array.isArray(payload?.conversations) ? payload.conversations : [], total: typeof payload?.total === "number" ? payload.total : Array.isArray(payload?.conversations) ? payload.conversations.length : 0, } } export async function fetchGhlConversationMessages( config: GhlMirrorConfig, args: { conversationId: string } ) { const payload = await fetchGhlMirrorJson( config, `/conversations/${encodeURIComponent(args.conversationId)}/messages` ) return { items: Array.isArray(payload?.messages?.messages) ? payload.messages.messages : Array.isArray(payload?.messages) ? payload.messages : Array.isArray(payload?.data?.messages?.messages) ? payload.data.messages.messages : Array.isArray(payload?.data?.messages) ? payload.data.messages : Array.isArray(payload) ? payload : [], } } export async function sendGhlConversationMessage( config: GhlMirrorConfig, args: { conversationId?: string contactId?: string message: string type?: string } ) { return await fetchGhlMirrorJson(config, "/conversations/messages", { method: "POST", body: JSON.stringify({ type: args.type || "SMS", message: args.message, conversationId: args.conversationId, contactId: args.contactId, }), }) } export async function fetchGhlCallLogsPage( config: GhlMirrorConfig, args?: { page?: number pageSize?: number } ) { const url = new URL(`${config.baseUrl}/voice-ai/dashboard/call-logs`) url.searchParams.set("locationId", config.locationId) url.searchParams.set("page", String(Math.max(1, args?.page || 1))) url.searchParams.set( "pageSize", String(Math.min(50, Math.max(1, args?.pageSize || 50))) ) const payload = await fetchGhlMirrorJson(config, url.pathname + url.search) return { items: Array.isArray(payload?.callLogs) ? payload.callLogs : [], page: Number(payload?.page || args?.page || 1), total: Number(payload?.total || 0), pageSize: Number(payload?.pageSize || args?.pageSize || 50), } }