Add GoHighLevel CRM sync for tenant locations.

Warehouse leads/deals from GHL contacts and opportunities so Métricas and CRM can use the same scorecard as Clientify.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
4Ventures
2026-10-06 11:57:02 +02:00
parent fb8adab162
commit 487e2c7a2b
12 changed files with 603 additions and 17 deletions

View File

@@ -118,6 +118,7 @@ export async function PATCH(req: NextRequest) {
typeof body.errorMessage === 'string' ? body.errorMessage.trim() : undefined;
const enabled =
typeof body.enabled === 'boolean' ? body.enabled : undefined;
const pit = typeof body.pit === 'string' ? body.pit.trim() : '';
if (!tenantId || !provider) {
return NextResponse.json(
@@ -193,7 +194,23 @@ export async function PATCH(req: NextRequest) {
patch.error_message = null;
}
if (!status && enabled === undefined && externalAccountId === undefined) {
if (provider === 'gohighlevel' && (pit || externalAccountId !== undefined)) {
const cur = await fetch(
`${supabaseUrl()}/rest/v1/integrations?tenant_id=eq.${encodeURIComponent(tenantId)}&provider=eq.gohighlevel&select=meta`,
{ headers, cache: 'no-store' }
);
let meta: Record<string, unknown> = {};
if (cur.ok) {
const rows = (await cur.json()) as { meta?: Record<string, unknown> }[];
if (rows[0]?.meta && typeof rows[0].meta === 'object') meta = { ...rows[0].meta };
}
if (pit) meta.pit = pit;
if (externalAccountId) meta.location_id = externalAccountId;
patch.meta = meta;
if (!label) patch.label = patch.label || 'GoHighLevel';
}
if (!status && enabled === undefined && externalAccountId === undefined && !pit) {
return NextResponse.json(
{ error: 'status, enabled o externalAccountId requeridos' },
{ status: 400 }

View File

@@ -4,6 +4,7 @@ import { isAgencyRole, serviceHeaders, supabaseUrl, userRole } from '@/lib/agenc
import { resolveActiveTenant } from '@/lib/tenant-context';
import { syncAdsForTenants } from '@/lib/ads-sync';
import { syncAllClientifyTenants } from '@/lib/clientify-sync';
import { syncAllGhlTenants } from '@/lib/gohighlevel-sync';
import { syncAllConnectedOrganic } from '@/lib/google-organic';
import {
getAgencyOAuthStatus,
@@ -67,7 +68,15 @@ export async function POST(req: NextRequest) {
try {
if (want('crm') || want('metrics')) {
out.crm = await syncAllClientifyTenants({ tenantId });
const [clientify, gohighlevel] = await Promise.all([
syncAllClientifyTenants({ tenantId }),
syncAllGhlTenants({ tenantId }),
]);
out.crm = {
results: [...clientify.results, ...gohighlevel.results],
clientify,
gohighlevel,
};
}
} catch (e) {
out.crm = {