Files
MP-Manager/n8n/DEPLOYED_backup_20260526_230349.json
2026-05-30 14:31:19 -06:00

3503 lines
122 KiB
JSON

{
"updatedAt": "2026-05-26T09:42:34.301Z",
"createdAt": "2026-03-02T01:12:56.387Z",
"id": "Cfgwp0bOtDW8zuKW",
"name": "Sincronizar Oportunidad - Nodos Nuevos (Create/Update)",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "3eecb45a-e24c-49ac-aef7-99843f485819",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
144,
-16
],
"id": "dd424583-8295-4013-96ba-c7e29ea944c6",
"name": "Webhook",
"webhookId": "3eecb45a-e24c-49ac-aef7-99843f485819"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "8a998fd4-2de6-4895-ab3d-e052e823d1b8",
"name": "Cliente.Fuente Posible Cliente",
"value": "={{ $json.body['Fuente de Posible cliente'] }}",
"type": "string"
},
{
"id": "938c6fec-ae16-4e7a-ba2a-f450794fa40d",
"name": "Cliente.Fecha de creación",
"value": "={{ $json.body.date_created }}",
"type": "string"
},
{
"id": "b56a1939-2608-47c8-85ad-b60b557d2a27",
"name": "Cliente.Sucursal.Sucursal",
"value": "={{ $json.body.Sucursal }}",
"type": "string"
},
{
"id": "0d07b9c9-4450-497b-ab81-3baa441787fb",
"name": "Vehiculo.Versión.Versión",
"value": "={{ $json.body['Version del Vehiculo'] }}",
"type": "string"
},
{
"id": "75e3f337-00d1-429d-8d5b-85ec18e6c5e4",
"name": "Vehiculo.Marca.Marca",
"value": "={{ $json.body['Marca del Vehiculo'] }}",
"type": "string"
},
{
"id": "cb09c536-fe84-4598-aaae-aa79f2eda61b",
"name": "Vehiculo.Marca.fieldKey",
"value": "=contact.marca_del_vehiculo",
"type": "string"
},
{
"id": "17d36409-4c54-48dd-8100-f7f667fd2415",
"name": "Vehiculo.Año.Año",
"value": "={{ $json.body['Año del Vehículo'] }}",
"type": "string"
},
{
"id": "a1886afc-b0af-4950-9752-f8bfff594896",
"name": "Vehiculo.Modalidad.Modalidad",
"value": "={{ $json.body['¿Qué modalidad prefieres?'] }}",
"type": "string"
},
{
"id": "33b2c28a-1ad3-4c74-917f-3cd718a3a709",
"name": "Cliente.Nombre",
"value": "={{ $json.body['Información Adicional'] }}",
"type": "string"
},
{
"id": "b36131ac-2d88-41f8-8f0f-7640cdb02b57",
"name": "Cliente.Apellido",
"value": "={{ $json.body.first_name }}",
"type": "string"
},
{
"id": "ae252c8f-f0a1-41d9-a21d-04ca949f01c8",
"name": "Cliente.Nombre Completo",
"value": "={{ $json.body.full_name }}",
"type": "string"
},
{
"id": "342a9377-0ded-4f23-b93b-1f76e57c0cbd",
"name": "Cliente.Email",
"value": "={{ $json.body.email }}",
"type": "string"
},
{
"id": "cf1b7058-96c2-4c73-9250-719a88b68673",
"name": "Cliente.Telefono",
"value": "={{ $json.body.phone }}",
"type": "string"
},
{
"id": "0b916193-15e8-4a91-9ff2-0a6f262b3c38",
"name": "Cliente.Contact ID",
"value": "={{ $json.body.contact_id }}",
"type": "string"
},
{
"id": "67eeaa9b-f703-4521-82af-9d2797131edc",
"name": "Cliente.Sucursal.fieldKey",
"value": "contact.sucursal",
"type": "string"
},
{
"id": "b05ea7bb-bbaa-467b-8247-eabb162ff029",
"name": "Vehiculo.Versión.fieldKey",
"value": "contact.version_del_vehiculo",
"type": "string"
},
{
"id": "9891b919-ef4c-46bd-8414-6d916565d896",
"name": "Vehiculo.Año.fieldKey",
"value": "contact.ano_del_vehiculo",
"type": "string"
},
{
"id": "0b6bf582-49c1-41de-9c2e-6ae85c4e41e8",
"name": "Vehiculo.Modalidad.fieldKey",
"value": "contact.que_modalidad_prefieres",
"type": "string"
},
{
"id": "b02bc821-6121-452d-a042-623fac6e443c",
"name": "Oportunidad.opportunity_name",
"value": "={{ $json.body.opportunity_name }}",
"type": "string"
},
{
"id": "898817a2-7926-4ddf-b785-cac8e28afc58",
"name": "Oportunidad.pipleline_stage (new)",
"value": "={{ $json.body.pipleline_stage }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
384,
-16
],
"id": "2b3ec130-27ce-4988-82db-46e4f12c3f7d",
"name": "Datos de Lead"
},
{
"parameters": {
"content": "# OBTENER DATOS DE SUCURSAL",
"height": 352,
"width": 992
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1232,
-144
],
"typeVersion": 1,
"id": "19023e33-a9f1-4c60-b87c-957e751e3dc2",
"name": "Sticky Note"
},
{
"parameters": {
"content": "# OBTENER DATOS DE MARCA",
"height": 208,
"width": 1188,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
-80
],
"typeVersion": 1,
"id": "3a3d4f18-1a08-4dbc-a00b-7ae6bc4d49d1",
"name": "Sticky Note1"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "55ff7d12-17b9-4bec-a324-e633020b131d",
"name": "Name Location",
"value": "={{ $json.Nombre }}",
"type": "string"
},
{
"id": "d877c8cd-db32-4c16-96dd-4eeb2dc48efe",
"name": "Location ID",
"value": "={{ $json.Location_ID }}",
"type": "string"
},
{
"id": "7698f395-5db8-415b-919e-3ad61c6566f8",
"name": "Token/API",
"value": "={{ $json.API_token }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2480,
-32
],
"id": "a46df506-6a9a-420d-9cdd-6fc51d1a691e",
"name": "DATOS API"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "44d54b9e-d192-4b54-bf0c-156b79afc6e2",
"leftValue": "={{ $json.Cliente.Email }}",
"rightValue": "@ezcorp.com",
"operator": {
"type": "string",
"operation": "notContains"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
560,
-16
],
"id": "25db982f-7bc7-4318-a7b0-e94326abc437",
"name": "Omitir @ezcorp.com"
},
{
"parameters": {
"method": "PUT",
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3952,
-32
],
"id": "2320b102-816e-4a0c-ae9c-e305d25df6df",
"name": "Actualizar Oportunidad - MARCA2",
"notes": "El código mapea los custom fields de una oportunidad de una sucursal hacia los IDs equivalentes de una marca. Toma tres fuentes: los metadatos de campos de la sucursal, los valores reales de esos campos en la oportunidad, y los metadatos de campos de la marca. Para cada campo con valor en la oportunidad, primero busca su `fieldKey` en los metadatos de la sucursal usando el `id`, luego usa ese `fieldKey` para encontrar el campo equivalente en la marca, y construye un array con el `id` y `key` de la marca pero con el valor original de la sucursal. Finalmente arma el body de una petición para crear/actualizar una oportunidad en la marca, reutilizando pipeline, nombre, stage y valor monetario de otros nodos, con los custom fields ya traducidos al contexto de la marca."
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $json['Location ID'] }}\",\n \"query\": \"{{ $('Datos de Lead').item.json.Oportunidad.opportunity_name }}\",\n \"limit\": 1,\n \"page\": 0\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1344,
-32
],
"id": "4e89658b-7ffd-4a3b-b91e-9ed3223a1a73",
"name": "Buscar Oportunidad - SUCURSAL",
"notes": "NECESITA MEJORAS\n\nActualmente solo hace busqueda con base al NOMBRE DE OPORTUNIDAD.\n\nSe puede optimizar la busqueda futura añadiendo más parametros como valor de oportunidad o datos que sean 100% seguros e inmutables."
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "55ff7d12-17b9-4bec-a324-e633020b131d",
"name": "Name Location",
"value": "={{ $json.Nombre }}",
"type": "string"
},
{
"id": "d877c8cd-db32-4c16-96dd-4eeb2dc48efe",
"name": "Location ID",
"value": "={{ $json.Location_ID }}",
"type": "string"
},
{
"id": "7698f395-5db8-415b-919e-3ad61c6566f8",
"name": "Token/API",
"value": "={{ $json.API_token }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1008,
-32
],
"id": "b721a65d-bcbb-44ab-bb7f-8f200b34fcdd",
"name": "DATOS API - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API - SUCURSAL').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API - SUCURSAL').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1552,
-32
],
"id": "39ef9dcc-ac20-4ba2-b891-2a2baa6ea4f5",
"name": "Conseguir Custom Fields - Opportunity - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Buscar Oportunidad - SUCURSAL').item.json.opportunities[0].id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API - SUCURSAL').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1712,
-32
],
"id": "fbd46ae4-792b-451b-b99e-9816dc175d52",
"name": "Obtener info de Oportunidad - SUCURSAL"
},
{
"parameters": {
"content": "# ACTUALIZAR OPORTUNIDAD - MARCA",
"height": 352,
"width": 928
},
"type": "n8n-nodes-base.stickyNote",
"position": [
3456,
-144
],
"typeVersion": 1,
"id": "f3ca1cfe-08e2-485b-b238-9240f5753809",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "",
"height": 208,
"width": 992,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2768,
-64
],
"typeVersion": 1,
"id": "45066721-8404-48ed-94c1-c88edf48bca5",
"name": "Sticky Note5"
},
{
"parameters": {
"content": "",
"height": 192,
"width": 752,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1280,
-64
],
"typeVersion": 1,
"id": "b1646bb4-8b64-4bf4-b380-189cc7902741",
"name": "Sticky Note7"
},
{
"parameters": {
"databaseId": 63,
"tableId": 749,
"limit": 1,
"additionalOptions": {
"filters": {
"fields": [
{
"field": 7235,
"value": "={{ $('Webhook').item.json.body.location.name }}"
}
]
}
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1.1,
"position": [
800,
-32
],
"id": "12088f29-8bb4-475d-ae0e-2cbdf8033138",
"name": "API de Sucursal",
"credentials": {
"baserowApi": {
"id": "LZztQ3WMpzXjSTIH",
"name": "Baserow account"
}
}
},
{
"parameters": {
"databaseId": 63,
"tableId": 749,
"limit": 1,
"additionalOptions": {
"filters": {
"fields": [
{
"field": 7235,
"value": "=Monte Providencia"
}
]
}
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1.1,
"position": [
2288,
-32
],
"id": "8c8fa238-6ce4-4adf-8926-b603987a55cf",
"name": "API de MARCA",
"credentials": {
"baserowApi": {
"id": "LZztQ3WMpzXjSTIH",
"name": "Baserow account"
}
}
},
{
"parameters": {
"jsCode": "const opportunityData = $('Obtener info de Oportunidad - SUCURSAL').first().json;\nconst opportunity = opportunityData.opportunity;\nconst customFieldsDefs = $('Conseguir Custom Fields - Opportunity - SUCURSAL').first().json.customFields;\nconst pipelines = $input.first().json.pipelines;\n\n// Map custom fields: id -> { fieldKey, name }\nconst fieldMap = {};\nfor (const def of customFieldsDefs) {\n fieldMap[def.id] = { fieldKey: def.fieldKey, name: def.name };\n}\n\n// Map pipelines: id -> name, stages: id -> { name, position, stageWinProbability }\nconst pipelineMap = {};\nconst stageMap = {};\nfor (const pipeline of pipelines) {\n pipelineMap[pipeline.id] = pipeline.name;\n for (const stage of pipeline.stages) {\n stageMap[stage.id] = {\n name: stage.name,\n position: stage.position,\n stageWinProbability: stage.stageWinProbability,\n color: stage.color || null\n };\n }\n}\n\n// Enrich custom fields with fieldKey and name\nconst enrichedCustomFields = opportunity.customFields.map(cf => ({\n id: cf.id,\n name: fieldMap[cf.id]?.name || null,\n fieldKey: fieldMap[cf.id]?.fieldKey || null,\n fieldValue: cf.fieldValue\n}));\n\n// Resolve pipeline and stage info\nconst stageInfo = stageMap[opportunity.pipelineStageId] || {};\n\n// Build enriched opportunity\nconst enrichedOpportunity = {\n ...opportunity,\n pipelineName: pipelineMap[opportunity.pipelineId] || null,\n pipelineStageName: stageInfo.name || null,\n pipelineStagePosition: stageInfo.position ?? null,\n pipelineStageWinProbability: stageInfo.stageWinProbability ?? null,\n pipelineStageColor: stageInfo.color || null,\n customFields: enrichedCustomFields\n};\n\nreturn [{ json: { opportunity: enrichedOpportunity, traceId: opportunityData.traceId } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2080,
-32
],
"id": "d9609dd9-9493-4f3d-b356-99438cedada6",
"name": "Mapeo completo oportunidad origen - SUCURSAL"
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('Webhook').item.json.body.location.id }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('API de Sucursal').item.json.API_token }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1872,
-32
],
"id": "2d799ae3-b6b1-4e4f-8774-714ebe4f009f",
"name": "Obtener Pipelines - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Buscar Oportunidad - MARCA').item.json.opportunities[0].id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
3216,
-32
],
"id": "1eee43d2-c6a8-414b-bebf-4b31d6fb34d7",
"name": "Obtener info de Oportunidad - MARCA"
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('API de MARCA').item.json.Location_ID }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('API de MARCA').item.json.API_token }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
3424,
-32
],
"id": "20a1a288-2cd8-471b-9203-5ba88770edb0",
"name": "Obtener Pipelines - MARCA"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $json['Location ID'] }}\",\n \"query\": \"{{ $('Datos de Lead').item.json.Oportunidad.opportunity_name }}\",\n \"limit\": 1,\n \"page\": 0\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2800,
-32
],
"id": "798a7e51-b8ed-4364-947a-7396fab47940",
"name": "Buscar Oportunidad - MARCA",
"notes": "NECESITA MEJORAS\n\nActualmente solo hace busqueda con base al NOMBRE DE OPORTUNIDAD.\n\nSe puede optimizar la busqueda futura añadiendo más parametros como valor de oportunidad o datos que sean 100% seguros e inmutables."
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3008,
-32
],
"id": "cc37ea9b-0a9f-44ce-8ce2-ee2444822ecf",
"name": "Conseguir Custom Fields - Opportunity - MARCA"
},
{
"parameters": {
"jsCode": "// ── DATOS MARCA ──────────────────────────────────────────────────────────────\nconst marcaOppData = $('Obtener info de Oportunidad - MARCA').first().json;\nconst marcaOpp = marcaOppData.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA').first().json.customFields;\nconst marcaPipelines = $input.first().json.pipelines;\n\n// ── DATOS SUCURSAL (ya enriquecidos) ─────────────────────────────────────────\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\n\n// ── MAP PIPELINES MARCA: name -> { id, stages } ───────────────────────────────\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim()] = stage.id;\n }\n}\n\n// ── RESOLVER PIPELINE Y STAGE POR NAME DESDE SUCURSAL ────────────────────────\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim()] || marcaOpp.pipelineId;\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim()] || marcaOpp.pipelineStageId;\n\n// ── MAP CUSTOM FIELDS SUCURSAL: name -> fieldValue ────────────────────────────\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields) {\n if (cf.name) {\n sucursalValueByName[cf.name.trim()] = cf.fieldValue;\n }\n}\n\n// ── CONSTRUIR CUSTOM FIELDS PARA EL BODY ─────────────────────────────────────\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n const nameKey = def.name.trim();\n const sucursalValue = sucursalValueByName[nameKey];\n const marcaOriginal = marcaOpp.customFields?.find(cf => cf.id === def.id);\n const fieldValue = sucursalValue !== undefined ? sucursalValue : (marcaOriginal?.fieldValue ?? null);\n\n if (fieldValue === null) continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: fieldValue\n });\n}\n\n// ── CONSTRUIR BODY VÁLIDO PARA UPDATE OPPORTUNITY ────────────────────────────\nconst body = {\n pipelineId: resolvedPipelineId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status,\n monetaryValue: sucursalOpp.monetaryValue,\n source: sucursalOpp.source,\n customFields: customFields\n};\n\nreturn [{ json: {\n opportunityId: marcaOpp.id,\n body: JSON.stringify(body)\n} }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3632,
-32
],
"id": "3b547c2a-a541-4b48-8d97-ea2d5df52010",
"name": "Code in JavaScript"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/contacts/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"pageLimit\": 5,\n \"filters\": [\n {\n \"field\": \"email\",\n \"operator\": \"eq\",\n \"value\": \"{{ $('Datos de Lead').item.json.Cliente.Email }}\"\n }\n ]\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3360,
960
],
"id": "02cd0fd6-6bb8-4faa-b85f-5d42663fba29",
"name": "Buscar Contacto en MARCA",
"notes": "Busca contacto en la location de marca por email.\nSi no encuentra, la siguiente IF deriva a creación."
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "exist-contact-check",
"leftValue": "={{ $json.contacts ? $json.contacts.length : 0 }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
3600,
960
],
"id": "aa2644dc-34b4-4159-8afb-89147b12f5ee",
"name": "¿Existe contacto en MARCA?"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/contacts/",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"firstName\": \"{{ $('Datos de Lead').item.json.Cliente.Apellido }}\",\n \"name\": \"{{ $('Datos de Lead').item.json.Cliente['Nombre Completo'] }}\",\n \"email\": \"{{ $('Datos de Lead').item.json.Cliente.Email }}\",\n \"phone\": \"{{ $('Datos de Lead').item.json.Cliente.Telefono }}\",\n \"source\": \"Sincronización Sucursal\",\n \"tags\": [\"sincronizado-sucursal\"]\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3840,
1104
],
"id": "f6c75352-3b9e-4fc9-b8e4-063c2792d190",
"name": "Crear Contacto en MARCA",
"notes": "Crea contacto en la marca solo si no existía.\nIMPORTANTE: revisa el mapeo de Nombre/Apellido, en el workflow original están invertidos."
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "contact-id-resolved",
"name": "contactId",
"value": "={{ $json.contact ? $json.contact.id : $json.contacts[0].id }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
4080,
960
],
"id": "2a49d01e-6679-4584-9d9b-5778dfc4431e",
"name": "Set Contact ID Resuelto",
"notes": "Unifica el contactId tanto si vino de la búsqueda (contacts[0].id) como de la creación (contact.id)."
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"location_id\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"contact_id\": \"{{ $('Set Contact ID Resuelto').item.json.contactId }}\",\n \"limit\": 20,\n \"page\": 1\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
4320,
960
],
"id": "8e25f660-3ed2-4597-9c2a-7480ac7d150f",
"name": "Buscar Oportunidades del Contacto - MARCA",
"notes": "Busca TODAS las oportunidades del contacto en la marca.\nDespués el Code de decisión elige cuál (o crea nueva)."
},
{
"parameters": {
"jsCode": "// ─── DECISIÓN DE MATCHING MULTINIVEL ─────────────────────────────────\n// Input: oportunidades del contacto en la MARCA\n// Output: { action: 'CREATE' | 'UPDATE', opportunityId?, matchReason }\n\nconst result = $input.first().json;\nconst opportunities = result.opportunities || [];\nconst sucursalOppId = $('Buscar Oportunidad - SUCURSAL').first().json.opportunities?.[0]?.id || $('Datos de Lead').first().json.Oportunidad?.opportunity_name;\nconst originTag = `origin-id:${sucursalOppId}`;\n\nlet action = 'CREATE';\nlet opportunityId = null;\nlet matchReason = '';\n\nif (opportunities.length === 0) {\n action = 'CREATE';\n matchReason = 'No hay oportunidades del contacto en marca';\n} else if (opportunities.length === 1) {\n // Match más probable: única oportunidad del contacto en marca\n action = 'UPDATE';\n opportunityId = opportunities[0].id;\n matchReason = 'Única oportunidad del contacto en marca';\n} else {\n // Hay varias: discriminar por tag origin-id\n const withOriginTag = opportunities.find(opp =>\n (opp.tags || []).some(t => t === originTag || t.includes(`origin-id:${sucursalOppId}`))\n );\n if (withOriginTag) {\n action = 'UPDATE';\n opportunityId = withOriginTag.id;\n matchReason = 'Match por tag origin-id';\n } else {\n // Varias oportunidades pero ninguna marcada como origen → crear nueva (más seguro que adivinar)\n action = 'CREATE';\n matchReason = `Hay ${opportunities.length} oportunidades del contacto pero ninguna con tag de origen, se crea nueva`;\n }\n}\n\nreturn [{\n json: {\n action,\n opportunityId,\n matchReason,\n sucursalOppId,\n originTag,\n contactId: $('Set Contact ID Resuelto').first().json.contactId,\n totalOppsContacto: opportunities.length\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
4560,
960
],
"id": "6ca30f13-8503-427f-95ec-b243d30688ec",
"name": "Decidir Match (Create vs Update)"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "switch-update",
"leftValue": "={{ $json.action }}",
"rightValue": "UPDATE",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "UPDATE"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "switch-create",
"leftValue": "={{ $json.action }}",
"rightValue": "CREATE",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "CREATE"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
4800,
960
],
"id": "bff7a5dc-b4af-4033-83ea-c508aa92264a",
"name": "Switch UPDATE vs CREATE"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Decidir Match (Create vs Update)').item.json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
5040,
816
],
"id": "83cd0fd7-1ee9-4896-926e-a0b752e216fe",
"name": "Obtener info de Oportunidad - MARCA (v2)",
"notes": "Sólo se ejecuta en rama UPDATE.\nReemplaza el nodo original 'Obtener info de Oportunidad - MARCA' que dependía de búsqueda por nombre."
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5040,
1104
],
"id": "0fb2fdea-cf40-4dfb-abfa-c422282e5d2a",
"name": "Conseguir Custom Fields - Opportunity - MARCA (CREATE)",
"notes": "Necesitamos los custom fields de la marca también en la rama CREATE para mapear los valores que vienen de sucursal."
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('DATOS API').item.json['Location ID'] }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
5280,
1104
],
"id": "58114758-f0fb-483a-bd5b-d28188880a02",
"name": "Obtener Pipelines - MARCA (CREATE)"
},
{
"parameters": {
"jsCode": "// ─── ARMAR BODY PARA CREAR OPORTUNIDAD EN MARCA ──────────────────────\n// Mapea custom fields por fieldKey (más estable que por name)\n// Resuelve pipeline/stage por nombre desde la oportunidad de sucursal\n\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA (CREATE)').first().json.customFields || [];\nconst marcaPipelines = $('Obtener Pipelines - MARCA (CREATE)').first().json.pipelines || [];\nconst locationId = $('DATOS API').first().json['Location ID'];\nconst decision = $('Decidir Match (Create vs Update)').first().json;\nconst contactId = decision.contactId;\nconst originTag = decision.originTag;\n\n// Map pipelines y stages de la marca por nombre normalizado\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim().toLowerCase()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim().toLowerCase()] = stage.id;\n }\n}\n\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim().toLowerCase()];\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim().toLowerCase()];\n\nif (!resolvedPipelineId) {\n throw new Error(`No se encontró pipeline en marca: \"${sucursalOpp.pipelineName}\". Revisa que el nombre coincida.`);\n}\nif (!resolvedStageId) {\n throw new Error(`No se encontró stage en marca: \"${sucursalOpp.pipelineStageName}\". Revisa que el nombre coincida.`);\n}\n\n// Mapear custom fields: preferir fieldKey (más estable), fallback a name\nconst sucursalValueByFieldKey = {};\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields || []) {\n if (cf.fieldKey) sucursalValueByFieldKey[cf.fieldKey] = cf.fieldValue;\n if (cf.name) sucursalValueByName[cf.name.trim().toLowerCase()] = cf.fieldValue;\n}\n\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n // 1er intento: por fieldKey\n let value = sucursalValueByFieldKey[def.fieldKey];\n // 2do intento: por nombre normalizado\n if (value === undefined && def.name) {\n value = sucursalValueByName[def.name.trim().toLowerCase()];\n }\n if (value === undefined || value === null || value === '') continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: value\n });\n}\n\n// Tags: combinar los que ya tiene la oportunidad de sucursal + tag de origen\nconst existingTags = sucursalOpp.tags || [];\nconst tagsForCreate = Array.from(new Set([...existingTags, originTag]));\n\nconst body = {\n pipelineId: resolvedPipelineId,\n locationId: locationId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status || 'open',\n contactId: contactId,\n monetaryValue: sucursalOpp.monetaryValue,\n source: sucursalOpp.source || 'Sincronización Sucursal',\n tags: tagsForCreate,\n customFields: customFields\n};\n\nreturn [{\n json: {\n body: JSON.stringify(body),\n debug: {\n resolvedPipelineId,\n resolvedStageId,\n customFieldsCount: customFields.length,\n originTag\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5520,
1104
],
"id": "2f9a63e7-277d-49de-8838-a00922c993b2",
"name": "Armar Body - CREATE"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5760,
1104
],
"id": "fc4b3398-91bb-4dd9-b406-96c8d75a17be",
"name": "Crear Oportunidad - MARCA"
},
{
"parameters": {
"jsCode": "// ─── ARMAR BODY PARA ACTUALIZAR OPORTUNIDAD EN MARCA (v2) ────────────\n// Versión mejorada del Code original:\n// 1. Mapea custom fields por fieldKey (preferente) con fallback a name\n// 2. Incluye tag origin-id para idempotencia futura\n// 3. Normaliza pipeline/stage por nombre lowercase + trim\n\nconst marcaOppData = $('Obtener info de Oportunidad - MARCA (v2)').first().json;\nconst marcaOpp = marcaOppData.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA').first().json.customFields || [];\nconst marcaPipelines = $('Obtener Pipelines - MARCA').first().json.pipelines || [];\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\nconst decision = $('Decidir Match (Create vs Update)').first().json;\nconst originTag = decision.originTag;\n\n// Map pipelines/stages marca por nombre normalizado\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim().toLowerCase()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim().toLowerCase()] = stage.id;\n }\n}\n\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim().toLowerCase()] || marcaOpp.pipelineId;\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim().toLowerCase()] || marcaOpp.pipelineStageId;\n\n// Map sucursal: por fieldKey y por name\nconst sucursalValueByFieldKey = {};\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields || []) {\n if (cf.fieldKey) sucursalValueByFieldKey[cf.fieldKey] = cf.fieldValue;\n if (cf.name) sucursalValueByName[cf.name.trim().toLowerCase()] = cf.fieldValue;\n}\n\n// Construir custom fields del body\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n let value = sucursalValueByFieldKey[def.fieldKey];\n if (value === undefined && def.name) {\n value = sucursalValueByName[def.name.trim().toLowerCase()];\n }\n // Fallback: mantener valor original que tenía la oportunidad de marca\n if (value === undefined || value === null) {\n const marcaOriginal = marcaOpp.customFields?.find(cf => cf.id === def.id);\n value = marcaOriginal?.fieldValue;\n }\n if (value === undefined || value === null) continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: value\n });\n}\n\n// Tags: preservar los de marca + agregar origin-id\nconst existingTags = marcaOpp.tags || [];\nconst tagsForUpdate = Array.from(new Set([...existingTags, originTag]));\n\nconst body = {\n pipelineId: resolvedPipelineId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status || marcaOpp.status,\n monetaryValue: sucursalOpp.monetaryValue ?? marcaOpp.monetaryValue,\n source: sucursalOpp.source || marcaOpp.source,\n tags: tagsForUpdate,\n customFields: customFields\n};\n\nreturn [{\n json: {\n opportunityId: marcaOpp.id,\n body: JSON.stringify(body),\n debug: {\n matchReason: decision.matchReason,\n customFieldsCount: customFields.length\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5280,
816
],
"id": "969e46cd-bbae-4372-9808-c939f63e3c02",
"name": "Armar Body - UPDATE (v2)"
},
{
"parameters": {
"method": "PUT",
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5520,
816
],
"id": "83929e08-7afd-4670-9c18-be22b8c3656f",
"name": "Actualizar Oportunidad - MARCA (v2)"
},
{
"parameters": {
"content": "# RAMA UPDATE\n## Oportunidad ya existe en marca → se actualiza",
"height": 280,
"width": 880,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
5008,
720
],
"typeVersion": 1,
"id": "1c285234-8d90-49ef-8dac-c98cb379299a",
"name": "Sticky Update"
},
{
"parameters": {
"content": "# RAMA CREATE\n## Oportunidad no existe en marca → se crea desde cero\n### Incluye contacto + custom fields + tag origin-id",
"height": 280,
"width": 1120,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"position": [
5008,
1024
],
"typeVersion": 1,
"id": "7e8f350c-9562-485b-8ce5-1b13b4086856",
"name": "Sticky Create"
},
{
"parameters": {
"content": "# MATCHING ROBUSTO\n## 1. Buscar/crear contacto en marca\n## 2. Buscar oportunidades DEL CONTACTO\n## 3. Decidir match por cantidad + tag origin-id",
"height": 320,
"width": 1500,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"position": [
3328,
864
],
"typeVersion": 1,
"id": "8a583e46-41b6-44e0-9313-b70ee085b740",
"name": "Sticky Matching"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Datos de Lead",
"type": "main",
"index": 0
}
]
]
},
"Datos de Lead": {
"main": [
[
{
"node": "Omitir @ezcorp.com",
"type": "main",
"index": 0
}
]
]
},
"DATOS API": {
"main": [
[
{
"node": "Buscar Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Omitir @ezcorp.com": {
"main": [
[
{
"node": "API de Sucursal",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidad - SUCURSAL": {
"main": [
[
{
"node": "Conseguir Custom Fields - Opportunity - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"DATOS API - SUCURSAL": {
"main": [
[
{
"node": "Buscar Oportunidad - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - SUCURSAL": {
"main": [
[
{
"node": "Obtener info de Oportunidad - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - SUCURSAL": {
"main": [
[
{
"node": "Obtener Pipelines - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"API de Sucursal": {
"main": [
[
{
"node": "DATOS API - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"API de MARCA": {
"main": [
[
{
"node": "DATOS API",
"type": "main",
"index": 0
}
]
]
},
"Mapeo completo oportunidad origen - SUCURSAL": {
"main": [
[
{
"node": "API de MARCA",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - SUCURSAL": {
"main": [
[
{
"node": "Mapeo completo oportunidad origen - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - MARCA": {
"main": [
[
{
"node": "Obtener Pipelines - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - MARCA": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidad - MARCA": {
"main": [
[
{
"node": "Conseguir Custom Fields - Opportunity - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - MARCA": {
"main": [
[
{
"node": "Obtener info de Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Actualizar Oportunidad - MARCA2",
"type": "main",
"index": 0
}
]
]
},
"Buscar Contacto en MARCA": {
"main": [
[
{
"node": "¿Existe contacto en MARCA?",
"type": "main",
"index": 0
}
]
]
},
"¿Existe contacto en MARCA?": {
"main": [
[
{
"node": "Set Contact ID Resuelto",
"type": "main",
"index": 0
}
],
[
{
"node": "Crear Contacto en MARCA",
"type": "main",
"index": 0
}
]
]
},
"Crear Contacto en MARCA": {
"main": [
[
{
"node": "Set Contact ID Resuelto",
"type": "main",
"index": 0
}
]
]
},
"Set Contact ID Resuelto": {
"main": [
[
{
"node": "Buscar Oportunidades del Contacto - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidades del Contacto - MARCA": {
"main": [
[
{
"node": "Decidir Match (Create vs Update)",
"type": "main",
"index": 0
}
]
]
},
"Decidir Match (Create vs Update)": {
"main": [
[
{
"node": "Switch UPDATE vs CREATE",
"type": "main",
"index": 0
}
]
]
},
"Switch UPDATE vs CREATE": {
"main": [
[
{
"node": "Obtener info de Oportunidad - MARCA (v2)",
"type": "main",
"index": 0
}
],
[
{
"node": "Conseguir Custom Fields - Opportunity - MARCA (CREATE)",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - MARCA (v2)": {
"main": [
[
{
"node": "Armar Body - UPDATE (v2)",
"type": "main",
"index": 0
}
]
]
},
"Armar Body - UPDATE (v2)": {
"main": [
[
{
"node": "Actualizar Oportunidad - MARCA (v2)",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - MARCA (CREATE)": {
"main": [
[
{
"node": "Obtener Pipelines - MARCA (CREATE)",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - MARCA (CREATE)": {
"main": [
[
{
"node": "Armar Body - CREATE",
"type": "main",
"index": 0
}
]
]
},
"Armar Body - CREATE": {
"main": [
[
{
"node": "Crear Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"staticData": null,
"meta": {
"templateCredsSetupCompleted": true
},
"pinData": {
"Webhook": [
{
"json": {
"headers": {
"host": "webhookn8.consultoriae3.com",
"user-agent": "axios/1.13.2",
"content-length": "1220",
"accept": "application/json, text/plain, */*",
"accept-encoding": "gzip, compress, deflate, br",
"content-type": "application/json",
"traceparent": "00-7f85eca8d34c73a29d9f986235cf8ef6-a33140ec25c69ebd-01",
"x-forwarded-for": "34.42.159.131",
"x-forwarded-host": "webhookn8.consultoriae3.com",
"x-forwarded-port": "443",
"x-forwarded-proto": "https",
"x-forwarded-server": "f569f6e85d30",
"x-real-ip": "34.42.159.131"
},
"params": {},
"query": {},
"body": {
"contact_id": "QE9sYvlc3zSnn0qhzZaX",
"first_name": "javier",
"last_name": "rodriguez bernal",
"full_name": "javier rodriguez bernal",
"phone": "+524521277210",
"tags": "sucursal",
"country": "MX",
"timezone": "America/Mexico_City",
"date_created": "2026-04-10T18:47:52.272Z",
"company_name": "agricultor",
"full_address": "",
"contact_type": "customer",
"opportunity_name": "Javier Rodriguez Bernal",
"status": "open",
"lead_value": 90000,
"opportunity_source": "cliente del valuador",
"source": "cliente del valuador",
"pipleline_stage": "En Pausa",
"pipeline_id": "RwcmZZuNB0WSmoqYKzwk",
"id": "ADVtIkKepfl1Pctm8jlp",
"pipeline_name": "Standar",
"user": {
"firstName": "Uruapan - 85966",
"lastName": "Uruapan",
"email": "ezstore85966@ezcorp.com"
},
"owner": "Uruapan - 85966 Uruapan",
"location": {
"name": "85966 - MP - Uruapan",
"address": "Uruapan",
"city": "Uruapan",
"state": "Michoacán",
"country": "MX",
"postalCode": "60000",
"fullAddress": "Uruapan, Uruapan Michoacán 60000",
"id": "FoQWuksh4wQjPbVVZ8ZQ"
},
"workflow": {
"id": "2108d5d2-a622-4761-b961-fa9ef9f20a55",
"name": "Sincronizar Oportunidad V2"
},
"triggerData": {},
"contact": {
"attributionSource": {
"sessionSource": "CRM UI",
"medium": "manual",
"mediumId": null
},
"lastAttributionSource": {}
},
"attributionSource": {},
"customData": {}
},
"webhookUrl": "https://webhookn8.consultoriae3.com/webhook/3eecb45a-e24c-49ac-aef7-99843f485819",
"executionMode": "production"
},
"pairedItem": {
"item": 0
}
}
]
},
"versionId": "9f358327-31aa-48d8-a188-e48332b62600",
"activeVersionId": "9f358327-31aa-48d8-a188-e48332b62600",
"versionCounter": 391,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-03-02T01:12:56.387Z",
"createdAt": "2026-03-02T01:12:56.387Z",
"role": "workflow:owner",
"workflowId": "Cfgwp0bOtDW8zuKW",
"projectId": "aycNlMpnzsxvXbfG",
"project": {
"updatedAt": "2025-11-27T04:06:26.313Z",
"createdAt": "2025-11-27T03:54:24.410Z",
"id": "aycNlMpnzsxvXbfG",
"name": "Consultoria E3 ® <hola@consultoriae3.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "74a7f127-b963-4eb0-aff4-1190428e8409"
}
}
],
"tags": [
{
"updatedAt": "2025-11-27T05:48:12.272Z",
"createdAt": "2025-11-27T05:48:12.272Z",
"id": "pHkPpq3Httzx4hnb",
"name": "Bucefalo"
}
],
"activeVersion": {
"updatedAt": "2026-05-26T09:42:35.735Z",
"createdAt": "2026-05-26T09:42:34.305Z",
"versionId": "9f358327-31aa-48d8-a188-e48332b62600",
"workflowId": "Cfgwp0bOtDW8zuKW",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "3eecb45a-e24c-49ac-aef7-99843f485819",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
144,
-16
],
"id": "dd424583-8295-4013-96ba-c7e29ea944c6",
"name": "Webhook",
"webhookId": "3eecb45a-e24c-49ac-aef7-99843f485819"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "8a998fd4-2de6-4895-ab3d-e052e823d1b8",
"name": "Cliente.Fuente Posible Cliente",
"value": "={{ $json.body['Fuente de Posible cliente'] }}",
"type": "string"
},
{
"id": "938c6fec-ae16-4e7a-ba2a-f450794fa40d",
"name": "Cliente.Fecha de creación",
"value": "={{ $json.body.date_created }}",
"type": "string"
},
{
"id": "b56a1939-2608-47c8-85ad-b60b557d2a27",
"name": "Cliente.Sucursal.Sucursal",
"value": "={{ $json.body.Sucursal }}",
"type": "string"
},
{
"id": "0d07b9c9-4450-497b-ab81-3baa441787fb",
"name": "Vehiculo.Versión.Versión",
"value": "={{ $json.body['Version del Vehiculo'] }}",
"type": "string"
},
{
"id": "75e3f337-00d1-429d-8d5b-85ec18e6c5e4",
"name": "Vehiculo.Marca.Marca",
"value": "={{ $json.body['Marca del Vehiculo'] }}",
"type": "string"
},
{
"id": "cb09c536-fe84-4598-aaae-aa79f2eda61b",
"name": "Vehiculo.Marca.fieldKey",
"value": "=contact.marca_del_vehiculo",
"type": "string"
},
{
"id": "17d36409-4c54-48dd-8100-f7f667fd2415",
"name": "Vehiculo.Año.Año",
"value": "={{ $json.body['Año del Vehículo'] }}",
"type": "string"
},
{
"id": "a1886afc-b0af-4950-9752-f8bfff594896",
"name": "Vehiculo.Modalidad.Modalidad",
"value": "={{ $json.body['¿Qué modalidad prefieres?'] }}",
"type": "string"
},
{
"id": "33b2c28a-1ad3-4c74-917f-3cd718a3a709",
"name": "Cliente.Nombre",
"value": "={{ $json.body['Información Adicional'] }}",
"type": "string"
},
{
"id": "b36131ac-2d88-41f8-8f0f-7640cdb02b57",
"name": "Cliente.Apellido",
"value": "={{ $json.body.first_name }}",
"type": "string"
},
{
"id": "ae252c8f-f0a1-41d9-a21d-04ca949f01c8",
"name": "Cliente.Nombre Completo",
"value": "={{ $json.body.full_name }}",
"type": "string"
},
{
"id": "342a9377-0ded-4f23-b93b-1f76e57c0cbd",
"name": "Cliente.Email",
"value": "={{ $json.body.email }}",
"type": "string"
},
{
"id": "cf1b7058-96c2-4c73-9250-719a88b68673",
"name": "Cliente.Telefono",
"value": "={{ $json.body.phone }}",
"type": "string"
},
{
"id": "0b916193-15e8-4a91-9ff2-0a6f262b3c38",
"name": "Cliente.Contact ID",
"value": "={{ $json.body.contact_id }}",
"type": "string"
},
{
"id": "67eeaa9b-f703-4521-82af-9d2797131edc",
"name": "Cliente.Sucursal.fieldKey",
"value": "contact.sucursal",
"type": "string"
},
{
"id": "b05ea7bb-bbaa-467b-8247-eabb162ff029",
"name": "Vehiculo.Versión.fieldKey",
"value": "contact.version_del_vehiculo",
"type": "string"
},
{
"id": "9891b919-ef4c-46bd-8414-6d916565d896",
"name": "Vehiculo.Año.fieldKey",
"value": "contact.ano_del_vehiculo",
"type": "string"
},
{
"id": "0b6bf582-49c1-41de-9c2e-6ae85c4e41e8",
"name": "Vehiculo.Modalidad.fieldKey",
"value": "contact.que_modalidad_prefieres",
"type": "string"
},
{
"id": "b02bc821-6121-452d-a042-623fac6e443c",
"name": "Oportunidad.opportunity_name",
"value": "={{ $json.body.opportunity_name }}",
"type": "string"
},
{
"id": "898817a2-7926-4ddf-b785-cac8e28afc58",
"name": "Oportunidad.pipleline_stage (new)",
"value": "={{ $json.body.pipleline_stage }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
384,
-16
],
"id": "2b3ec130-27ce-4988-82db-46e4f12c3f7d",
"name": "Datos de Lead"
},
{
"parameters": {
"content": "# OBTENER DATOS DE SUCURSAL",
"height": 352,
"width": 992
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1232,
-144
],
"typeVersion": 1,
"id": "19023e33-a9f1-4c60-b87c-957e751e3dc2",
"name": "Sticky Note"
},
{
"parameters": {
"content": "# OBTENER DATOS DE MARCA",
"height": 208,
"width": 1188,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2240,
-80
],
"typeVersion": 1,
"id": "3a3d4f18-1a08-4dbc-a00b-7ae6bc4d49d1",
"name": "Sticky Note1"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "55ff7d12-17b9-4bec-a324-e633020b131d",
"name": "Name Location",
"value": "={{ $json.Nombre }}",
"type": "string"
},
{
"id": "d877c8cd-db32-4c16-96dd-4eeb2dc48efe",
"name": "Location ID",
"value": "={{ $json.Location_ID }}",
"type": "string"
},
{
"id": "7698f395-5db8-415b-919e-3ad61c6566f8",
"name": "Token/API",
"value": "={{ $json.API_token }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
2480,
-32
],
"id": "a46df506-6a9a-420d-9cdd-6fc51d1a691e",
"name": "DATOS API"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "44d54b9e-d192-4b54-bf0c-156b79afc6e2",
"leftValue": "={{ $json.Cliente.Email }}",
"rightValue": "@ezcorp.com",
"operator": {
"type": "string",
"operation": "notContains"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
560,
-16
],
"id": "25db982f-7bc7-4318-a7b0-e94326abc437",
"name": "Omitir @ezcorp.com"
},
{
"parameters": {
"method": "PUT",
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3952,
-32
],
"id": "2320b102-816e-4a0c-ae9c-e305d25df6df",
"name": "Actualizar Oportunidad - MARCA2",
"notes": "El código mapea los custom fields de una oportunidad de una sucursal hacia los IDs equivalentes de una marca. Toma tres fuentes: los metadatos de campos de la sucursal, los valores reales de esos campos en la oportunidad, y los metadatos de campos de la marca. Para cada campo con valor en la oportunidad, primero busca su `fieldKey` en los metadatos de la sucursal usando el `id`, luego usa ese `fieldKey` para encontrar el campo equivalente en la marca, y construye un array con el `id` y `key` de la marca pero con el valor original de la sucursal. Finalmente arma el body de una petición para crear/actualizar una oportunidad en la marca, reutilizando pipeline, nombre, stage y valor monetario de otros nodos, con los custom fields ya traducidos al contexto de la marca."
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $json['Location ID'] }}\",\n \"query\": \"{{ $('Datos de Lead').item.json.Oportunidad.opportunity_name }}\",\n \"limit\": 1,\n \"page\": 0\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1344,
-32
],
"id": "4e89658b-7ffd-4a3b-b91e-9ed3223a1a73",
"name": "Buscar Oportunidad - SUCURSAL",
"notes": "NECESITA MEJORAS\n\nActualmente solo hace busqueda con base al NOMBRE DE OPORTUNIDAD.\n\nSe puede optimizar la busqueda futura añadiendo más parametros como valor de oportunidad o datos que sean 100% seguros e inmutables."
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "55ff7d12-17b9-4bec-a324-e633020b131d",
"name": "Name Location",
"value": "={{ $json.Nombre }}",
"type": "string"
},
{
"id": "d877c8cd-db32-4c16-96dd-4eeb2dc48efe",
"name": "Location ID",
"value": "={{ $json.Location_ID }}",
"type": "string"
},
{
"id": "7698f395-5db8-415b-919e-3ad61c6566f8",
"name": "Token/API",
"value": "={{ $json.API_token }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1008,
-32
],
"id": "b721a65d-bcbb-44ab-bb7f-8f200b34fcdd",
"name": "DATOS API - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API - SUCURSAL').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API - SUCURSAL').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1552,
-32
],
"id": "39ef9dcc-ac20-4ba2-b891-2a2baa6ea4f5",
"name": "Conseguir Custom Fields - Opportunity - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Buscar Oportunidad - SUCURSAL').item.json.opportunities[0].id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API - SUCURSAL').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1712,
-32
],
"id": "fbd46ae4-792b-451b-b99e-9816dc175d52",
"name": "Obtener info de Oportunidad - SUCURSAL"
},
{
"parameters": {
"content": "# ACTUALIZAR OPORTUNIDAD - MARCA",
"height": 352,
"width": 928
},
"type": "n8n-nodes-base.stickyNote",
"position": [
3456,
-144
],
"typeVersion": 1,
"id": "f3ca1cfe-08e2-485b-b238-9240f5753809",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "",
"height": 208,
"width": 992,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
2768,
-64
],
"typeVersion": 1,
"id": "45066721-8404-48ed-94c1-c88edf48bca5",
"name": "Sticky Note5"
},
{
"parameters": {
"content": "",
"height": 192,
"width": 752,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"position": [
1280,
-64
],
"typeVersion": 1,
"id": "b1646bb4-8b64-4bf4-b380-189cc7902741",
"name": "Sticky Note7"
},
{
"parameters": {
"databaseId": 63,
"tableId": 749,
"limit": 1,
"additionalOptions": {
"filters": {
"fields": [
{
"field": 7235,
"value": "={{ $('Webhook').item.json.body.location.name }}"
}
]
}
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1.1,
"position": [
800,
-32
],
"id": "12088f29-8bb4-475d-ae0e-2cbdf8033138",
"name": "API de Sucursal",
"credentials": {
"baserowApi": {
"id": "LZztQ3WMpzXjSTIH",
"name": "Baserow account"
}
}
},
{
"parameters": {
"databaseId": 63,
"tableId": 749,
"limit": 1,
"additionalOptions": {
"filters": {
"fields": [
{
"field": 7235,
"value": "=Monte Providencia"
}
]
}
}
},
"type": "n8n-nodes-base.baserow",
"typeVersion": 1.1,
"position": [
2288,
-32
],
"id": "8c8fa238-6ce4-4adf-8926-b603987a55cf",
"name": "API de MARCA",
"credentials": {
"baserowApi": {
"id": "LZztQ3WMpzXjSTIH",
"name": "Baserow account"
}
}
},
{
"parameters": {
"jsCode": "const opportunityData = $('Obtener info de Oportunidad - SUCURSAL').first().json;\nconst opportunity = opportunityData.opportunity;\nconst customFieldsDefs = $('Conseguir Custom Fields - Opportunity - SUCURSAL').first().json.customFields;\nconst pipelines = $input.first().json.pipelines;\n\n// Map custom fields: id -> { fieldKey, name }\nconst fieldMap = {};\nfor (const def of customFieldsDefs) {\n fieldMap[def.id] = { fieldKey: def.fieldKey, name: def.name };\n}\n\n// Map pipelines: id -> name, stages: id -> { name, position, stageWinProbability }\nconst pipelineMap = {};\nconst stageMap = {};\nfor (const pipeline of pipelines) {\n pipelineMap[pipeline.id] = pipeline.name;\n for (const stage of pipeline.stages) {\n stageMap[stage.id] = {\n name: stage.name,\n position: stage.position,\n stageWinProbability: stage.stageWinProbability,\n color: stage.color || null\n };\n }\n}\n\n// Enrich custom fields with fieldKey and name\nconst enrichedCustomFields = opportunity.customFields.map(cf => ({\n id: cf.id,\n name: fieldMap[cf.id]?.name || null,\n fieldKey: fieldMap[cf.id]?.fieldKey || null,\n fieldValue: cf.fieldValue\n}));\n\n// Resolve pipeline and stage info\nconst stageInfo = stageMap[opportunity.pipelineStageId] || {};\n\n// Build enriched opportunity\nconst enrichedOpportunity = {\n ...opportunity,\n pipelineName: pipelineMap[opportunity.pipelineId] || null,\n pipelineStageName: stageInfo.name || null,\n pipelineStagePosition: stageInfo.position ?? null,\n pipelineStageWinProbability: stageInfo.stageWinProbability ?? null,\n pipelineStageColor: stageInfo.color || null,\n customFields: enrichedCustomFields\n};\n\nreturn [{ json: { opportunity: enrichedOpportunity, traceId: opportunityData.traceId } }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2080,
-32
],
"id": "d9609dd9-9493-4f3d-b356-99438cedada6",
"name": "Mapeo completo oportunidad origen - SUCURSAL"
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('Webhook').item.json.body.location.id }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('API de Sucursal').item.json.API_token }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
1872,
-32
],
"id": "2d799ae3-b6b1-4e4f-8774-714ebe4f009f",
"name": "Obtener Pipelines - SUCURSAL"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Buscar Oportunidad - MARCA').item.json.opportunities[0].id }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
3216,
-32
],
"id": "1eee43d2-c6a8-414b-bebf-4b31d6fb34d7",
"name": "Obtener info de Oportunidad - MARCA"
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('API de MARCA').item.json.Location_ID }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('API de MARCA').item.json.API_token }}"
}
]
},
"sendBody": true,
"bodyParameters": {
"parameters": [
{}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
3424,
-32
],
"id": "20a1a288-2cd8-471b-9203-5ba88770edb0",
"name": "Obtener Pipelines - MARCA"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $json['Location ID'] }}\",\n \"query\": \"{{ $('Datos de Lead').item.json.Oportunidad.opportunity_name }}\",\n \"limit\": 1,\n \"page\": 0\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2800,
-32
],
"id": "798a7e51-b8ed-4364-947a-7396fab47940",
"name": "Buscar Oportunidad - MARCA",
"notes": "NECESITA MEJORAS\n\nActualmente solo hace busqueda con base al NOMBRE DE OPORTUNIDAD.\n\nSe puede optimizar la busqueda futura añadiendo más parametros como valor de oportunidad o datos que sean 100% seguros e inmutables."
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3008,
-32
],
"id": "cc37ea9b-0a9f-44ce-8ce2-ee2444822ecf",
"name": "Conseguir Custom Fields - Opportunity - MARCA"
},
{
"parameters": {
"jsCode": "// ── DATOS MARCA ──────────────────────────────────────────────────────────────\nconst marcaOppData = $('Obtener info de Oportunidad - MARCA').first().json;\nconst marcaOpp = marcaOppData.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA').first().json.customFields;\nconst marcaPipelines = $input.first().json.pipelines;\n\n// ── DATOS SUCURSAL (ya enriquecidos) ─────────────────────────────────────────\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\n\n// ── MAP PIPELINES MARCA: name -> { id, stages } ───────────────────────────────\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim()] = stage.id;\n }\n}\n\n// ── RESOLVER PIPELINE Y STAGE POR NAME DESDE SUCURSAL ────────────────────────\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim()] || marcaOpp.pipelineId;\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim()] || marcaOpp.pipelineStageId;\n\n// ── MAP CUSTOM FIELDS SUCURSAL: name -> fieldValue ────────────────────────────\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields) {\n if (cf.name) {\n sucursalValueByName[cf.name.trim()] = cf.fieldValue;\n }\n}\n\n// ── CONSTRUIR CUSTOM FIELDS PARA EL BODY ─────────────────────────────────────\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n const nameKey = def.name.trim();\n const sucursalValue = sucursalValueByName[nameKey];\n const marcaOriginal = marcaOpp.customFields?.find(cf => cf.id === def.id);\n const fieldValue = sucursalValue !== undefined ? sucursalValue : (marcaOriginal?.fieldValue ?? null);\n\n if (fieldValue === null) continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: fieldValue\n });\n}\n\n// ── CONSTRUIR BODY VÁLIDO PARA UPDATE OPPORTUNITY ────────────────────────────\nconst body = {\n pipelineId: resolvedPipelineId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status,\n monetaryValue: sucursalOpp.monetaryValue,\n source: sucursalOpp.source,\n customFields: customFields\n};\n\nreturn [{ json: {\n opportunityId: marcaOpp.id,\n body: JSON.stringify(body)\n} }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3632,
-32
],
"id": "3b547c2a-a541-4b48-8d97-ea2d5df52010",
"name": "Code in JavaScript"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/contacts/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"pageLimit\": 5,\n \"filters\": [\n {\n \"field\": \"email\",\n \"operator\": \"eq\",\n \"value\": \"{{ $('Datos de Lead').item.json.Cliente.Email }}\"\n }\n ]\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3360,
960
],
"id": "02cd0fd6-6bb8-4faa-b85f-5d42663fba29",
"name": "Buscar Contacto en MARCA",
"notes": "Busca contacto en la location de marca por email.\nSi no encuentra, la siguiente IF deriva a creación."
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "exist-contact-check",
"leftValue": "={{ $json.contacts ? $json.contacts.length : 0 }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
3600,
960
],
"id": "aa2644dc-34b4-4159-8afb-89147b12f5ee",
"name": "¿Existe contacto en MARCA?"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/contacts/",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"locationId\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"firstName\": \"{{ $('Datos de Lead').item.json.Cliente.Apellido }}\",\n \"name\": \"{{ $('Datos de Lead').item.json.Cliente['Nombre Completo'] }}\",\n \"email\": \"{{ $('Datos de Lead').item.json.Cliente.Email }}\",\n \"phone\": \"{{ $('Datos de Lead').item.json.Cliente.Telefono }}\",\n \"source\": \"Sincronización Sucursal\",\n \"tags\": [\"sincronizado-sucursal\"]\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3840,
1104
],
"id": "f6c75352-3b9e-4fc9-b8e4-063c2792d190",
"name": "Crear Contacto en MARCA",
"notes": "Crea contacto en la marca solo si no existía.\nIMPORTANTE: revisa el mapeo de Nombre/Apellido, en el workflow original están invertidos."
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "contact-id-resolved",
"name": "contactId",
"value": "={{ $json.contact ? $json.contact.id : $json.contacts[0].id }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
4080,
960
],
"id": "2a49d01e-6679-4584-9d9b-5778dfc4431e",
"name": "Set Contact ID Resuelto",
"notes": "Unifica el contactId tanto si vino de la búsqueda (contacts[0].id) como de la creación (contact.id)."
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/search",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"location_id\": \"{{ $('DATOS API').item.json['Location ID'] }}\",\n \"contact_id\": \"{{ $('Set Contact ID Resuelto').item.json.contactId }}\",\n \"limit\": 20,\n \"page\": 1\n}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
4320,
960
],
"id": "8e25f660-3ed2-4597-9c2a-7480ac7d150f",
"name": "Buscar Oportunidades del Contacto - MARCA",
"notes": "Busca TODAS las oportunidades del contacto en la marca.\nDespués el Code de decisión elige cuál (o crea nueva)."
},
{
"parameters": {
"jsCode": "// ─── DECISIÓN DE MATCHING MULTINIVEL ─────────────────────────────────\n// Input: oportunidades del contacto en la MARCA\n// Output: { action: 'CREATE' | 'UPDATE', opportunityId?, matchReason }\n\nconst result = $input.first().json;\nconst opportunities = result.opportunities || [];\nconst sucursalOppId = $('Buscar Oportunidad - SUCURSAL').first().json.opportunities?.[0]?.id || $('Datos de Lead').first().json.Oportunidad?.opportunity_name;\nconst originTag = `origin-id:${sucursalOppId}`;\n\nlet action = 'CREATE';\nlet opportunityId = null;\nlet matchReason = '';\n\nif (opportunities.length === 0) {\n action = 'CREATE';\n matchReason = 'No hay oportunidades del contacto en marca';\n} else if (opportunities.length === 1) {\n // Match más probable: única oportunidad del contacto en marca\n action = 'UPDATE';\n opportunityId = opportunities[0].id;\n matchReason = 'Única oportunidad del contacto en marca';\n} else {\n // Hay varias: discriminar por tag origin-id\n const withOriginTag = opportunities.find(opp =>\n (opp.tags || []).some(t => t === originTag || t.includes(`origin-id:${sucursalOppId}`))\n );\n if (withOriginTag) {\n action = 'UPDATE';\n opportunityId = withOriginTag.id;\n matchReason = 'Match por tag origin-id';\n } else {\n // Varias oportunidades pero ninguna marcada como origen → crear nueva (más seguro que adivinar)\n action = 'CREATE';\n matchReason = `Hay ${opportunities.length} oportunidades del contacto pero ninguna con tag de origen, se crea nueva`;\n }\n}\n\nreturn [{\n json: {\n action,\n opportunityId,\n matchReason,\n sucursalOppId,\n originTag,\n contactId: $('Set Contact ID Resuelto').first().json.contactId,\n totalOppsContacto: opportunities.length\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
4560,
960
],
"id": "6ca30f13-8503-427f-95ec-b243d30688ec",
"name": "Decidir Match (Create vs Update)"
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "switch-update",
"leftValue": "={{ $json.action }}",
"rightValue": "UPDATE",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "UPDATE"
},
{
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "switch-create",
"leftValue": "={{ $json.action }}",
"rightValue": "CREATE",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "CREATE"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
4800,
960
],
"id": "bff7a5dc-b4af-4033-83ea-c508aa92264a",
"name": "Switch UPDATE vs CREATE"
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $('Decidir Match (Create vs Update)').item.json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
5040,
816
],
"id": "83cd0fd7-1ee9-4896-926e-a0b752e216fe",
"name": "Obtener info de Oportunidad - MARCA (v2)",
"notes": "Sólo se ejecuta en rama UPDATE.\nReemplaza el nodo original 'Obtener info de Oportunidad - MARCA' que dependía de búsqueda por nombre."
},
{
"parameters": {
"url": "=https://services.leadconnectorhq.com/locations/{{ $('DATOS API').item.json['Location ID'] }}/customFields",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "model",
"value": "opportunity"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {
"redirect": {
"redirect": {
"maxRedirects": 90
}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5040,
1104
],
"id": "0fb2fdea-cf40-4dfb-abfa-c422282e5d2a",
"name": "Conseguir Custom Fields - Opportunity - MARCA (CREATE)",
"notes": "Necesitamos los custom fields de la marca también en la rama CREATE para mapear los valores que vienen de sucursal."
},
{
"parameters": {
"url": "https://services.leadconnectorhq.com/opportunities/pipelines",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "locationId",
"value": "={{ $('DATOS API').item.json['Location ID'] }}"
}
]
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
5280,
1104
],
"id": "58114758-f0fb-483a-bd5b-d28188880a02",
"name": "Obtener Pipelines - MARCA (CREATE)"
},
{
"parameters": {
"jsCode": "// ─── ARMAR BODY PARA CREAR OPORTUNIDAD EN MARCA ──────────────────────\n// Mapea custom fields por fieldKey (más estable que por name)\n// Resuelve pipeline/stage por nombre desde la oportunidad de sucursal\n\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA (CREATE)').first().json.customFields || [];\nconst marcaPipelines = $('Obtener Pipelines - MARCA (CREATE)').first().json.pipelines || [];\nconst locationId = $('DATOS API').first().json['Location ID'];\nconst decision = $('Decidir Match (Create vs Update)').first().json;\nconst contactId = decision.contactId;\nconst originTag = decision.originTag;\n\n// Map pipelines y stages de la marca por nombre normalizado\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim().toLowerCase()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim().toLowerCase()] = stage.id;\n }\n}\n\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim().toLowerCase()];\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim().toLowerCase()];\n\nif (!resolvedPipelineId) {\n throw new Error(`No se encontró pipeline en marca: \"${sucursalOpp.pipelineName}\". Revisa que el nombre coincida.`);\n}\nif (!resolvedStageId) {\n throw new Error(`No se encontró stage en marca: \"${sucursalOpp.pipelineStageName}\". Revisa que el nombre coincida.`);\n}\n\n// Mapear custom fields: preferir fieldKey (más estable), fallback a name\nconst sucursalValueByFieldKey = {};\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields || []) {\n if (cf.fieldKey) sucursalValueByFieldKey[cf.fieldKey] = cf.fieldValue;\n if (cf.name) sucursalValueByName[cf.name.trim().toLowerCase()] = cf.fieldValue;\n}\n\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n // 1er intento: por fieldKey\n let value = sucursalValueByFieldKey[def.fieldKey];\n // 2do intento: por nombre normalizado\n if (value === undefined && def.name) {\n value = sucursalValueByName[def.name.trim().toLowerCase()];\n }\n if (value === undefined || value === null || value === '') continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: value\n });\n}\n\n// Tags: combinar los que ya tiene la oportunidad de sucursal + tag de origen\nconst existingTags = sucursalOpp.tags || [];\nconst tagsForCreate = Array.from(new Set([...existingTags, originTag]));\n\nconst body = {\n pipelineId: resolvedPipelineId,\n locationId: locationId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status || 'open',\n contactId: contactId,\n monetaryValue: sucursalOpp.monetaryValue,\n source: sucursalOpp.source || 'Sincronización Sucursal',\n tags: tagsForCreate,\n customFields: customFields\n};\n\nreturn [{\n json: {\n body: JSON.stringify(body),\n debug: {\n resolvedPipelineId,\n resolvedStageId,\n customFieldsCount: customFields.length,\n originTag\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5520,
1104
],
"id": "2f9a63e7-277d-49de-8838-a00922c993b2",
"name": "Armar Body - CREATE"
},
{
"parameters": {
"method": "POST",
"url": "https://services.leadconnectorhq.com/opportunities/",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5760,
1104
],
"id": "fc4b3398-91bb-4dd9-b406-96c8d75a17be",
"name": "Crear Oportunidad - MARCA"
},
{
"parameters": {
"jsCode": "// ─── ARMAR BODY PARA ACTUALIZAR OPORTUNIDAD EN MARCA (v2) ────────────\n// Versión mejorada del Code original:\n// 1. Mapea custom fields por fieldKey (preferente) con fallback a name\n// 2. Incluye tag origin-id para idempotencia futura\n// 3. Normaliza pipeline/stage por nombre lowercase + trim\n\nconst marcaOppData = $('Obtener info de Oportunidad - MARCA (v2)').first().json;\nconst marcaOpp = marcaOppData.opportunity;\nconst marcaCustomFieldsDefs = $('Conseguir Custom Fields - Opportunity - MARCA').first().json.customFields || [];\nconst marcaPipelines = $('Obtener Pipelines - MARCA').first().json.pipelines || [];\nconst sucursalOpp = $('Mapeo completo oportunidad origen - SUCURSAL').first().json.opportunity;\nconst decision = $('Decidir Match (Create vs Update)').first().json;\nconst originTag = decision.originTag;\n\n// Map pipelines/stages marca por nombre normalizado\nconst marcaPipelineByName = {};\nconst marcaStageByName = {};\nfor (const pipeline of marcaPipelines) {\n marcaPipelineByName[pipeline.name.trim().toLowerCase()] = pipeline.id;\n for (const stage of pipeline.stages) {\n marcaStageByName[stage.name.trim().toLowerCase()] = stage.id;\n }\n}\n\nconst resolvedPipelineId = marcaPipelineByName[sucursalOpp.pipelineName?.trim().toLowerCase()] || marcaOpp.pipelineId;\nconst resolvedStageId = marcaStageByName[sucursalOpp.pipelineStageName?.trim().toLowerCase()] || marcaOpp.pipelineStageId;\n\n// Map sucursal: por fieldKey y por name\nconst sucursalValueByFieldKey = {};\nconst sucursalValueByName = {};\nfor (const cf of sucursalOpp.customFields || []) {\n if (cf.fieldKey) sucursalValueByFieldKey[cf.fieldKey] = cf.fieldValue;\n if (cf.name) sucursalValueByName[cf.name.trim().toLowerCase()] = cf.fieldValue;\n}\n\n// Construir custom fields del body\nconst customFields = [];\nfor (const def of marcaCustomFieldsDefs) {\n let value = sucursalValueByFieldKey[def.fieldKey];\n if (value === undefined && def.name) {\n value = sucursalValueByName[def.name.trim().toLowerCase()];\n }\n // Fallback: mantener valor original que tenía la oportunidad de marca\n if (value === undefined || value === null) {\n const marcaOriginal = marcaOpp.customFields?.find(cf => cf.id === def.id);\n value = marcaOriginal?.fieldValue;\n }\n if (value === undefined || value === null) continue;\n\n customFields.push({\n id: def.id,\n key: def.fieldKey,\n field_value: value\n });\n}\n\n// Tags: preservar los de marca + agregar origin-id\nconst existingTags = marcaOpp.tags || [];\nconst tagsForUpdate = Array.from(new Set([...existingTags, originTag]));\n\nconst body = {\n pipelineId: resolvedPipelineId,\n name: sucursalOpp.name,\n pipelineStageId: resolvedStageId,\n status: sucursalOpp.status || marcaOpp.status,\n monetaryValue: sucursalOpp.monetaryValue ?? marcaOpp.monetaryValue,\n source: sucursalOpp.source || marcaOpp.source,\n tags: tagsForUpdate,\n customFields: customFields\n};\n\nreturn [{\n json: {\n opportunityId: marcaOpp.id,\n body: JSON.stringify(body),\n debug: {\n matchReason: decision.matchReason,\n customFieldsCount: customFields.length\n }\n }\n}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5280,
816
],
"id": "969e46cd-bbae-4372-9808-c939f63e3c02",
"name": "Armar Body - UPDATE (v2)"
},
{
"parameters": {
"method": "PUT",
"url": "=https://services.leadconnectorhq.com/opportunities/{{ $json.opportunityId }}",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Accept",
"value": "application/json"
},
{
"name": "Version",
"value": "2021-07-28"
},
{
"name": "Authorization",
"value": "=Bearer {{ $('DATOS API').item.json['Token/API'] }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ $json.body }}",
"options": {
"redirect": {
"redirect": {}
}
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5520,
816
],
"id": "83929e08-7afd-4670-9c18-be22b8c3656f",
"name": "Actualizar Oportunidad - MARCA (v2)"
},
{
"parameters": {
"content": "# RAMA UPDATE\n## Oportunidad ya existe en marca → se actualiza",
"height": 280,
"width": 880,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"position": [
5008,
720
],
"typeVersion": 1,
"id": "1c285234-8d90-49ef-8dac-c98cb379299a",
"name": "Sticky Update"
},
{
"parameters": {
"content": "# RAMA CREATE\n## Oportunidad no existe en marca → se crea desde cero\n### Incluye contacto + custom fields + tag origin-id",
"height": 280,
"width": 1120,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"position": [
5008,
1024
],
"typeVersion": 1,
"id": "7e8f350c-9562-485b-8ce5-1b13b4086856",
"name": "Sticky Create"
},
{
"parameters": {
"content": "# MATCHING ROBUSTO\n## 1. Buscar/crear contacto en marca\n## 2. Buscar oportunidades DEL CONTACTO\n## 3. Decidir match por cantidad + tag origin-id",
"height": 320,
"width": 1500,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"position": [
3328,
864
],
"typeVersion": 1,
"id": "8a583e46-41b6-44e0-9313-b70ee085b740",
"name": "Sticky Matching"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Datos de Lead",
"type": "main",
"index": 0
}
]
]
},
"Datos de Lead": {
"main": [
[
{
"node": "Omitir @ezcorp.com",
"type": "main",
"index": 0
}
]
]
},
"DATOS API": {
"main": [
[
{
"node": "Buscar Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Omitir @ezcorp.com": {
"main": [
[
{
"node": "API de Sucursal",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidad - SUCURSAL": {
"main": [
[
{
"node": "Conseguir Custom Fields - Opportunity - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"DATOS API - SUCURSAL": {
"main": [
[
{
"node": "Buscar Oportunidad - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - SUCURSAL": {
"main": [
[
{
"node": "Obtener info de Oportunidad - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - SUCURSAL": {
"main": [
[
{
"node": "Obtener Pipelines - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"API de Sucursal": {
"main": [
[
{
"node": "DATOS API - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"API de MARCA": {
"main": [
[
{
"node": "DATOS API",
"type": "main",
"index": 0
}
]
]
},
"Mapeo completo oportunidad origen - SUCURSAL": {
"main": [
[
{
"node": "API de MARCA",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - SUCURSAL": {
"main": [
[
{
"node": "Mapeo completo oportunidad origen - SUCURSAL",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - MARCA": {
"main": [
[
{
"node": "Obtener Pipelines - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - MARCA": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidad - MARCA": {
"main": [
[
{
"node": "Conseguir Custom Fields - Opportunity - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - MARCA": {
"main": [
[
{
"node": "Obtener info de Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Actualizar Oportunidad - MARCA2",
"type": "main",
"index": 0
}
]
]
},
"Buscar Contacto en MARCA": {
"main": [
[
{
"node": "¿Existe contacto en MARCA?",
"type": "main",
"index": 0
}
]
]
},
"¿Existe contacto en MARCA?": {
"main": [
[
{
"node": "Set Contact ID Resuelto",
"type": "main",
"index": 0
}
],
[
{
"node": "Crear Contacto en MARCA",
"type": "main",
"index": 0
}
]
]
},
"Crear Contacto en MARCA": {
"main": [
[
{
"node": "Set Contact ID Resuelto",
"type": "main",
"index": 0
}
]
]
},
"Set Contact ID Resuelto": {
"main": [
[
{
"node": "Buscar Oportunidades del Contacto - MARCA",
"type": "main",
"index": 0
}
]
]
},
"Buscar Oportunidades del Contacto - MARCA": {
"main": [
[
{
"node": "Decidir Match (Create vs Update)",
"type": "main",
"index": 0
}
]
]
},
"Decidir Match (Create vs Update)": {
"main": [
[
{
"node": "Switch UPDATE vs CREATE",
"type": "main",
"index": 0
}
]
]
},
"Switch UPDATE vs CREATE": {
"main": [
[
{
"node": "Obtener info de Oportunidad - MARCA (v2)",
"type": "main",
"index": 0
}
],
[
{
"node": "Conseguir Custom Fields - Opportunity - MARCA (CREATE)",
"type": "main",
"index": 0
}
]
]
},
"Obtener info de Oportunidad - MARCA (v2)": {
"main": [
[
{
"node": "Armar Body - UPDATE (v2)",
"type": "main",
"index": 0
}
]
]
},
"Armar Body - UPDATE (v2)": {
"main": [
[
{
"node": "Actualizar Oportunidad - MARCA (v2)",
"type": "main",
"index": 0
}
]
]
},
"Conseguir Custom Fields - Opportunity - MARCA (CREATE)": {
"main": [
[
{
"node": "Obtener Pipelines - MARCA (CREATE)",
"type": "main",
"index": 0
}
]
]
},
"Obtener Pipelines - MARCA (CREATE)": {
"main": [
[
{
"node": "Armar Body - CREATE",
"type": "main",
"index": 0
}
]
]
},
"Armar Body - CREATE": {
"main": [
[
{
"node": "Crear Oportunidad - MARCA",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Consultoria E3 ®",
"name": "Version 9f358327",
"description": "",
"autosaved": false,
"workflowPublishHistory": [
{
"createdAt": "2026-05-26T09:42:35.722Z",
"id": 611,
"workflowId": "Cfgwp0bOtDW8zuKW",
"versionId": "9f358327-31aa-48d8-a188-e48332b62600",
"event": "activated",
"userId": "74a7f127-b963-4eb0-aff4-1190428e8409"
}
]
}
}