deploy: harden lead and call notification delivery

This commit is contained in:
DMleadgen 2026-04-20 19:54:10 -06:00
parent 656b78bf8e
commit 78ddcb9146
Signed by: matt
GPG key ID: C2720CF8CD701894
3 changed files with 50 additions and 22 deletions

View file

@ -36,16 +36,31 @@ export async function POST(request: Request) {
const url = new URL(request.url)
const summaryText = buildPhoneCallSummary(detail)
const notificationResult = await sendPhoneCallSummaryEmail({
detail: {
...detail,
call: {
...detail.call,
summaryText,
let notificationResult:
| { status: "pending" | "sent" | "failed" | "disabled"; error?: string }
| undefined
try {
notificationResult = await sendPhoneCallSummaryEmail({
detail: {
...detail,
call: {
...detail.call,
summaryText,
},
},
},
adminUrl: url.origin,
})
adminUrl: url.origin,
})
} catch (notificationError) {
console.error("Failed to send phone call summary email:", notificationError)
notificationResult = {
status: "failed",
error:
notificationError instanceof Error
? notificationError.message
: "Unknown phone call notification error.",
}
}
const result = await fetchMutation(api.voiceSessions.completeSession, {
sessionId: detail.call.id,
@ -58,10 +73,13 @@ export async function POST(request: Request) {
? String(body.recordingError)
: undefined,
summaryText,
notificationStatus: notificationResult.status,
notificationStatus: notificationResult?.status || "failed",
notificationSentAt:
notificationResult.status === "sent" ? Date.now() : undefined,
notificationError: notificationResult.error,
notificationResult?.status === "sent" ? Date.now() : undefined,
notificationError:
notificationResult?.status === "sent"
? undefined
: notificationResult?.error || "Phone call notification did not run.",
})
return NextResponse.json({

View file

@ -1,6 +1,19 @@
const GHL_API_BASE = "https://services.leadconnectorhq.com"
const GHL_API_VERSION = "2021-07-28"
export function getGhlApiToken() {
return (
process.env.GHL_PRIVATE_INTEGRATION_TOKEN ||
process.env.GHL_API_TOKEN ||
""
).trim()
}
export function isGhlConfigured() {
const locationId = (process.env.GHL_LOCATION_ID || "").trim()
return Boolean(locationId && getGhlApiToken())
}
export async function createGHLContact(data: {
email: string
firstName?: string
@ -10,8 +23,8 @@ export async function createGHLContact(data: {
source?: string
tags?: string[]
}) {
const locationId = process.env.GHL_LOCATION_ID
const apiToken = process.env.GHL_API_TOKEN
const locationId = (process.env.GHL_LOCATION_ID || "").trim()
const apiToken = getGhlApiToken()
if (!locationId || !apiToken) {
console.warn("GHL credentials incomplete; skipping contact creation.")

View file

@ -11,7 +11,7 @@ import {
sendTransactionalEmail,
TO_EMAIL,
} from "@/lib/email"
import { createGHLContact } from "@/lib/ghl"
import { createGHLContact, isGhlConfigured } from "@/lib/ghl"
import {
createSmsConsentPayload,
isValidConsentTimestamp,
@ -143,16 +143,10 @@ function getConfiguredTenantDomains() {
}
function defaultDeps(): LeadSubmissionDeps {
const ghlSyncEnabled = String(process.env.ENABLE_GHL_SYNC || "")
.trim()
.toLowerCase() === "true"
return {
storageConfigured: isConvexConfigured(),
emailConfigured: isEmailConfigured(),
ghlConfigured:
ghlSyncEnabled &&
Boolean(process.env.GHL_API_TOKEN && process.env.GHL_LOCATION_ID),
ghlConfigured: isGhlConfigured(),
ingest: ingestLead,
updateLeadStatus: updateLeadSyncStatus,
sendEmail: (to, subject, html, replyTo) =>
@ -635,6 +629,9 @@ export async function processLeadSubmission(
}
} else {
deps.logger.warn("GHL credentials incomplete; skipping Rocky GHL sync.")
warnings.push(
"GHL sync skipped: set GHL_PRIVATE_INTEGRATION_TOKEN (preferred) or GHL_API_TOKEN with GHL_LOCATION_ID."
)
}
if (leadId) {