158 lines
4.7 KiB
TypeScript
158 lines
4.7 KiB
TypeScript
// @ts-nocheck
|
|
import { action, mutation } from "./_generated/server";
|
|
import { v } from "convex/values";
|
|
|
|
const baseLead = {
|
|
firstName: v.string(),
|
|
lastName: v.string(),
|
|
email: v.string(),
|
|
phone: v.string(),
|
|
company: v.optional(v.string()),
|
|
intent: v.optional(v.string()),
|
|
message: v.optional(v.string()),
|
|
source: v.optional(v.string()),
|
|
page: v.optional(v.string()),
|
|
url: v.optional(v.string()),
|
|
serviceTextConsent: v.optional(v.boolean()),
|
|
marketingTextConsent: v.optional(v.boolean()),
|
|
consentVersion: v.optional(v.string()),
|
|
consentCapturedAt: v.optional(v.string()),
|
|
consentSourcePage: v.optional(v.string()),
|
|
};
|
|
|
|
async function sendWebhook(webhookUrl: string | undefined, payload: Record<string, unknown>) {
|
|
if (!webhookUrl) {
|
|
return { success: false, error: "Webhook URL not configured" };
|
|
}
|
|
|
|
const response = await fetch(webhookUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(payload),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
return {
|
|
success: false,
|
|
error: `${response.status} ${response.statusText}`,
|
|
};
|
|
}
|
|
|
|
return { success: true };
|
|
}
|
|
|
|
export const createLead = mutation({
|
|
args: {
|
|
type: v.union(v.literal("contact"), v.literal("requestMachine")),
|
|
firstName: v.string(),
|
|
lastName: v.string(),
|
|
email: v.string(),
|
|
phone: v.string(),
|
|
company: v.optional(v.string()),
|
|
intent: v.optional(v.string()),
|
|
message: v.optional(v.string()),
|
|
source: v.optional(v.string()),
|
|
page: v.optional(v.string()),
|
|
url: v.optional(v.string()),
|
|
employeeCount: v.optional(v.string()),
|
|
machineType: v.optional(v.string()),
|
|
machineCount: v.optional(v.string()),
|
|
serviceTextConsent: v.optional(v.boolean()),
|
|
marketingTextConsent: v.optional(v.boolean()),
|
|
consentVersion: v.optional(v.string()),
|
|
consentCapturedAt: v.optional(v.string()),
|
|
consentSourcePage: v.optional(v.string()),
|
|
marketingConsent: v.optional(v.boolean()),
|
|
termsAgreement: v.optional(v.boolean()),
|
|
status: v.union(v.literal("pending"), v.literal("delivered"), v.literal("failed")),
|
|
error: v.optional(v.string()),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
const now = Date.now();
|
|
return await ctx.db.insert("leadSubmissions", {
|
|
...args,
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
deliveredAt: args.status === "delivered" ? now : undefined,
|
|
});
|
|
},
|
|
});
|
|
|
|
export const submitContact = action({
|
|
args: {
|
|
...baseLead,
|
|
},
|
|
handler: async (ctx, args) => {
|
|
const payload = {
|
|
firstName: args.firstName,
|
|
lastName: args.lastName,
|
|
email: args.email,
|
|
phone: args.phone,
|
|
company: args.company ?? "",
|
|
custom1: args.message ?? "",
|
|
custom2: args.source ?? "website",
|
|
custom3: args.page ?? "",
|
|
custom4: new Date().toISOString(),
|
|
custom5: args.url ?? "",
|
|
custom6: args.intent ?? "",
|
|
custom7: args.serviceTextConsent ? "Consented" : "Not Consented",
|
|
custom8: args.marketingTextConsent ? "Consented" : "Not Consented",
|
|
custom9: args.consentVersion ?? "",
|
|
custom10: args.consentCapturedAt ?? "",
|
|
custom11: args.consentSourcePage ?? "",
|
|
};
|
|
|
|
const result = await sendWebhook(process.env.GHL_CONTACT_WEBHOOK_URL, payload);
|
|
await ctx.runMutation("leads:createLead", {
|
|
type: "contact",
|
|
...args,
|
|
status: result.success ? "delivered" : "failed",
|
|
error: result.error,
|
|
});
|
|
return result;
|
|
},
|
|
});
|
|
|
|
export const submitRequestMachine = action({
|
|
args: {
|
|
...baseLead,
|
|
employeeCount: v.string(),
|
|
machineType: v.string(),
|
|
machineCount: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
const payload = {
|
|
firstName: args.firstName,
|
|
lastName: args.lastName,
|
|
email: args.email,
|
|
phone: args.phone,
|
|
company: args.company ?? "",
|
|
custom1: args.employeeCount,
|
|
custom2: args.machineType,
|
|
custom3: args.machineCount,
|
|
custom4: args.message ?? "",
|
|
custom5: args.source ?? "website",
|
|
custom6: args.page ?? "",
|
|
custom7: new Date().toISOString(),
|
|
custom8: args.url ?? "",
|
|
custom9: args.serviceTextConsent ? "Consented" : "Not Consented",
|
|
custom10: args.marketingTextConsent ? "Consented" : "Not Consented",
|
|
custom11: args.consentVersion ?? "",
|
|
custom12: args.consentCapturedAt ?? "",
|
|
custom13: args.consentSourcePage ?? "",
|
|
custom14: "Free Consultation Request",
|
|
tags: ["Machine Request"],
|
|
};
|
|
|
|
const result = await sendWebhook(process.env.GHL_REQUEST_MACHINE_WEBHOOK_URL, payload);
|
|
await ctx.runMutation("leads:createLead", {
|
|
type: "requestMachine",
|
|
...args,
|
|
status: result.success ? "delivered" : "failed",
|
|
error: result.error,
|
|
});
|
|
return result;
|
|
},
|
|
});
|