99 lines
2.1 KiB
TypeScript
99 lines
2.1 KiB
TypeScript
export type LeadSyncStatus =
|
|
| "pending"
|
|
| "sent"
|
|
| "synced"
|
|
| "failed"
|
|
| "skipped"
|
|
|
|
export type IngestLeadInput = {
|
|
host: string
|
|
tenantSlug?: string
|
|
tenantName?: string
|
|
tenantDomains?: string[]
|
|
source?: string
|
|
idempotencyKey: string
|
|
name: string
|
|
firstName?: string
|
|
lastName?: string
|
|
email: string
|
|
phone: string
|
|
company?: string
|
|
service?: string
|
|
intent?: string
|
|
page?: string
|
|
url?: string
|
|
message: string
|
|
employeeCount?: string
|
|
machineType?: string
|
|
machineCount?: string
|
|
serviceTextConsent?: boolean
|
|
marketingTextConsent?: boolean
|
|
consentVersion?: string
|
|
consentCapturedAt?: string
|
|
consentSourcePage?: string
|
|
}
|
|
|
|
export type IngestLeadResult = {
|
|
inserted: boolean
|
|
leadId: string
|
|
idempotencyKey: string
|
|
tenantId: string
|
|
}
|
|
|
|
function getConvexUrl() {
|
|
return (
|
|
process.env.CONVEX_URL ||
|
|
process.env.NEXT_PUBLIC_CONVEX_URL ||
|
|
""
|
|
).replace(/\/+$/, "")
|
|
}
|
|
|
|
async function callConvex(path: string, args: Record<string, unknown>) {
|
|
const convexUrl = getConvexUrl()
|
|
if (!convexUrl) {
|
|
throw new Error("CONVEX_URL is not configured")
|
|
}
|
|
|
|
const endpoint = `${convexUrl}/api/mutation`
|
|
const response = await fetch(endpoint, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
cache: "no-store",
|
|
body: JSON.stringify({
|
|
path,
|
|
args,
|
|
format: "json",
|
|
}),
|
|
})
|
|
|
|
const body = await response.json().catch(() => null)
|
|
if (!response.ok || body?.status === "error") {
|
|
const message =
|
|
body?.errorMessage || `Convex call failed (${response.status})`
|
|
throw new Error(message)
|
|
}
|
|
|
|
return body?.value
|
|
}
|
|
|
|
export function isConvexConfigured() {
|
|
return getConvexUrl().length > 0
|
|
}
|
|
|
|
export async function ingestLead(
|
|
input: IngestLeadInput
|
|
): Promise<IngestLeadResult> {
|
|
const value = await callConvex("leads:ingestLead", input)
|
|
return value as IngestLeadResult
|
|
}
|
|
|
|
export async function updateLeadSyncStatus(input: {
|
|
leadId: string
|
|
usesendStatus?: LeadSyncStatus
|
|
ghlStatus?: LeadSyncStatus
|
|
error?: string
|
|
}) {
|
|
return await callConvex("leads:updateLeadSyncStatus", input)
|
|
}
|