Files
cotizador-wmc-gmail-agent/cotizador-wmc-gmail-agent.json

8051 lines
282 KiB
JSON

{
"updatedAt": "2026-08-30T00:43:39.289Z",
"createdAt": "2026-08-29T23:40:22.957Z",
"id": "p4rDtVLIWyPuK0LI",
"name": "Cotizador WMC - Gmail Agent",
"description": null,
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {
"q": "from:iaracena@gomezleemarketing.com to:wmc@gomezlee.marketing"
},
"options": {
"dataPropertyAttachmentsPrefixName": "attachment_",
"downloadAttachments": true
}
},
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.3,
"position": [
-608,
752
],
"id": "ab207f82-b390-4f05-bee8-8275c085aa13",
"name": "Gmail Trigger - WMC Inbox",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const raw = $json || {};\nconst binary = $binary || {};\nconst hdr = {};\nfor (const h of (raw.payload?.headers || [])) {\n const k = String(h?.name || '').trim().toLowerCase();\n if (k) hdr[k] = String(h?.value || '');\n}\nfunction hv(name, fallback='') {\n const k = String(name).toLowerCase();\n return String(hdr[k] ?? raw[name] ?? raw.headers?.[k] ?? raw.headers?.[name] ?? fallback ?? '');\n}\nfunction decode64url(v) {\n if (!v) return '';\n try {\n let s = String(v).replace(/-/g,'+').replace(/_/g,'/');\n while (s.length % 4) s += '=';\n return Buffer.from(s,'base64').toString('utf8');\n } catch { return ''; }\n}\nfunction collect(part, texts, htmls) {\n if (!part || typeof part !== 'object') return;\n const mime = String(part.mimeType || '').toLowerCase();\n const decoded = decode64url(part.body?.data);\n if (decoded) {\n if (mime === 'text/plain') texts.push(decoded);\n else if (mime === 'text/html') htmls.push(decoded);\n }\n for (const p of (part.parts || [])) collect(p,texts,htmls);\n}\nconst texts=[], htmls=[]; collect(raw.payload || {}, texts, htmls);\nlet bodyText = String(raw.textPlain || raw.text || texts.join('\\n\\n') || raw.snippet || '').trim();\nlet bodyHtml = String(raw.textHtml || htmls.join('\\n\\n') || '').trim();\nif (!bodyText && bodyHtml) bodyText = bodyHtml.replace(/<style[\\s\\S]*?<\\/style>/gi,' ').replace(/<script[\\s\\S]*?<\\/script>/gi,' ').replace(/<br\\s*\\/?>/gi,'\\n').replace(/<\\/p>/gi,'\\n').replace(/<[^>]+>/g,' ').replace(/&nbsp;/gi,' ').replace(/&amp;/gi,'&').replace(/\\s+\\n/g,'\\n').replace(/\\n{3,}/g,'\\n\\n').trim();\nconst bodyTextFull = bodyText;\nfunction stripQuotedReply_(value) {\n let s=String(value||'').replace(/\\r\\n/g,'\\n').trim();\n // Gmail suele añadir el mensaje anterior tras “On ... wrote:” o “El ... escribió:”.\n // Cortamos solo esas respuestas citadas; NO eliminamos mensajes reenviados porque\n // pueden ser una solicitud operativa válida que el usuario haya reenviado.\n const replyMarkers=[\n /\\nOn [^\\n]{1,500} wrote:\\s*(?:\\n|$)/i,\n /\\nEl [^\\n]{1,500} escribi[oó]:\\s*(?:\\n|$)/i,\n /\\nLe [^\\n]{1,500} a écrit\\s*:\\s*(?:\\n|$)/i\n ];\n let cut=-1;\n for (const re of replyMarkers) { const m=re.exec(s); if(m && (cut<0 || m.index<cut)) cut=m.index; }\n if(cut>=0) s=s.slice(0,cut).trim();\n // Si solo quedan líneas quoteadas al final, no las enviamos al clasificador.\n const lines=s.split('\\n');\n const firstQuoted=lines.findIndex((line,i)=>i>0 && /^\\s*>/.test(line));\n if(firstQuoted>0) s=lines.slice(0,firstQuoted).join('\\n').trim();\n return s;\n}\nbodyText = stripQuotedReply_(bodyText) || bodyTextFull;\nfunction parseAddress(v) {\n const s=String(v||'').trim();\n const m=s.match(/<([^<>\\s]+@[^<>\\s]+)>/);\n const email=String(m?.[1] || (s.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/i)||[])[0] || '').toLowerCase();\n let name=s.replace(/<[^>]+>/g,'').replace(/^\\s*[\"']|[\"']\\s*$/g,'').trim();\n if (!name || name===email) name='';\n return {email,name};\n}\nconst from=parseAddress(hv('From',raw.from));\nconst to=hv('To',raw.to); const cc=hv('Cc',raw.cc); const subject=hv('Subject',raw.Subject || '(Sin asunto)');\nconst gmailMessageId=String(raw.id || raw.messageId || '').trim();\nconst gmailThreadId=String(raw.threadId || '').trim();\nconst approvers=['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'];\nconst testSender='iaracena@gomezleemarketing.com';\nconst senderDomain=(from.email.split('@')[1]||'').toLowerCase();\nconst isApprover=approvers.includes(from.email);\nconst isAllowedRequester=(senderDomain==='walmart.com' || from.email===testSender);\nconst isSelf=(from.email==='wmc@gomezlee.marketing');\nconst attachmentMeta=[];\nfor (const [key,b] of Object.entries(binary)) {\n const fileName=String(b?.fileName || b?.fileName || key);\n const mediaType=String(b?.mimeType || b?.fileType || 'application/octet-stream');\n const size=Number(b?.fileSize || 0) || null;\n attachmentMeta.push({binaryKey:key,filename:fileName,mediaType,size});\n}\nconst textForCountry=(subject+'\\n'+bodyText).toLowerCase();\nconst countries=[['GT','guatemala'],['CR','costa rica'],['SV','el salvador'],['SV','salvador'],['HN','honduras'],['NI','nicaragua']];\nlet countryCode=null; for (const [c,t] of countries) if (textForCountry.includes(t)) {countryCode=c;break;}\nreturn [{json:{\n gmailMessageId,gmailThreadId,senderEmail:from.email,senderName:from.name,subject,to,cc,\n sentAt:hv('Date',new Date().toISOString()),bodyText,bodyTextFull,bodyHtml,attachmentMeta,countryCode,\n isApprover,isAllowedRequester,isSelf,approvers,testSender,\n source:'gmail',receivedAt:new Date().toISOString()\n},binary}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-368,
752
],
"id": "b3c728b0-d9d4-427d-baa0-10a2a80afa49",
"name": "Normalizar correo entrante"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "aaf3ccba-78a9-454f-9f14-b55bc667172c",
"leftValue": "={{ $json.isApprover === true && /\\[APROBACIÓN WMC\\]/i.test(String($json.subject || '')) }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
480,
768
],
"id": "95c42b09-c38b-4d85-ad06-91025bafbc0c",
"name": "¿Respuesta de aprobador?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "2599c6eb-9d4f-4442-a05a-baf138f2c35b",
"leftValue": "={{ $json.isAllowedRequester && !$json.isSelf }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
800,
1376
],
"id": "e739c023-0e45-42f2-9ca4-3459b5722e63",
"name": "¿Remitente permitido?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1040,
1616
],
"id": "3fb50aa6-8dea-428f-8b12-b3b3ed54c22f",
"name": "Fin - Remitente ignorado"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m.startsWith('image/')||/\\.(png|jpe?g|webp|gif|bmp|heic|heif)$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasImages:names.length>0,imageBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1040,
1376
],
"id": "e7808d43-d28b-4864-ada3-0a70d096a9c8",
"name": "Preparar imágenes email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "e5e507fd-a65e-4f07-ba4f-47ce85f79973",
"leftValue": "={{ $json.hasImages }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1280,
1376
],
"id": "fda52bfd-ce24-4c74-aff0-2b72d57690d7",
"name": "¿Tiene imágenes email?"
},
{
"parameters": {
"resource": "image",
"operation": "analyze",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-pro"
},
"text": "Analiza fielmente las imágenes adjuntas para una solicitud de cotización Walmart Connect. Extrae solo información visible o escrita relevante: marcas, producto, país, formato/tienda, cantidades, personal, uniformes, mobiliario, medidas, logística y observaciones. No inventes precios ni datos.",
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar imágenes email\"].json.imageBinaryNames }}",
"options": {
"maxOutputTokens": 2200
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
1520,
1216
],
"id": "a5566162-bb0b-4827-b9cc-f6c1ced415bf",
"name": "Gemini - Analizar imágenes email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar imágenes email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,imageAnalysis:t||null,imageAnalysisError:base.hasImages&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1760,
1216
],
"id": "d700f366-212a-4637-8d45-aee19bb3e1bb",
"name": "Integrar análisis imágenes"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,imageAnalysis:null,imageAnalysisError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1520,
1536
],
"id": "3df9c929-8766-4cb8-919e-2f79e76e500c",
"name": "Sin imágenes email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m==='application/pdf'||/\\.pdf$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasPdfs:names.length>0,pdfBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2000,
1376
],
"id": "1af5b2f6-2f46-4c76-8206-b9066966e8dd",
"name": "Preparar PDFs email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "692b7118-2bee-4b0e-961b-e783688e914e",
"leftValue": "={{ $json.hasPdfs }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2240,
1376
],
"id": "648a0d41-45df-4e8a-9dec-01ca563b3cfb",
"name": "¿Tiene PDFs email?"
},
{
"parameters": {
"resource": "document",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-pro"
},
"text": "Analiza fielmente los PDF adjuntos para el Cotizador Walmart Connect. Extrae únicamente datos explícitos relevantes: país, anunciante, proyecto, fechas, formatos, tiendas, ubicación/cobertura, personal, cantidades, días, mobiliario, insumos, logística, medidas, condiciones y observaciones. No inventes información ni precios.",
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar PDFs email\"].json.pdfBinaryNames }}",
"options": {
"maxOutputTokens": 2600
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
2480,
1216
],
"id": "bd831472-87a5-4836-9e70-dba6c73d78f4",
"name": "Gemini - Analizar PDFs email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar PDFs email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,documentAnalysis:t||null,documentAnalysisError:base.hasPdfs&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2720,
1216
],
"id": "bf272474-9aae-43fc-b879-0d94a65c31ef",
"name": "Integrar análisis PDFs"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,documentAnalysis:null,documentAnalysisError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2480,
1536
],
"id": "92a5a7dd-7cc2-4548-bf3b-ec0d91306277",
"name": "Sin PDFs email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m.startsWith('audio/')||/\\.(webm|mp3|wav|m4a|ogg|oga|aac|flac|mpeg|mpga)$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasAudio:names.length>0,audioBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2960,
1376
],
"id": "a1dd4f45-724b-4846-84a7-5427087de6cd",
"name": "Preparar audio email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f0e66802-b149-4681-8953-4deaf95f1a07",
"leftValue": "={{ $json.hasAudio }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
3200,
1216
],
"id": "7e36fa54-ba65-4439-bd2a-6a4b5fa36a80",
"name": "¿Tiene audio email?"
},
{
"parameters": {
"resource": "audio",
"modelId": {
"__rl": true,
"value": "models/gemini-2.5-pro",
"mode": "list",
"cachedResultName": "models/gemini-2.5-pro"
},
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar audio email\"].json.audioBinaryNames }}",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
3440,
1056
],
"id": "1eb02117-3fa7-4a60-81fe-4d2e7b13d296",
"name": "Gemini - Transcribir audio email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar audio email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,audioTranscription:t||null,audioTranscriptionError:base.hasAudio&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3680,
1056
],
"id": "187cb874-b625-4376-8ec1-323d7fd676ca",
"name": "Integrar transcripción audio"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,audioTranscription:null,audioTranscriptionError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3440,
1376
],
"id": "07bf21a9-1f3b-4e4f-8777-080b1f43533b",
"name": "Sin audio email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const keys=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m==='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'||/\\.xlsx$/i.test(f)) keys.push(k); }\nconst supported=new Set(keys); const unsupported=($json.attachmentMeta||[]).filter(a=>{const m=String(a.mediaType||'').toLowerCase(),f=String(a.filename||''); return !(m.startsWith('image/')||m.startsWith('audio/')||m==='application/pdf'||/\\.(png|jpe?g|webp|gif|bmp|heic|heif|webm|mp3|wav|m4a|ogg|oga|aac|flac|mpeg|mpga|pdf|xlsx)$/i.test(f));});\nreturn [{json:{...$json,hasXlsx:keys.length>0,xlsxBinaryKeys:keys,unsupportedAttachments:unsupported},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3920,
1216
],
"id": "26a4ac9d-2a64-4b24-a2af-2e4caab7c197",
"name": "Preparar XLSX email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "eaadc66d-c3f5-417d-b945-5397809d08b9",
"leftValue": "={{ $json.hasXlsx }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
4848,
1088
],
"id": "6c433395-f347-45a6-bd7e-5d0c37b4bd9f",
"name": "¿Tiene XLSX email?"
},
{
"parameters": {
"jsCode": "const base=$json, bin=$binary||{}, keys=Array.isArray(base.xlsxBinaryKeys)?base.xlsxBinaryKeys:[]; const out=[]; let i=0;\nfor(const k of keys){const b=bin[k]; if(!b) continue; i++; const fn=String(b.fileName||`archivo-${i}.xlsx`); out.push({json:{...base,xlsxIndex:i-1,xlsxFilename:fn,tempUploadName:`_TEMP_WMC_EMAIL_XLSX_${Date.now()}_${i}_${fn.replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,90)}`},binary:{data:b}})}\nreturn out.length?out:[{json:{...base,hasXlsx:false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5088,
928
],
"id": "76c6166e-02e0-4119-89c6-babb7682c06a",
"name": "Expandir XLSX email"
},
{
"parameters": {
"name": "={{ $json.tempUploadName }}",
"driveId": {
"__rl": true,
"value": "My Drive",
"mode": "list"
},
"folderId": {
"__rl": true,
"value": "root",
"mode": "list",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
5328,
928
],
"id": "262b6267-8259-407d-a105-831750270537",
"name": "Subir XLSX email temporal a Drive",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const ups=$input.all(); let src=[]; try{src=$items(\"Expandir XLSX email\");}catch{} return ups.map((it,i)=>({json:{...(src[i]?.json||{}),tempXlsxDriveId:String(it.json?.id||'')||null,tempXlsxUploadError:it.json?.error||null},pairedItem:{item:i}}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5568,
928
],
"id": "53d5ef62-ba53-4a13-abf0-02223658ac6d",
"name": "Mapear XLSX email temporal"
},
{
"parameters": {
"method": "POST",
"url": "={{ 'https://www.googleapis.com/drive/v2/files/' + encodeURIComponent($json.tempXlsxDriveId || 'invalid') + '/copy?convert=true' }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"timeout": 60000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5808,
928
],
"id": "212fa06d-0a76-4e04-a540-7a101a26d283",
"name": "Convertir XLSX email a Google Sheets",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const xs=$input.all(); let src=[]; try{src=$items(\"Mapear XLSX email temporal\");}catch{} return xs.map((it,i)=>({json:{...(src[i]?.json||{}),tempGoogleSheetId:String(it.json?.id||'')||null,tempGoogleSheetMimeType:String(it.json?.mimeType||''),tempConversionError:it.json?.error||null},pairedItem:{item:i}}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6048,
928
],
"id": "c30d3b4a-58f2-45fd-ad7e-b9f3773c930f",
"name": "Mapear XLSX convertido email"
},
{
"parameters": {
"url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + encodeURIComponent($json.tempGoogleSheetId || 'invalid') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "includeGridData",
"value": "true"
},
{
"name": "fields",
"value": "spreadsheetId,properties(title),sheets(properties(sheetId,title,index,hidden,gridProperties(rowCount,columnCount)),data(startRow,startColumn,rowData(values(formattedValue,effectiveValue))))"
}
]
},
"options": {
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
6288,
928
],
"id": "555ba82c-e8ca-488a-b817-db114a0b9954",
"name": "Leer todas las hojas XLSX email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar XLSX email\"].json; const incoming=$input.all(); let metas=[]; try{metas=$items(\"Mapear XLSX convertido email\");}catch{}\nconst MAX=70000, ROWS=1500, COLS=100, SHEETS=40; let chars=0,trunc=false; const blocks=[],inventory=[],warn=[];\nconst clean=v=>String(v??'').replace(/[\\u0000-\\u001F]+/g,' ').replace(/\\s+/g,' ').trim();\nfunction col(i){let n=i+1,s='';while(n){const r=(n-1)%26;s=String.fromCharCode(65+r)+s;n=Math.floor((n-1)/26);}return s;}\nfunction val(c){if(!c||typeof c!=='object')return'';if(c.formattedValue!=null)return clean(c.formattedValue);const e=c.effectiveValue||{};for(const k of ['stringValue','numberValue','boolValue','formulaValue'])if(e[k]!=null)return clean(e[k]);return'';}\nfor(let fi=0;fi<incoming.length;fi++){const raw=incoming[fi]?.json||{}, meta=metas[fi]?.json||{}, fn=clean(meta.xlsxFilename||`archivo-${fi+1}.xlsx`), sheets=Array.isArray(raw.sheets)?raw.sheets.slice(0,SHEETS):[]; const names=[]; if(!sheets.length){warn.push(fn+': no se pudieron leer hojas.');continue;} for(const sh of sheets){if(chars>=MAX){trunc=true;break;}const p=sh?.properties||{}, sn=clean(p.title||`Hoja ${names.length+1}`);names.push(sn);const rm=new Map();for(const g of (sh.data||[])){const sr=Number(g?.startRow||0),sc=Number(g?.startColumn||0);for(let r=0;r<(g.rowData||[]).length;r++){const ar=sr+r;if(ar>=ROWS){trunc=true;break;}for(let c=0;c<(g.rowData[r]?.values||[]).length;c++){const ac=sc+c;if(ac>=COLS){trunc=true;break;}const v=val(g.rowData[r].values[c]);if(v){if(!rm.has(ar))rm.set(ar,new Map());rm.get(ar).set(ac,v);}}}}const lines=[];for(const r of [...rm.keys()].sort((a,b)=>a-b)){const cells=[...rm.get(r).entries()].sort((a,b)=>a[0]-b[0]);const line=`Fila ${r+1}: `+cells.map(([c,v])=>`[${col(c)}] ${v}`).join(' | ');if(chars+line.length>MAX){trunc=true;break;}lines.push(line);chars+=line.length+1;}blocks.push(`Archivo: ${fn}\\nHoja analizada: ${sn}${p.hidden?' (oculta)':''}\\n${lines.length?lines.join('\\n'):'(Sin contenido legible)'}`);}inventory.push({file:fn,sheets:names});}\nif(trunc)warn.push('Extracción XLSX truncada por límite de seguridad.');\nreturn [{json:{...base,spreadsheetAnalysis:blocks.join('\\n\\n').trim()||null,spreadsheetAnalysisError:blocks.length===0,spreadsheetSheetNames:inventory,spreadsheetExtractionWarnings:warn}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6528,
928
],
"id": "e25959cf-4a9d-440d-89e6-e77732472f69",
"name": "Agregar análisis XLSX email"
},
{
"parameters": {
"jsCode": "let metas=[];try{metas=$items(\"Mapear XLSX convertido email\");}catch{}const out=[],seen=new Set();for(const m0 of metas){const m=m0.json||{};for(const id0 of [m.tempGoogleSheetId,m.tempXlsxDriveId]){const id=String(id0||'').trim();if(id&&!seen.has(id)){seen.add(id);out.push({json:{deleteFileId:id}});}}}return out.length?out:[{json:{deleteFileId:null}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6768,
928
],
"id": "959e39a9-fd46-4ae5-b9f5-2ee81f418988",
"name": "Preparar limpieza XLSX email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "873da85e-f479-4fe3-85b3-95c6f9c105e8",
"leftValue": "={{ !!$json.deleteFileId }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
7008,
928
],
"id": "c992c380-1830-4340-9adf-a54fc401df24",
"name": "¿Hay temporal XLSX?"
},
{
"parameters": {
"operation": "deleteFile",
"fileId": {
"__rl": true,
"value": "={{ $json.deleteFileId }}",
"mode": "id"
},
"options": {
"deletePermanently": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
7248,
800
],
"id": "d924d82b-5ff6-4ab6-b84c-369cce1a95eb",
"name": "Eliminar temporal XLSX email",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Agregar análisis XLSX email\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7488,
800
],
"id": "0d5af946-c85f-47f4-a11f-a947696196af",
"name": "Restaurar base tras limpieza XLSX"
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Agregar análisis XLSX email\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7248,
1040
],
"id": "8d0f1365-ea58-4f3f-9fcd-edcc09773181",
"name": "Restaurar base sin limpieza XLSX"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,spreadsheetAnalysis:null,spreadsheetAnalysisError:false,spreadsheetSheetNames:[],spreadsheetExtractionWarnings:[]}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5088,
1248
],
"id": "3dfe6356-38d4-4be1-b08a-18ff31309002",
"name": "Sin XLSX email"
},
{
"parameters": {
"jsCode": "return [{json:$json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7728,
1088
],
"id": "b447a80b-ee83-4c9d-850e-a2dfe62f1a9a",
"name": "Base email lista para agente"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_ingest",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_gmail_message_id:$json.gmailMessageId,p_sender_email:$json.senderEmail,p_sender_name:$json.senderName,p_subject:$json.subject,p_body_text:$json.bodyText,p_body_html:$json.bodyHtml||null,p_attachments:$json.attachmentMeta||[],p_country_code:$json.countryCode||null}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
7968,
1088
],
"id": "26cb64c2-0b25-4d30-b054-d2a991ba468f",
"name": "Supabase - Ingestar email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500
},
{
"parameters": {
"jsCode": "const base=$node[\"Base email lista para agente\"].json; const raw=$json||{}; const ing=raw.body&&typeof raw.body==='object'?raw.body:(raw.data&&typeof raw.data==='object'?raw.data:raw);\nconst parts=[String(base.bodyText||'').trim()];\nif(base.imageAnalysis)parts.push('[ANÁLISIS REAL DE IMÁGENES ADJUNTAS]\\n'+base.imageAnalysis);\nif(base.documentAnalysis)parts.push('[ANÁLISIS REAL DE PDF ADJUNTOS]\\n'+base.documentAnalysis);\nif(base.audioTranscription)parts.push('[TRANSCRIPCIÓN REAL DE AUDIO ADJUNTO]\\n'+base.audioTranscription);\nif(base.spreadsheetAnalysis)parts.push('[CONTENIDO REAL EXTRAÍDO DE XLSX ADJUNTO]\\n'+base.spreadsheetAnalysis);\nif((base.unsupportedAttachments||[]).length)parts.push('[ADJUNTOS NO ANALIZADOS AUTOMÁTICAMENTE]\\n'+base.unsupportedAttachments.map(a=>`${a.filename} (${a.mediaType})`).join('\\n'));\nreturn [{json:{...base,ingest:ing,agentRequest:{gmailThreadId:base.gmailThreadId,gmailMessageId:base.gmailMessageId,senderEmail:base.senderEmail,senderName:base.senderName,text:parts.filter(Boolean).join('\\n\\n'),attachments:[],countryCode:base.countryCode,history:Array.isArray(ing.history)?ing.history:[],context:ing.context&&typeof ing.context==='object'?ing.context:{},emailMeta:{subject:base.subject,to:base.to,cc:base.cc,sentAt:base.sentAt,attachmentMeta:base.attachmentMeta||[],spreadsheetSheetNames:base.spreadsheetSheetNames||[]}}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
8208,
1088
],
"id": "02146f13-9a85-4727-8d27-a81a1c3d07fa",
"name": "Construir solicitud agente email"
},
{
"parameters": {
"method": "POST",
"url": "https://agenteit.digitalcompass.agency/webhook/cotizador-wmc-email-agent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-WMC-Internal-Secret",
"value": "fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.agentRequest) }}",
"options": {
"timeout": 240000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
8448,
1088
],
"id": "d13eba8c-3cc5-4c21-a8f8-a60b048d15ee",
"name": "Agente WMC - Procesar email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 4000,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir solicitud agente email\"].json; const raw=$json||{}; const a=(raw.body&&typeof raw.body==='object')?raw.body:raw; const cfg=base.ingest?.config||{};\nconst disposition=String(a.emailDisposition||'process').toLowerCase(); const action=String(a.action||'chat'); const quote=a.quote&&typeof a.quote==='object'?a.quote:null; const total=Number(quote?.totalUsd||0)||0; const threshold=Number(cfg.approval_threshold_usd??cfg.approvalThresholdUsd??10000)||10000;\nconst nonTariff=[]; if(quote&&Array.isArray(quote.items)){for(const it of quote.items){const amount=Math.abs(Number(it?.totalUsd||0));if(!(amount>0))continue;const code=String(it?.metadata?.priceSourceCode||it?.priceSourceCode||'').toUpperCase();if(code!=='T')nonTariff.push({description:String(it?.description||''),code:code||'E',amount});}}\nconst reasons=[];if(total>threshold)reasons.push({code:'OVER_10000',text:`Total USD ${total.toFixed(2)} supera el umbral de USD ${threshold.toFixed(2)}.`});if(nonTariff.length)reasons.push({code:'NON_TARIFF',text:`${nonTariff.length} partida(s) usan referencia fuera del tarifario oficial.`,items:nonTariff});\nconst approvalRequired=!!quote && ['generate_quote','generate_proposal','generate_monthly_glm'].includes(action) && reasons.length>0;\nconst generatedActions=['generate_quote','generate_proposal','generate_monthly_glm','generate_image'];\nconst artifactFailure=generatedActions.includes(action) && !a.artifactUrl;\nif(artifactFailure){\n a.reply='No pude generar el archivo solicitado en este momento. Por favor responde a este mismo correo para reintentarlo.';\n a.warnings=[...(Array.isArray(a.warnings)?a.warnings:[]),'El artefacto no fue generado; no se envió ningún archivo.'];\n}\nlet customerMode='final'; if(disposition==='ignore')customerMode='ignore'; else if(action==='chat'||artifactFailure)customerMode='clarification'; else if(approvalRequired)customerMode='approval';\nconst artifactType=String(a.artifactType||''); const artifactId=String(a.artifactId||''); const shouldExport=!!artifactId&&['quote','proposal','monthly_glm'].includes(artifactType);\nreturn [{json:{...base,agent:a,config:cfg,customerMode,approvalRequired,approvalReasons:reasons,nonTariffItems:nonTariff,totalUsd:total,thresholdUsd:threshold,artifactType,artifactId,artifactUrl:a.artifactUrl||null,artifactTitle:a.title||quote?.project||'WMC',quote,shouldExport,artifactFailure}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
8688,
1088
],
"id": "339b335b-e1ad-4696-92a3-43c4bcb7d437",
"name": "Evaluar respuesta agente email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "93182a6b-e065-4c35-93a8-e5c81bcddd2b",
"leftValue": "={{ $json.customerMode }}",
"rightValue": "ignore",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
8928,
1088
],
"id": "81685b4e-e097-456a-8a99-511234820fc6",
"name": "¿Ignorar correo?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
9168,
928
],
"id": "f80493b2-681c-491c-a844-605f26421534",
"name": "Fin - Correo fuera de alcance"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "257b6ccb-e648-4422-bd6d-025089fed298",
"leftValue": "={{ $json.approvalRequired }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9168,
1248
],
"id": "e8fc2f77-6ee2-4c75-916c-975c282e8fde",
"name": "¿Requiere aprobación interna?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_create_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_quote:$json.quote,p_document_url:$json.artifactUrl,p_artifact_id:$json.artifactId,p_artifact_type:$json.artifactType,p_artifact_title:$json.artifactTitle,p_customer_gmail_message_id:$json.gmailMessageId,p_reason:$json.approvalReasons}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
9408,
1488
],
"id": "d14f3a22-591f-495a-9f49-63f218e8dbe0",
"name": "Supabase - Crear aprobación email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500
},
{
"parameters": {
"jsCode": "const base=$node[\"Evaluar respuesta agente email\"].json;const raw=$json||{};const r=raw.body&&typeof raw.body==='object'?raw.body:raw;const approvalId=String(r.approvalId||'');\nconst esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));\nconst q=base.quote||{};const items=(base.nonTariffItems||[]).map(x=>`<li style=\"margin:5px 0\"><b>${esc(x.code)}</b> · ${esc(x.description)} · USD ${Number(x.amount||0).toFixed(2)}</li>`).join('');\nconst reasons=(base.approvalReasons||[]).map(x=>`<div style=\"margin:8px 0;padding:10px 12px;border-left:4px solid #FF8C00;background:#FFF8E1;color:#4A4A4A\">${esc(x.text)}</div>`).join('');\nconst html=`<div style=\"font-family:Arial,sans-serif;background:#f5f5f5;padding:24px\"><div style=\"max-width:720px;margin:auto;background:#fff;border:1px solid #e1e1e1;border-radius:14px;overflow:hidden\"><div style=\"height:6px;background:#6CC24A\"></div><div style=\"padding:26px 30px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" alt=\"GomezLee Marketing\" style=\"max-width:210px;height:auto\"><div style=\"margin-top:22px;color:#4F758B;font-size:12px;font-weight:bold;letter-spacing:1px\">COTIZADOR WALMART CONNECT · APROBACIÓN INTERNA</div><h2 style=\"color:#4F758B;margin:8px 0 4px\">Cotización pendiente de aprobación</h2><p style=\"color:#4A4A4A;margin-top:8px\">El agente preparó una cotización recibida por correo que no puede enviarse automáticamente.</p>${reasons}<table style=\"width:100%;border-collapse:collapse;margin:18px 0;font-size:14px\"><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold;width:32%\">Proyecto</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.project||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Anunciante</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.advertiser||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">País</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.country||q.countryCode||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Solicitante</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(base.senderEmail)}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Total</td><td style=\"padding:9px;font-size:18px;font-weight:bold;color:#4F758B\">USD ${Number(base.totalUsd||0).toFixed(2)}</td></tr></table>${items?`<div style=\"color:#4F758B;font-weight:bold;margin-top:16px\">Partidas fuera de tarifario</div><ul style=\"color:#4A4A4A\">${items}</ul>`:''}<div style=\"margin:20px 0;padding:14px;background:#D6E8F4;border-radius:10px;color:#4F758B\"><b>Para decidir, responde a este mismo correo:</b><br><b>APROBAR</b> · envía la cotización al cliente.<br><b>RECHAZAR</b> · no la envía.<br><b>CAMBIAR:</b> seguido de la modificación solicitada · el agente regenera el borrador y vuelve a pedir aprobación.</div>${base.artifactUrl?`<p><a href=\"${esc(base.artifactUrl)}\" style=\"color:#4F758B;font-weight:bold\">Abrir borrador en Google Workspace</a></p>`:''}<div style=\"margin-top:24px;border-top:1px solid #ddd;padding-top:12px;color:#6B8FA3;font-size:11px\">Referencia interna: ${esc(approvalId)}</div></div></div></div>`;\nconst approverEmails=(Array.isArray(base.config?.approver_emails)?base.config.approver_emails:(Array.isArray(base.emailConfig?.approver_emails)?base.emailConfig.approver_emails:['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'])).map(x=>String(x||'').trim()).filter(Boolean);return [{json:{...base,approvalId,requiredApprovals:Number(r.requiredApprovals||1),approvalSubject:`[APROBACIÓN WMC] ${q.project||q.advertiser||'Cotización'} · USD ${Number(base.totalUsd||0).toFixed(2)}`,approvalHtml:html,approverList:approverEmails.join(', '),approverEmails}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
9648,
1488
],
"id": "f15c6913-b9ee-47f9-9eb8-03529ff1b481",
"name": "Preparar correo aprobación GLM"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "dccfd9d3-857b-4b82-a269-6eef3029549d",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9888,
1488
],
"id": "5a76b54f-0585-438c-ad80-be0c812e27ad",
"name": "¿Adjuntar borrador a aprobación?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
10320,
1408
],
"id": "975d8649-99b7-41d0-993a-ce032b6fd94a",
"name": "Descargar borrador para aprobación",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar correo aprobación GLM\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}\nreturn [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10560,
1408
],
"id": "79448614-99a4-4125-a885-baf0f2da5d9f",
"name": "Preparar adjunto aprobación"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "7eb6cac5-d384-4161-9ac3-7b4ade92b248",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
11008,
1376
],
"id": "24d47913-b611-4203-ae4b-04be6e8311b9",
"name": "¿Borrador descargado?"
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11552,
1264
],
"id": "bf6b11ec-3341-42ad-b433-316684ad660c",
"name": "Gmail - Enviar aprobación con adjunto",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "64450f47-d0b4-424f-a091-341c4a34c2cd",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11776,
1472
],
"id": "cc24abfe-a768-4cb8-a227-575a8695bcd6",
"name": "Gmail - Enviar aprobación sin adjunto",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "b538ae39-7ec0-496a-a263-ce5263a9499f",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "return [{json:{...$json,exportOk:false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10992,
1856
],
"id": "5c3cec29-debb-4d98-8a51-6fcba1561663",
"name": "Preparar aprobación sin exportar"
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11232,
1856
],
"id": "78b06108-0570-4e13-939b-0c722ff2fdcb",
"name": "Gmail - Enviar aprobación solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "f13b8337-eee5-4a66-846d-908c2ea31ad9",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_set_approval_gmail_thread",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$node['Preparar correo aprobación GLM'].json.approvalId,p_approval_gmail_thread_id:$json.threadId,p_approval_gmail_message_id:$json.id}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13376,
1680
],
"id": "5a9dafcd-c828-433b-aa0b-1d7d56fc5316",
"name": "Supabase - Vincular hilo de aprobación",
"continueOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$node['Evaluar respuesta agente email'].json.gmailThreadId,p_gmail_message_id:'approval-out-'+$node['Preparar correo aprobación GLM'].json.approvalId,p_direction:'internal_out',p_from_email:'wmc@gomezlee.marketing',p_to_emails:$node['Preparar correo aprobación GLM'].json.approverEmails,p_subject:$node['Preparar correo aprobación GLM'].json.approvalSubject,p_body_text:'Solicitud de aprobación interna de cotización WMC.',p_body_html:$node['Preparar correo aprobación GLM'].json.approvalHtml,p_attachments:[],p_metadata:{approvalId:$node['Preparar correo aprobación GLM'].json.approvalId},p_status:'pending_approval'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13616,
1680
],
"id": "e7d604e0-1355-4350-8869-3c363498d708",
"name": "Supabase - Registrar solicitud aprobación",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
13856,
1680
],
"id": "c599c6f8-093e-459e-8390-b14279ccebe8",
"name": "Fin - Esperando aprobación"
},
{
"parameters": {
"jsCode": "const b=$json;const a=b.agent||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const name=String(b.senderName||'').trim();const greeting=name?`Hola ${esc(name.split(/\\s+/)[0])},`:'Hola,';const reply=esc(a.reply||'').replace(/\\n/g,'<br>');const isClar=b.customerMode==='clarification';const title=isClar?'Necesitamos una confirmación para continuar':'Cotización Walmart Connect';const intro=isClar?'Gracias por tu solicitud. Para continuar correctamente necesitamos confirmar lo siguiente:':'La solicitud fue procesada. Encontrarás el archivo correspondiente adjunto o disponible en el enlace incluido.';\nconst html=`<div style=\"font-family:Arial,sans-serif;background:#f5f7fa;padding:24px\"><div style=\"max-width:700px;margin:auto;background:#fff;border:1px solid #e5e8ec;border-radius:14px;overflow:hidden\"><div style=\"padding:26px 30px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/wallmart-logo.jpg\" alt=\"Walmart Connect\" style=\"max-width:230px;height:auto\"><h2 style=\"color:#041E42;margin:22px 0 8px\">${esc(title)}</h2><p style=\"color:#4A4A4A;line-height:1.55\">${greeting}</p><p style=\"color:#4A4A4A;line-height:1.55\">${esc(intro)}</p><div style=\"margin:18px 0;padding:14px 16px;border-left:4px solid #00BDE3;background:#F5FBFE;color:#041E42;line-height:1.55\">${reply||'Listo.'}</div>${!isClar&&b.artifactUrl?`<p style=\"margin:18px 0\"><a href=\"${esc(b.artifactUrl)}\" style=\"color:#0071CE;font-weight:bold\">Abrir archivo en Google Workspace</a></p>`:''}${isClar?'<p style=\"color:#4A4A4A\">Por favor responde a este mismo correo con la información solicitada y continuaremos desde aquí.</p>':'<p style=\"color:#4A4A4A\">Quedamos atentos a cualquier comentario o ajuste.</p>'}<div style=\"margin-top:26px;padding-top:14px;border-top:1px solid #e5e8ec;color:#6b7280;font-size:11px\">Walmart Connect · Gestión automatizada de cotizaciones</div></div></div></div>`;return [{json:{...b,customerHtml:html,customerSubject:b.subject}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
9408,
1168
],
"id": "ee0eab64-c0ec-4e4b-800b-e1942931944c",
"name": "Construir HTML cliente Walmart"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "e94406c9-0285-4541-ab19-a06c44a85b99",
"leftValue": "={{ $json.customerMode }}",
"rightValue": "clarification",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9648,
1168
],
"id": "b5f91adb-ca7d-4f7c-8680-a6697855b7d1",
"name": "¿Es aclaración?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
10192,
752
],
"id": "92fd8304-6172-4aa1-8067-cf2edc56905f",
"name": "Gmail - Responder aclaración cliente",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "160a5c37-d2e5-4ae9-8c18-327091bf22e5",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "1aebba2a-7e1b-47b2-b464-7835a163efe1",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9888,
1280
],
"id": "f58741f6-91f1-4843-b35c-619046a2839e",
"name": "¿Adjuntar archivo al cliente?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
10208,
1008
],
"id": "f43c7d77-f75f-4e9c-b067-92d62b151074",
"name": "Descargar artefacto para cliente",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir HTML cliente Walmart\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}return [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10448,
1008
],
"id": "3d6acf36-9b2a-46b2-8253-3bba8b2e09bc",
"name": "Preparar adjunto cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f45ceb76-0896-4be4-bd24-03175f38373c",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
10736,
976
],
"id": "f9f98ee7-51c2-4c8d-948d-bfc26f480705",
"name": "¿Archivo cliente descargado?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11248,
656
],
"id": "c7b347ba-e3a0-47b7-87ec-5f60858a0162",
"name": "Gmail - Responder cliente con archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ced5a909-e80a-4a90-8da6-cdd9b9f2d13d",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11088,
1088
],
"id": "d1706a6c-4fb8-46c7-aba1-2e0b63ccc99a",
"name": "Gmail - Responder cliente sin archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "541a4fe0-64c3-4eb0-acbe-65f3082d2845",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
10320,
1184
],
"id": "01ba8fb0-98c7-4f97-a5d6-1b0d754ddee8",
"name": "Gmail - Responder cliente solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "7520e58c-aa85-4301-be4d-b74d633610b4",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir HTML cliente Walmart\"].json;const g=$json||{};return [{json:{...base,sentGmailMessageId:String(g.id||''),sentGmailThreadId:String(g.threadId||base.gmailThreadId),sentOk:!!g.id}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
11632,
928
],
"id": "7ba23678-b7c4-4681-b8c5-75eadefb8977",
"name": "Postprocesar envío cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d974d8c2-6e06-41e0-880c-a2ab2f81f641",
"leftValue": "={{ !!$json.quote && $json.customerMode === \"final\" }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
11872,
928
],
"id": "793b94a2-a6d0-4c0b-8ca8-a611dc5c975f",
"name": "¿Guardar quote enviado?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_save_sent_quote",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_quote:$json.quote,p_document_url:$json.artifactUrl,p_artifact_id:$json.artifactId,p_artifact_type:$json.artifactType,p_artifact_title:$json.artifactTitle,p_sent_gmail_message_id:$json.sentGmailMessageId}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
12368,
800
],
"id": "d691d86e-23bc-4834-8651-3e35072b0c25",
"name": "Supabase - Guardar cotización enviada",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Postprocesar envío cliente\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
12608,
800
],
"id": "7698dbfb-1fac-4906-bf24-5a0a6316a48c",
"name": "Restaurar post envío tras guardar"
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Postprocesar envío cliente\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
12464,
1232
],
"id": "35274e8e-3527-4bb2-9b96-a23c40c6ab22",
"name": "Continuar sin guardar quote"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_gmail_message_id:$json.sentGmailMessageId,p_direction:'outbound',p_from_email:'wmc@gomezlee.marketing',p_to_emails:[$json.senderEmail],p_subject:$json.subject,p_body_text:$json.agent.reply||'',p_body_html:$json.customerHtml,p_attachments:$json.customerMode==='final'&&$json.artifactUrl?[{filename:$json.artifactTitle||'WMC',mediaType:$json.artifactType||'artifact',url:$json.artifactUrl}]:[],p_metadata:{action:$json.agent.action||'chat',artifactUrl:$json.artifactUrl||null},p_status:$json.customerMode==='clarification'?'awaiting_clarification':'sent'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13408,
1248
],
"id": "5463d643-ff69-4a0e-bdcc-02a71bc746ec",
"name": "Supabase - Registrar respuesta al cliente",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
13648,
1248
],
"id": "87ab6e4b-9587-4a2d-abe9-011ba22e31b7",
"name": "Fin - Email cliente procesado"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_get_pending_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_gmail_thread_id:$json.gmailThreadId,p_approver_email:$json.senderEmail}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
448
],
"id": "2885f662-e411-420a-bb10-e12588d7c594",
"name": "Supabase - Buscar aprobación pendiente",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const mail=$node[\"Normalizar correo entrante\"].json;\nconst raw=$json||{};\nconst r=raw.body&&typeof raw.body==='object'?raw.body:raw;\nconst found=!!r.found;\nconst normalize=v=>String(v||'').toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/\\s+/g,' ').trim();\nconst text=normalize(mail.bodyText||'');\nlet decision='change';\n// Se evalúa únicamente la respuesta nueva (el texto citado de Gmail ya fue retirado).\nif (/^(rechazar|rechazo|no aprobar|no apruebo|cancelar)\\b/.test(text)) decision='reject';\nelse if (/^(aprobar|apruebo|aprobado|confirmo|confirmado|adelante)\\b/.test(text)) decision='approve';\nelse if (/^(cambiar|cambio|modificar|ajustar|corregir)\\b/.test(text)) decision='change';\nreturn [{json:{...mail,pending:r,found,approval:r.approval||null,customerThread:r.customerThread||null,history:r.history||[],context:r.context||{},approvalDecision:decision,approvalInstructions:mail.bodyText}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
960,
448
],
"id": "87090417-f5f4-492a-a9f3-ee99a77f92d2",
"name": "Preparar respuesta de aprobación"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "2391c203-8c51-436b-a7c4-62e86f2963d1",
"leftValue": "={{ $json.found }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1200,
448
],
"id": "80a80c46-df48-4e3c-b658-db1f72f8bb8b",
"name": "¿Aprobación pendiente encontrada?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1440,
208
],
"id": "2c48258c-8563-4f1b-9ca4-37d5ac6d93cc",
"name": "Fin - Sin aprobación pendiente"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.customerThread.gmailThreadId,p_gmail_message_id:$json.gmailMessageId,p_direction:'internal_in',p_from_email:$json.senderEmail,p_to_emails:['wmc@gomezlee.marketing'],p_subject:$json.subject,p_body_text:$json.bodyText,p_body_html:$json.bodyHtml||null,p_attachments:$json.attachmentMeta||[],p_metadata:{approvalId:$json.approval.id},p_status:'pending_approval'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1440,
528
],
"id": "a0fcc6ee-8aa6-4f58-8506-626bfbe42ba0",
"name": "Supabase - Registrar respuesta aprobador",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Preparar respuesta de aprobación\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
528
],
"id": "a362cd2f-e5ac-4bd5-a6e0-6279fef142b1",
"name": "Restaurar aprobación tras registro"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "70b77420-e9f5-45c2-a5ce-ba7c06d88ef9",
"leftValue": "={{ $json.approvalDecision }}",
"rightValue": "change",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1920,
528
],
"id": "5be3f8fa-7c0b-4e38-b9fe-a4ce636fd7d2",
"name": "¿Solicita cambios internos?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_decide_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_approver_email:$json.senderEmail,p_decision:$json.approvalDecision,p_note:$json.bodyText}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2160,
688
],
"id": "1d1234b9-dc97-480e-803f-8661b31645cb",
"name": "Supabase - Decidir aprobación",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Restaurar aprobación tras registro\"].json;const raw=$json||{};const r=raw.body&&typeof raw.body==='object'?raw.body:raw;return [{json:{...base,decisionResult:r,finalDecision:String(r.finalDecision||''),approvalFinalOk:r.ok!==false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2400,
688
],
"id": "6230ea05-3cc2-4de8-a6f6-5cbd64936aa7",
"name": "Evaluar decisión interna"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "75942c37-1cb3-4221-a5ee-01dca0898f55",
"leftValue": "={{ $json.finalDecision }}",
"rightValue": "approved",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2640,
688
],
"id": "cc0e5278-4017-477d-944b-8531f812179d",
"name": "¿Aprobado final?"
},
{
"parameters": {
"jsCode": "const b=$json;const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const rejected=b.finalDecision==='rejected';const msg=rejected?'La cotización fue rechazada y no se enviará al cliente.':'La aprobación quedó registrada y continúa pendiente de las aprobaciones requeridas.';const html=`<div style=\"font-family:Arial,sans-serif;padding:20px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:190px\"><h3 style=\"color:#4F758B\">${rejected?'Cotización rechazada':'Aprobación registrada'}</h3><p style=\"color:#4A4A4A\">${esc(msg)}</p></div>`;return [{json:{...b,internalAckHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2880,
848
],
"id": "13d60b72-4de5-413f-8091-ac9a615d2b60",
"name": "Preparar confirmación decisión interna"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalAckHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3120,
848
],
"id": "c827ea05-0996-430d-818d-99c01e3decf6",
"name": "Gmail - Confirmar decisión al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "23dccd92-8d02-43bd-bca5-c96ce84abd6c",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3360,
848
],
"id": "63689e52-aad6-468f-8e61-9a851ae73c07",
"name": "Fin - Decisión interna registrada"
},
{
"parameters": {
"jsCode": "const b=$json;const a=b.approval||{};const q=a.candidateQuote||b.decisionResult?.candidateQuote||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const html=`<div style=\"font-family:Arial,sans-serif;background:#f5f7fa;padding:24px\"><div style=\"max-width:700px;margin:auto;background:white;border:1px solid #e5e8ec;border-radius:14px;padding:28px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/wallmart-logo.jpg\" style=\"max-width:230px\"><h2 style=\"color:#041E42\">Cotización Walmart Connect</h2><p style=\"color:#4A4A4A\">Hola,</p><p style=\"color:#4A4A4A;line-height:1.55\">Adjunto encontrarás la cotización solicitada para <b>${esc(q.project||'el proyecto indicado')}</b>.</p>${a.artifactUrl?`<p><a href=\"${esc(a.artifactUrl)}\" style=\"color:#0071CE;font-weight:bold\">Abrir cotización en Google Workspace</a></p>`:''}<p style=\"color:#4A4A4A\">Quedamos atentos a cualquier comentario o ajuste.</p></div></div>`;const type=String(a.artifactType||'');return [{json:{...b,quote:q,artifactId:a.artifactId,artifactUrl:a.artifactUrl,artifactType:type,artifactTitle:a.artifactTitle||q.project||'Cotizacion WMC',customerHtml:html,customerMessageId:a.customerGmailMessageId,shouldExport:!!a.artifactId&&['quote','proposal','monthly_glm'].includes(type)}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2880,
528
],
"id": "6325982d-9758-4b41-9b54-abb442790169",
"name": "Preparar envío aprobado al cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d25c7755-c533-472c-b27e-62b8a46da16e",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
3120,
528
],
"id": "9fc5b7cf-f07f-48a3-96fe-dc48e432030d",
"name": "¿Adjuntar archivo aprobado?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3504,
272
],
"id": "3d9f2351-adea-48f2-a349-54d2fd3556ec",
"name": "Descargar artefacto aprobado",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar envío aprobado al cliente\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}return [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3744,
272
],
"id": "074c1f03-b7bc-4d8d-a25c-76fa616db4d1",
"name": "Preparar adjunto aprobado"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "6d87afdd-9702-4c7a-809a-38f5b7331a0f",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
4240,
224
],
"id": "14065d5b-400d-432f-b30e-83f3e408c1ff",
"name": "¿Archivo aprobado descargado?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
4480,
144
],
"id": "9b7f449f-2574-432c-b318-32c475f10ea7",
"name": "Gmail - Enviar aprobado con archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ab9cd32a-ae42-48f1-87ba-26e33714c900",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
4480,
352
],
"id": "a326b49f-39cd-41c1-aa43-670e4f348933",
"name": "Gmail - Enviar aprobado sin archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ff99c43e-af13-44ec-8ed5-63b891dbb5a5",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3360,
640
],
"id": "7448f893-a0da-49d4-a0c8-6ac38f4a5459",
"name": "Gmail - Enviar aprobado solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "0a92c11b-b768-4729-ac5a-d6547891db37",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar envío aprobado al cliente\"].json;const g=$json||{};return [{json:{...base,sentGmailMessageId:String(g.id||''),sentGmailThreadId:String(g.threadId||base.customerThread?.gmailThreadId||'')}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5360,
384
],
"id": "506a308d-aaec-4d24-8634-9fdbe8aeeddc",
"name": "Postprocesar envío aprobado"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_mark_approval_sent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_sent_gmail_message_id:$json.sentGmailMessageId}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5600,
384
],
"id": "a1f193f6-61e8-42d9-a5dc-9dfa58b5da87",
"name": "Supabase - Marcar aprobación enviada",
"continueOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$node['Postprocesar envío aprobado'].json.customerThread.gmailThreadId,p_gmail_message_id:$node['Postprocesar envío aprobado'].json.sentGmailMessageId,p_direction:'outbound',p_from_email:'wmc@gomezlee.marketing',p_to_emails:[$node['Postprocesar envío aprobado'].json.customerThread.requesterEmail],p_subject:$node['Postprocesar envío aprobado'].json.customerThread.subject,p_body_text:'Cotización aprobada y enviada.',p_body_html:$node['Postprocesar envío aprobado'].json.customerHtml,p_attachments:[{filename:$node['Postprocesar envío aprobado'].json.artifactTitle,mediaType:$node['Postprocesar envío aprobado'].json.artifactType,url:$node['Postprocesar envío aprobado'].json.artifactUrl}],p_metadata:{approvalId:$node['Postprocesar envío aprobado'].json.approval.id},p_status:'sent'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5840,
384
],
"id": "9299ffeb-f273-4512-8c6a-029931e7139f",
"name": "Supabase - Registrar envío aprobado cliente",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
6080,
384
],
"id": "ad781ca1-ba7b-4850-ae31-2ed33cb7cf05",
"name": "Fin - Aprobación enviada al cliente"
},
{
"parameters": {
"jsCode": "const b=$node[\"Restaurar aprobación tras registro\"].json;const a=b.approval||{};return [{json:{...b,revisionRequest:{gmailThreadId:b.customerThread.gmailThreadId,gmailMessageId:b.gmailMessageId,senderEmail:b.senderEmail,senderName:b.senderName,text:`Revisión interna autorizada por ${b.senderEmail}:\\n${b.approvalInstructions}`,attachments:[],countryCode:b.customerThread.countryCode||null,history:b.history||[],context:b.context||{},emailMeta:{subject:b.customerThread.subject,internalApproval:true,approverEmail:b.senderEmail,requesterEmail:b.customerThread.requesterEmail},approvalRevision:{approvalId:a.id,approverEmail:b.senderEmail,instructions:b.approvalInstructions,candidateQuote:a.candidateQuote,artifactUrl:a.artifactUrl}}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
368
],
"id": "3e523ab8-90fb-431e-ad5b-384ee83e03a7",
"name": "Preparar revisión interna para agente"
},
{
"parameters": {
"method": "POST",
"url": "https://agenteit.digitalcompass.agency/webhook/cotizador-wmc-email-agent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-WMC-Internal-Secret",
"value": "fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.revisionRequest) }}",
"options": {
"timeout": 240000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2400,
368
],
"id": "b9b37eb4-bedb-4bf4-b29e-983835b05c59",
"name": "Agente WMC - Aplicar cambios aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 4000,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const b=$node[\"Preparar revisión interna para agente\"].json;const raw=$json||{};const a=raw.body&&typeof raw.body==='object'?raw.body:raw;const ready=!!(a.quote&&a.artifactUrl&&a.artifactId)&&a.action!=='chat';const q=a.quote||{};const nonT=[];for(const it of (q.items||[])){if(Number(it.totalUsd||0)>0){const c=String(it?.metadata?.priceSourceCode||'').toUpperCase()||'E';if(c!=='T')nonT.push({description:it.description,code:c,amount:Number(it.totalUsd||0)});}}const reasons=[];if(Number(q.totalUsd||0)>10000)reasons.push({code:'OVER_10000',text:`Total USD ${Number(q.totalUsd).toFixed(2)} supera USD 10,000.`});if(nonT.length)reasons.push({code:'NON_TARIFF',text:`${nonT.length} partida(s) fuera de tarifario.`,items:nonT});return [{json:{...b,revisionAgent:a,revisionReady:ready,revisionQuote:a.quote||null,revisionArtifactId:a.artifactId||null,revisionArtifactUrl:a.artifactUrl||null,revisionArtifactType:a.artifactType||null,revisionArtifactTitle:a.title||q.project||'WMC',revisionReasons:reasons}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2640,
368
],
"id": "6e2488a6-0781-45da-8fd5-e2ec64fab9ff",
"name": "Evaluar revisión interna"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "21c1085b-3260-4823-8161-2d59fba12d14",
"leftValue": "={{ $json.revisionReady }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2880,
368
],
"id": "fe12a681-17e1-4863-aebe-eb77df9fec26",
"name": "¿Revisión regenerada?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_replace_approval_candidate",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_approver_email:$json.senderEmail,p_quote:$json.revisionQuote,p_document_url:$json.revisionArtifactUrl,p_artifact_id:$json.revisionArtifactId,p_artifact_type:$json.revisionArtifactType,p_artifact_title:$json.revisionArtifactTitle,p_reason:$json.revisionReasons}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3264,
-16
],
"id": "d2205239-e261-4540-89f3-8ec3b95bcae8",
"name": "Supabase - Reemplazar candidato aprobación",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const b=$node[\"Evaluar revisión interna\"].json;const q=b.revisionQuote||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const html=`<div style=\"font-family:Arial,sans-serif;padding:22px;background:#f5f5f5\"><div style=\"max-width:700px;margin:auto;background:#fff;border-radius:12px;padding:26px;border-top:6px solid #6CC24A\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:200px\"><h2 style=\"color:#4F758B\">Borrador actualizado</h2><p style=\"color:#4A4A4A\">Se aplicaron los cambios solicitados. El nuevo total es <b>USD ${Number(q.totalUsd||0).toFixed(2)}</b>.</p>${b.revisionArtifactUrl?`<p><a href=\"${esc(b.revisionArtifactUrl)}\" style=\"color:#4F758B;font-weight:bold\">Abrir borrador actualizado</a></p>`:''}<div style=\"padding:14px;background:#D6E8F4;color:#4F758B;border-radius:8px\"><b>Responde a este hilo con APROBAR, RECHAZAR o CAMBIAR: ...</b></div></div></div>`;return [{json:{...b,internalRevisionHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3504,
-16
],
"id": "4b0e8f7e-8f97-4c15-b1dc-ad0cb3e6a3d0",
"name": "Preparar confirmación revisión GLM"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalRevisionHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3744,
-16
],
"id": "bd39629e-7f00-4024-8e06-b97b76da06ea",
"name": "Gmail - Enviar borrador actualizado al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "b5b19d95-d7d7-456e-ba99-2c60e80498a9",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3984,
-16
],
"id": "31181c4a-f6fe-43b0-96a2-784e0d809824",
"name": "Fin - Revisión pendiente nueva decisión"
},
{
"parameters": {
"jsCode": "const b=$json;const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const msg=esc(b.revisionAgent?.reply||'Necesito una precisión adicional para aplicar el cambio.').replace(/\\n/g,'<br>');const html=`<div style=\"font-family:Arial,sans-serif;padding:22px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:190px\"><h3 style=\"color:#4F758B\">Necesito confirmar un detalle del cambio</h3><div style=\"padding:12px;background:#D6E8F4;color:#4F758B\">${msg}</div><p style=\"color:#4A4A4A\">Responde a este mismo correo con la aclaración.</p></div>`;return [{json:{...b,internalRevisionHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3152,
320
],
"id": "175d6f84-a294-41e3-bedd-9ebd7f3215d2",
"name": "Preparar aclaración cambio al aprobador"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalRevisionHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3616,
464
],
"id": "5ecffd80-3047-438f-9855-30ee11bc5704",
"name": "Gmail - Pedir aclaración al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "e282116c-ad2a-4509-8f12-be7e95b06c14",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3856,
464
],
"id": "f85e6ffd-e7f0-4732-b161-ceed68521561",
"name": "Fin - Esperando aclaración aprobador"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_get_config",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08'}) }}",
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-32,
528
],
"id": "74d66de7-d63a-4400-ba2b-498c01800035",
"name": "Supabase - Config canal email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1500
},
{
"parameters": {
"jsCode": "const mail=$node[\"Normalizar correo entrante\"].json;\nconst raw=$json||{};\nconst cfg=(raw.body&&typeof raw.body==='object')?raw.body:(raw.data&&typeof raw.data==='object'?raw.data:raw);\nconst enabled=cfg.enabled===true || String(cfg.enabled||'').toLowerCase()==='true';\nconst allowTest=cfg.allow_test_sender===true || cfg.allowTestSender===true || String(cfg.allow_test_sender??cfg.allowTestSender??'').toLowerCase()==='true';\nconst testSender=String(cfg.test_sender_email??cfg.testSenderEmail??'iaracena@gomezleemarketing.com').trim().toLowerCase();\nconst walmartDomain=String(cfg.walmart_sender_domain??cfg.walmartSenderDomain??'walmart.com').trim().toLowerCase();\nconst approversRaw=cfg.approver_emails??cfg.approverEmails??['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'];\nconst approvers=(Array.isArray(approversRaw)?approversRaw:String(approversRaw||'').split(',')).map(x=>String(x||'').trim().toLowerCase()).filter(Boolean);\nconst sender=String(mail.senderEmail||'').trim().toLowerCase();\nconst domain=(sender.split('@')[1]||'').toLowerCase();\nconst isApprover=approvers.includes(sender);\nconst isSelf=sender==='wmc@gomezlee.marketing';\nconst isAllowedRequester=enabled && !isSelf && (domain===walmartDomain || (allowTest && sender===testSender));\nreturn [{json:{...mail,emailConfig:cfg,emailEnabled:enabled,allowTestSender:allowTest,testSender,walmartSenderDomain:walmartDomain,approvers,isApprover,isSelf,isAllowedRequester}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
208,
528
],
"id": "f0a4115a-e0c8-44ec-bf85-47cff0143b0a",
"name": "Aplicar configuración canal email"
}
],
"connections": {
"Gmail Trigger - WMC Inbox": {
"main": [
[
{
"node": "Normalizar correo entrante",
"type": "main",
"index": 0
}
]
]
},
"Normalizar correo entrante": {
"main": [
[
{
"node": "Supabase - Config canal email",
"type": "main",
"index": 0
}
]
]
},
"¿Respuesta de aprobador?": {
"main": [
[
{
"node": "Supabase - Buscar aprobación pendiente",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Remitente permitido?",
"type": "main",
"index": 0
}
]
]
},
"¿Remitente permitido?": {
"main": [
[
{
"node": "Preparar imágenes email",
"type": "main",
"index": 0
}
],
[
{
"node": "Fin - Remitente ignorado",
"type": "main",
"index": 0
}
]
]
},
"Preparar imágenes email": {
"main": [
[
{
"node": "¿Tiene imágenes email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene imágenes email?": {
"main": [
[
{
"node": "Gemini - Analizar imágenes email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin imágenes email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Analizar imágenes email": {
"main": [
[
{
"node": "Integrar análisis imágenes",
"type": "main",
"index": 0
}
]
]
},
"Integrar análisis imágenes": {
"main": [
[
{
"node": "Preparar PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Sin imágenes email": {
"main": [
[
{
"node": "Preparar PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Preparar PDFs email": {
"main": [
[
{
"node": "¿Tiene PDFs email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene PDFs email?": {
"main": [
[
{
"node": "Gemini - Analizar PDFs email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Analizar PDFs email": {
"main": [
[
{
"node": "Integrar análisis PDFs",
"type": "main",
"index": 0
}
]
]
},
"Integrar análisis PDFs": {
"main": [
[
{
"node": "Preparar audio email",
"type": "main",
"index": 0
}
]
]
},
"Sin PDFs email": {
"main": [
[
{
"node": "Preparar audio email",
"type": "main",
"index": 0
}
]
]
},
"Preparar audio email": {
"main": [
[
{
"node": "¿Tiene audio email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene audio email?": {
"main": [
[
{
"node": "Gemini - Transcribir audio email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin audio email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Transcribir audio email": {
"main": [
[
{
"node": "Integrar transcripción audio",
"type": "main",
"index": 0
}
]
]
},
"Integrar transcripción audio": {
"main": [
[
{
"node": "Preparar XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Sin audio email": {
"main": [
[
{
"node": "Preparar XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Preparar XLSX email": {
"main": [
[
{
"node": "¿Tiene XLSX email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene XLSX email?": {
"main": [
[
{
"node": "Expandir XLSX email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Expandir XLSX email": {
"main": [
[
{
"node": "Subir XLSX email temporal a Drive",
"type": "main",
"index": 0
}
]
]
},
"Subir XLSX email temporal a Drive": {
"main": [
[
{
"node": "Mapear XLSX email temporal",
"type": "main",
"index": 0
}
]
]
},
"Mapear XLSX email temporal": {
"main": [
[
{
"node": "Convertir XLSX email a Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Convertir XLSX email a Google Sheets": {
"main": [
[
{
"node": "Mapear XLSX convertido email",
"type": "main",
"index": 0
}
]
]
},
"Mapear XLSX convertido email": {
"main": [
[
{
"node": "Leer todas las hojas XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Leer todas las hojas XLSX email": {
"main": [
[
{
"node": "Agregar análisis XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Agregar análisis XLSX email": {
"main": [
[
{
"node": "Preparar limpieza XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Preparar limpieza XLSX email": {
"main": [
[
{
"node": "¿Hay temporal XLSX?",
"type": "main",
"index": 0
}
]
]
},
"¿Hay temporal XLSX?": {
"main": [
[
{
"node": "Eliminar temporal XLSX email",
"type": "main",
"index": 0
}
],
[
{
"node": "Restaurar base sin limpieza XLSX",
"type": "main",
"index": 0
}
]
]
},
"Eliminar temporal XLSX email": {
"main": [
[
{
"node": "Restaurar base tras limpieza XLSX",
"type": "main",
"index": 0
}
]
]
},
"Restaurar base tras limpieza XLSX": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Restaurar base sin limpieza XLSX": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Sin XLSX email": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Base email lista para agente": {
"main": [
[
{
"node": "Supabase - Ingestar email",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Ingestar email": {
"main": [
[
{
"node": "Construir solicitud agente email",
"type": "main",
"index": 0
}
]
]
},
"Construir solicitud agente email": {
"main": [
[
{
"node": "Agente WMC - Procesar email",
"type": "main",
"index": 0
}
]
]
},
"Agente WMC - Procesar email": {
"main": [
[
{
"node": "Evaluar respuesta agente email",
"type": "main",
"index": 0
}
]
]
},
"Evaluar respuesta agente email": {
"main": [
[
{
"node": "¿Ignorar correo?",
"type": "main",
"index": 0
}
]
]
},
"¿Ignorar correo?": {
"main": [
[
{
"node": "Fin - Correo fuera de alcance",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Requiere aprobación interna?",
"type": "main",
"index": 0
}
]
]
},
"¿Requiere aprobación interna?": {
"main": [
[
{
"node": "Supabase - Crear aprobación email",
"type": "main",
"index": 0
}
],
[
{
"node": "Construir HTML cliente Walmart",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Crear aprobación email": {
"main": [
[
{
"node": "Preparar correo aprobación GLM",
"type": "main",
"index": 0
}
]
]
},
"Preparar correo aprobación GLM": {
"main": [
[
{
"node": "¿Adjuntar borrador a aprobación?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar borrador a aprobación?": {
"main": [
[
{
"node": "Descargar borrador para aprobación",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar aprobación sin exportar",
"type": "main",
"index": 0
}
]
]
},
"Descargar borrador para aprobación": {
"main": [
[
{
"node": "Preparar adjunto aprobación",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto aprobación": {
"main": [
[
{
"node": "¿Borrador descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Borrador descargado?": {
"main": [
[
{
"node": "Gmail - Enviar aprobación con adjunto",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobación sin adjunto",
"type": "main",
"index": 0
}
]
]
},
"Preparar aprobación sin exportar": {
"main": [
[
{
"node": "Gmail - Enviar aprobación solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación con adjunto": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación sin adjunto": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación solo enlace": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Vincular hilo de aprobación": {
"main": [
[
{
"node": "Supabase - Registrar solicitud aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar solicitud aprobación": {
"main": [
[
{
"node": "Fin - Esperando aprobación",
"type": "main",
"index": 0
}
]
]
},
"Construir HTML cliente Walmart": {
"main": [
[
{
"node": "¿Es aclaración?",
"type": "main",
"index": 0
}
]
]
},
"¿Es aclaración?": {
"main": [
[
{
"node": "Gmail - Responder aclaración cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Adjuntar archivo al cliente?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar archivo al cliente?": {
"main": [
[
{
"node": "Descargar artefacto para cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Responder cliente solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Descargar artefacto para cliente": {
"main": [
[
{
"node": "Preparar adjunto cliente",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto cliente": {
"main": [
[
{
"node": "¿Archivo cliente descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Archivo cliente descargado?": {
"main": [
[
{
"node": "Gmail - Responder cliente con archivo",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Responder cliente sin archivo",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder aclaración cliente": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente con archivo": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente sin archivo": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente solo enlace": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Postprocesar envío cliente": {
"main": [
[
{
"node": "¿Guardar quote enviado?",
"type": "main",
"index": 0
}
]
]
},
"¿Guardar quote enviado?": {
"main": [
[
{
"node": "Supabase - Guardar cotización enviada",
"type": "main",
"index": 0
}
],
[
{
"node": "Continuar sin guardar quote",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Guardar cotización enviada": {
"main": [
[
{
"node": "Restaurar post envío tras guardar",
"type": "main",
"index": 0
}
]
]
},
"Restaurar post envío tras guardar": {
"main": [
[
{
"node": "Supabase - Registrar respuesta al cliente",
"type": "main",
"index": 0
}
]
]
},
"Continuar sin guardar quote": {
"main": [
[
{
"node": "Supabase - Registrar respuesta al cliente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar respuesta al cliente": {
"main": [
[
{
"node": "Fin - Email cliente procesado",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Buscar aprobación pendiente": {
"main": [
[
{
"node": "Preparar respuesta de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta de aprobación": {
"main": [
[
{
"node": "¿Aprobación pendiente encontrada?",
"type": "main",
"index": 0
}
]
]
},
"¿Aprobación pendiente encontrada?": {
"main": [
[
{
"node": "Supabase - Registrar respuesta aprobador",
"type": "main",
"index": 0
}
],
[
{
"node": "Fin - Sin aprobación pendiente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar respuesta aprobador": {
"main": [
[
{
"node": "Restaurar aprobación tras registro",
"type": "main",
"index": 0
}
]
]
},
"Restaurar aprobación tras registro": {
"main": [
[
{
"node": "¿Solicita cambios internos?",
"type": "main",
"index": 0
}
]
]
},
"¿Solicita cambios internos?": {
"main": [
[
{
"node": "Preparar revisión interna para agente",
"type": "main",
"index": 0
}
],
[
{
"node": "Supabase - Decidir aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Decidir aprobación": {
"main": [
[
{
"node": "Evaluar decisión interna",
"type": "main",
"index": 0
}
]
]
},
"Evaluar decisión interna": {
"main": [
[
{
"node": "¿Aprobado final?",
"type": "main",
"index": 0
}
]
]
},
"¿Aprobado final?": {
"main": [
[
{
"node": "Preparar envío aprobado al cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar confirmación decisión interna",
"type": "main",
"index": 0
}
]
]
},
"Preparar confirmación decisión interna": {
"main": [
[
{
"node": "Gmail - Confirmar decisión al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Confirmar decisión al aprobador": {
"main": [
[
{
"node": "Fin - Decisión interna registrada",
"type": "main",
"index": 0
}
]
]
},
"Preparar envío aprobado al cliente": {
"main": [
[
{
"node": "¿Adjuntar archivo aprobado?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar archivo aprobado?": {
"main": [
[
{
"node": "Descargar artefacto aprobado",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobado solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Descargar artefacto aprobado": {
"main": [
[
{
"node": "Preparar adjunto aprobado",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto aprobado": {
"main": [
[
{
"node": "¿Archivo aprobado descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Archivo aprobado descargado?": {
"main": [
[
{
"node": "Gmail - Enviar aprobado con archivo",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobado sin archivo",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado con archivo": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado sin archivo": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado solo enlace": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Postprocesar envío aprobado": {
"main": [
[
{
"node": "Supabase - Marcar aprobación enviada",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Marcar aprobación enviada": {
"main": [
[
{
"node": "Supabase - Registrar envío aprobado cliente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar envío aprobado cliente": {
"main": [
[
{
"node": "Fin - Aprobación enviada al cliente",
"type": "main",
"index": 0
}
]
]
},
"Preparar revisión interna para agente": {
"main": [
[
{
"node": "Agente WMC - Aplicar cambios aprobador",
"type": "main",
"index": 0
}
]
]
},
"Agente WMC - Aplicar cambios aprobador": {
"main": [
[
{
"node": "Evaluar revisión interna",
"type": "main",
"index": 0
}
]
]
},
"Evaluar revisión interna": {
"main": [
[
{
"node": "¿Revisión regenerada?",
"type": "main",
"index": 0
}
]
]
},
"¿Revisión regenerada?": {
"main": [
[
{
"node": "Supabase - Reemplazar candidato aprobación",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar aclaración cambio al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Reemplazar candidato aprobación": {
"main": [
[
{
"node": "Preparar confirmación revisión GLM",
"type": "main",
"index": 0
}
]
]
},
"Preparar confirmación revisión GLM": {
"main": [
[
{
"node": "Gmail - Enviar borrador actualizado al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar borrador actualizado al aprobador": {
"main": [
[
{
"node": "Fin - Revisión pendiente nueva decisión",
"type": "main",
"index": 0
}
]
]
},
"Preparar aclaración cambio al aprobador": {
"main": [
[
{
"node": "Gmail - Pedir aclaración al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Pedir aclaración al aprobador": {
"main": [
[
{
"node": "Fin - Esperando aclaración aprobador",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Config canal email": {
"main": [
[
{
"node": "Aplicar configuración canal email",
"type": "main",
"index": 0
}
]
]
},
"Aplicar configuración canal email": {
"main": [
[
{
"node": "¿Respuesta de aprobador?",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate"
},
"staticData": {
"node:Gmail Trigger - WMC Inbox": {
"Gmail Trigger - WMC Inbox": {
"lastTimeChecked": 1788050507,
"possibleDuplicates": [
"1a0501db03001970",
"1a0501c3d985fa2b"
]
}
}
},
"meta": {
"templateCredsSetupCompleted": true
},
"versionId": "5c4f87b4-f17a-4b66-9600-388931fcd2b9",
"activeVersionId": "5c4f87b4-f17a-4b66-9600-388931fcd2b9",
"versionCounter": 75,
"triggerCount": 1,
"shared": [
{
"updatedAt": "2026-08-29T23:40:22.961Z",
"createdAt": "2026-08-29T23:40:22.961Z",
"role": "workflow:owner",
"workflowId": "p4rDtVLIWyPuK0LI",
"projectId": "PJpTANzTXIFibWsW",
"project": {
"updatedAt": "2026-04-22T14:25:09.686Z",
"createdAt": "2026-04-22T14:22:54.790Z",
"id": "PJpTANzTXIFibWsW",
"name": "Isaac Aracena <iaracena@gomezleemarketing.com>",
"type": "personal",
"icon": null,
"description": null,
"creatorId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}
}
],
"tags": [],
"activeVersion": {
"updatedAt": "2026-08-30T00:40:38.000Z",
"createdAt": "2026-08-30T00:35:48.576Z",
"versionId": "5c4f87b4-f17a-4b66-9600-388931fcd2b9",
"workflowId": "p4rDtVLIWyPuK0LI",
"nodes": [
{
"parameters": {
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"simple": false,
"filters": {
"q": "from:iaracena@gomezleemarketing.com to:wmc@gomezlee.marketing"
},
"options": {
"dataPropertyAttachmentsPrefixName": "attachment_",
"downloadAttachments": true
}
},
"type": "n8n-nodes-base.gmailTrigger",
"typeVersion": 1.3,
"position": [
-608,
752
],
"id": "ab207f82-b390-4f05-bee8-8275c085aa13",
"name": "Gmail Trigger - WMC Inbox",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const raw = $json || {};\nconst binary = $binary || {};\nconst hdr = {};\nfor (const h of (raw.payload?.headers || [])) {\n const k = String(h?.name || '').trim().toLowerCase();\n if (k) hdr[k] = String(h?.value || '');\n}\nfunction hv(name, fallback='') {\n const k = String(name).toLowerCase();\n return String(hdr[k] ?? raw[name] ?? raw.headers?.[k] ?? raw.headers?.[name] ?? fallback ?? '');\n}\nfunction decode64url(v) {\n if (!v) return '';\n try {\n let s = String(v).replace(/-/g,'+').replace(/_/g,'/');\n while (s.length % 4) s += '=';\n return Buffer.from(s,'base64').toString('utf8');\n } catch { return ''; }\n}\nfunction collect(part, texts, htmls) {\n if (!part || typeof part !== 'object') return;\n const mime = String(part.mimeType || '').toLowerCase();\n const decoded = decode64url(part.body?.data);\n if (decoded) {\n if (mime === 'text/plain') texts.push(decoded);\n else if (mime === 'text/html') htmls.push(decoded);\n }\n for (const p of (part.parts || [])) collect(p,texts,htmls);\n}\nconst texts=[], htmls=[]; collect(raw.payload || {}, texts, htmls);\nlet bodyText = String(raw.textPlain || raw.text || texts.join('\\n\\n') || raw.snippet || '').trim();\nlet bodyHtml = String(raw.textHtml || htmls.join('\\n\\n') || '').trim();\nif (!bodyText && bodyHtml) bodyText = bodyHtml.replace(/<style[\\s\\S]*?<\\/style>/gi,' ').replace(/<script[\\s\\S]*?<\\/script>/gi,' ').replace(/<br\\s*\\/?>/gi,'\\n').replace(/<\\/p>/gi,'\\n').replace(/<[^>]+>/g,' ').replace(/&nbsp;/gi,' ').replace(/&amp;/gi,'&').replace(/\\s+\\n/g,'\\n').replace(/\\n{3,}/g,'\\n\\n').trim();\nconst bodyTextFull = bodyText;\nfunction stripQuotedReply_(value) {\n let s=String(value||'').replace(/\\r\\n/g,'\\n').trim();\n // Gmail suele añadir el mensaje anterior tras “On ... wrote:” o “El ... escribió:”.\n // Cortamos solo esas respuestas citadas; NO eliminamos mensajes reenviados porque\n // pueden ser una solicitud operativa válida que el usuario haya reenviado.\n const replyMarkers=[\n /\\nOn [^\\n]{1,500} wrote:\\s*(?:\\n|$)/i,\n /\\nEl [^\\n]{1,500} escribi[oó]:\\s*(?:\\n|$)/i,\n /\\nLe [^\\n]{1,500} a écrit\\s*:\\s*(?:\\n|$)/i\n ];\n let cut=-1;\n for (const re of replyMarkers) { const m=re.exec(s); if(m && (cut<0 || m.index<cut)) cut=m.index; }\n if(cut>=0) s=s.slice(0,cut).trim();\n // Si solo quedan líneas quoteadas al final, no las enviamos al clasificador.\n const lines=s.split('\\n');\n const firstQuoted=lines.findIndex((line,i)=>i>0 && /^\\s*>/.test(line));\n if(firstQuoted>0) s=lines.slice(0,firstQuoted).join('\\n').trim();\n return s;\n}\nbodyText = stripQuotedReply_(bodyText) || bodyTextFull;\nfunction parseAddress(v) {\n const s=String(v||'').trim();\n const m=s.match(/<([^<>\\s]+@[^<>\\s]+)>/);\n const email=String(m?.[1] || (s.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/i)||[])[0] || '').toLowerCase();\n let name=s.replace(/<[^>]+>/g,'').replace(/^\\s*[\"']|[\"']\\s*$/g,'').trim();\n if (!name || name===email) name='';\n return {email,name};\n}\nconst from=parseAddress(hv('From',raw.from));\nconst to=hv('To',raw.to); const cc=hv('Cc',raw.cc); const subject=hv('Subject',raw.Subject || '(Sin asunto)');\nconst gmailMessageId=String(raw.id || raw.messageId || '').trim();\nconst gmailThreadId=String(raw.threadId || '').trim();\nconst approvers=['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'];\nconst testSender='iaracena@gomezleemarketing.com';\nconst senderDomain=(from.email.split('@')[1]||'').toLowerCase();\nconst isApprover=approvers.includes(from.email);\nconst isAllowedRequester=(senderDomain==='walmart.com' || from.email===testSender);\nconst isSelf=(from.email==='wmc@gomezlee.marketing');\nconst attachmentMeta=[];\nfor (const [key,b] of Object.entries(binary)) {\n const fileName=String(b?.fileName || b?.fileName || key);\n const mediaType=String(b?.mimeType || b?.fileType || 'application/octet-stream');\n const size=Number(b?.fileSize || 0) || null;\n attachmentMeta.push({binaryKey:key,filename:fileName,mediaType,size});\n}\nconst textForCountry=(subject+'\\n'+bodyText).toLowerCase();\nconst countries=[['GT','guatemala'],['CR','costa rica'],['SV','el salvador'],['SV','salvador'],['HN','honduras'],['NI','nicaragua']];\nlet countryCode=null; for (const [c,t] of countries) if (textForCountry.includes(t)) {countryCode=c;break;}\nreturn [{json:{\n gmailMessageId,gmailThreadId,senderEmail:from.email,senderName:from.name,subject,to,cc,\n sentAt:hv('Date',new Date().toISOString()),bodyText,bodyTextFull,bodyHtml,attachmentMeta,countryCode,\n isApprover,isAllowedRequester,isSelf,approvers,testSender,\n source:'gmail',receivedAt:new Date().toISOString()\n},binary}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-368,
752
],
"id": "b3c728b0-d9d4-427d-baa0-10a2a80afa49",
"name": "Normalizar correo entrante"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "aaf3ccba-78a9-454f-9f14-b55bc667172c",
"leftValue": "={{ $json.isApprover === true && /\\[APROBACIÓN WMC\\]/i.test(String($json.subject || '')) }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
480,
768
],
"id": "95c42b09-c38b-4d85-ad06-91025bafbc0c",
"name": "¿Respuesta de aprobador?"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "2599c6eb-9d4f-4442-a05a-baf138f2c35b",
"leftValue": "={{ $json.isAllowedRequester && !$json.isSelf }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
800,
1376
],
"id": "e739c023-0e45-42f2-9ca4-3459b5722e63",
"name": "¿Remitente permitido?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1040,
1616
],
"id": "3fb50aa6-8dea-428f-8b12-b3b3ed54c22f",
"name": "Fin - Remitente ignorado"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m.startsWith('image/')||/\\.(png|jpe?g|webp|gif|bmp|heic|heif)$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasImages:names.length>0,imageBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1040,
1376
],
"id": "e7808d43-d28b-4864-ada3-0a70d096a9c8",
"name": "Preparar imágenes email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "e5e507fd-a65e-4f07-ba4f-47ce85f79973",
"leftValue": "={{ $json.hasImages }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1280,
1376
],
"id": "fda52bfd-ce24-4c74-aff0-2b72d57690d7",
"name": "¿Tiene imágenes email?"
},
{
"parameters": {
"resource": "image",
"operation": "analyze",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-pro"
},
"text": "Analiza fielmente las imágenes adjuntas para una solicitud de cotización Walmart Connect. Extrae solo información visible o escrita relevante: marcas, producto, país, formato/tienda, cantidades, personal, uniformes, mobiliario, medidas, logística y observaciones. No inventes precios ni datos.",
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar imágenes email\"].json.imageBinaryNames }}",
"options": {
"maxOutputTokens": 2200
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
1520,
1216
],
"id": "a5566162-bb0b-4827-b9cc-f6c1ced415bf",
"name": "Gemini - Analizar imágenes email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar imágenes email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,imageAnalysis:t||null,imageAnalysisError:base.hasImages&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1760,
1216
],
"id": "d700f366-212a-4637-8d45-aee19bb3e1bb",
"name": "Integrar análisis imágenes"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,imageAnalysis:null,imageAnalysisError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1520,
1536
],
"id": "3df9c929-8766-4cb8-919e-2f79e76e500c",
"name": "Sin imágenes email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m==='application/pdf'||/\\.pdf$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasPdfs:names.length>0,pdfBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2000,
1376
],
"id": "1af5b2f6-2f46-4c76-8206-b9066966e8dd",
"name": "Preparar PDFs email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "692b7118-2bee-4b0e-961b-e783688e914e",
"leftValue": "={{ $json.hasPdfs }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2240,
1376
],
"id": "648a0d41-45df-4e8a-9dec-01ca563b3cfb",
"name": "¿Tiene PDFs email?"
},
{
"parameters": {
"resource": "document",
"modelId": {
"__rl": true,
"mode": "list",
"value": "models/gemini-2.5-pro"
},
"text": "Analiza fielmente los PDF adjuntos para el Cotizador Walmart Connect. Extrae únicamente datos explícitos relevantes: país, anunciante, proyecto, fechas, formatos, tiendas, ubicación/cobertura, personal, cantidades, días, mobiliario, insumos, logística, medidas, condiciones y observaciones. No inventes información ni precios.",
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar PDFs email\"].json.pdfBinaryNames }}",
"options": {
"maxOutputTokens": 2600
}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
2480,
1216
],
"id": "bd831472-87a5-4836-9e70-dba6c73d78f4",
"name": "Gemini - Analizar PDFs email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar PDFs email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,documentAnalysis:t||null,documentAnalysisError:base.hasPdfs&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2720,
1216
],
"id": "bf272474-9aae-43fc-b879-0d94a65c31ef",
"name": "Integrar análisis PDFs"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,documentAnalysis:null,documentAnalysisError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2480,
1536
],
"id": "92a5a7dd-7cc2-4548-bf3b-ec0d91306277",
"name": "Sin PDFs email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const names=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m.startsWith('audio/')||/\\.(webm|mp3|wav|m4a|ogg|oga|aac|flac|mpeg|mpga)$/i.test(f)) names.push(k); }\nreturn [{json:{...$json,hasAudio:names.length>0,audioBinaryNames:names.join(',')},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2960,
1376
],
"id": "a1dd4f45-724b-4846-84a7-5427087de6cd",
"name": "Preparar audio email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f0e66802-b149-4681-8953-4deaf95f1a07",
"leftValue": "={{ $json.hasAudio }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
3200,
1216
],
"id": "7e36fa54-ba65-4439-bd2a-6a4b5fa36a80",
"name": "¿Tiene audio email?"
},
{
"parameters": {
"resource": "audio",
"modelId": {
"__rl": true,
"value": "models/gemini-2.5-pro",
"mode": "list",
"cachedResultName": "models/gemini-2.5-pro"
},
"inputType": "binary",
"binaryPropertyName": "={{ $node[\"Preparar audio email\"].json.audioBinaryNames }}",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.googleGemini",
"typeVersion": 1.1,
"position": [
3440,
1056
],
"id": "1eb02117-3fa7-4a60-81fe-4d2e7b13d296",
"name": "Gemini - Transcribir audio email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googlePalmApi": {
"id": "jvsXYwL6IOoY2DBU",
"name": "Isaac - Gemini Api Pago"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "function txt(r){ if(!r||typeof r!=='object') return ''; for(const k of ['text','output','response','result','mergedResponse']) if(typeof r[k]==='string'&&r[k].trim()) return r[k].trim(); const p=r.content?.parts||r.candidates?.[0]?.content?.parts; if(Array.isArray(p)) return p.map(x=>x?.text||'').join('\\n').trim(); return ''; }\nconst base=$node[\"Preparar audio email\"].json; const t=txt($json); let trg={}; try{trg=$items(\"Gmail Trigger - WMC Inbox\")[0]||{};}catch{}\nreturn [{json:{...base,audioTranscription:t||null,audioTranscriptionError:base.hasAudio&&!t},binary:trg.binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3680,
1056
],
"id": "187cb874-b625-4376-8ec1-323d7fd676ca",
"name": "Integrar transcripción audio"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,audioTranscription:null,audioTranscriptionError:false},binary:$binary||{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3440,
1376
],
"id": "07bf21a9-1f3b-4e4f-8777-080b1f43533b",
"name": "Sin audio email"
},
{
"parameters": {
"jsCode": "const bin=$binary||{}; const keys=[];\nfor(const [k,b] of Object.entries(bin)){ const m=String(b?.mimeType||'').toLowerCase(), f=String(b?.fileName||''); if(m==='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'||/\\.xlsx$/i.test(f)) keys.push(k); }\nconst supported=new Set(keys); const unsupported=($json.attachmentMeta||[]).filter(a=>{const m=String(a.mediaType||'').toLowerCase(),f=String(a.filename||''); return !(m.startsWith('image/')||m.startsWith('audio/')||m==='application/pdf'||/\\.(png|jpe?g|webp|gif|bmp|heic|heif|webm|mp3|wav|m4a|ogg|oga|aac|flac|mpeg|mpga|pdf|xlsx)$/i.test(f));});\nreturn [{json:{...$json,hasXlsx:keys.length>0,xlsxBinaryKeys:keys,unsupportedAttachments:unsupported},binary:bin}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3920,
1216
],
"id": "26a4ac9d-2a64-4b24-a2af-2e4caab7c197",
"name": "Preparar XLSX email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "eaadc66d-c3f5-417d-b945-5397809d08b9",
"leftValue": "={{ $json.hasXlsx }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
4848,
1088
],
"id": "6c433395-f347-45a6-bd7e-5d0c37b4bd9f",
"name": "¿Tiene XLSX email?"
},
{
"parameters": {
"jsCode": "const base=$json, bin=$binary||{}, keys=Array.isArray(base.xlsxBinaryKeys)?base.xlsxBinaryKeys:[]; const out=[]; let i=0;\nfor(const k of keys){const b=bin[k]; if(!b) continue; i++; const fn=String(b.fileName||`archivo-${i}.xlsx`); out.push({json:{...base,xlsxIndex:i-1,xlsxFilename:fn,tempUploadName:`_TEMP_WMC_EMAIL_XLSX_${Date.now()}_${i}_${fn.replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,90)}`},binary:{data:b}})}\nreturn out.length?out:[{json:{...base,hasXlsx:false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5088,
928
],
"id": "76c6166e-02e0-4119-89c6-babb7682c06a",
"name": "Expandir XLSX email"
},
{
"parameters": {
"name": "={{ $json.tempUploadName }}",
"driveId": {
"__rl": true,
"value": "My Drive",
"mode": "list"
},
"folderId": {
"__rl": true,
"value": "root",
"mode": "list",
"cachedResultName": "/ (Root folder)"
},
"options": {
"simplifyOutput": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
5328,
928
],
"id": "262b6267-8259-407d-a105-831750270537",
"name": "Subir XLSX email temporal a Drive",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const ups=$input.all(); let src=[]; try{src=$items(\"Expandir XLSX email\");}catch{} return ups.map((it,i)=>({json:{...(src[i]?.json||{}),tempXlsxDriveId:String(it.json?.id||'')||null,tempXlsxUploadError:it.json?.error||null},pairedItem:{item:i}}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5568,
928
],
"id": "53d5ef62-ba53-4a13-abf0-02223658ac6d",
"name": "Mapear XLSX email temporal"
},
{
"parameters": {
"method": "POST",
"url": "={{ 'https://www.googleapis.com/drive/v2/files/' + encodeURIComponent($json.tempXlsxDriveId || 'invalid') + '/copy?convert=true' }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"timeout": 60000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5808,
928
],
"id": "212fa06d-0a76-4e04-a540-7a101a26d283",
"name": "Convertir XLSX email a Google Sheets",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const xs=$input.all(); let src=[]; try{src=$items(\"Mapear XLSX email temporal\");}catch{} return xs.map((it,i)=>({json:{...(src[i]?.json||{}),tempGoogleSheetId:String(it.json?.id||'')||null,tempGoogleSheetMimeType:String(it.json?.mimeType||''),tempConversionError:it.json?.error||null},pairedItem:{item:i}}));"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6048,
928
],
"id": "c30d3b4a-58f2-45fd-ad7e-b9f3773c930f",
"name": "Mapear XLSX convertido email"
},
{
"parameters": {
"url": "={{ 'https://sheets.googleapis.com/v4/spreadsheets/' + encodeURIComponent($json.tempGoogleSheetId || 'invalid') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "includeGridData",
"value": "true"
},
{
"name": "fields",
"value": "spreadsheetId,properties(title),sheets(properties(sheetId,title,index,hidden,gridProperties(rowCount,columnCount)),data(startRow,startColumn,rowData(values(formattedValue,effectiveValue))))"
}
]
},
"options": {
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
6288,
928
],
"id": "555ba82c-e8ca-488a-b817-db114a0b9954",
"name": "Leer todas las hojas XLSX email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar XLSX email\"].json; const incoming=$input.all(); let metas=[]; try{metas=$items(\"Mapear XLSX convertido email\");}catch{}\nconst MAX=70000, ROWS=1500, COLS=100, SHEETS=40; let chars=0,trunc=false; const blocks=[],inventory=[],warn=[];\nconst clean=v=>String(v??'').replace(/[\\u0000-\\u001F]+/g,' ').replace(/\\s+/g,' ').trim();\nfunction col(i){let n=i+1,s='';while(n){const r=(n-1)%26;s=String.fromCharCode(65+r)+s;n=Math.floor((n-1)/26);}return s;}\nfunction val(c){if(!c||typeof c!=='object')return'';if(c.formattedValue!=null)return clean(c.formattedValue);const e=c.effectiveValue||{};for(const k of ['stringValue','numberValue','boolValue','formulaValue'])if(e[k]!=null)return clean(e[k]);return'';}\nfor(let fi=0;fi<incoming.length;fi++){const raw=incoming[fi]?.json||{}, meta=metas[fi]?.json||{}, fn=clean(meta.xlsxFilename||`archivo-${fi+1}.xlsx`), sheets=Array.isArray(raw.sheets)?raw.sheets.slice(0,SHEETS):[]; const names=[]; if(!sheets.length){warn.push(fn+': no se pudieron leer hojas.');continue;} for(const sh of sheets){if(chars>=MAX){trunc=true;break;}const p=sh?.properties||{}, sn=clean(p.title||`Hoja ${names.length+1}`);names.push(sn);const rm=new Map();for(const g of (sh.data||[])){const sr=Number(g?.startRow||0),sc=Number(g?.startColumn||0);for(let r=0;r<(g.rowData||[]).length;r++){const ar=sr+r;if(ar>=ROWS){trunc=true;break;}for(let c=0;c<(g.rowData[r]?.values||[]).length;c++){const ac=sc+c;if(ac>=COLS){trunc=true;break;}const v=val(g.rowData[r].values[c]);if(v){if(!rm.has(ar))rm.set(ar,new Map());rm.get(ar).set(ac,v);}}}}const lines=[];for(const r of [...rm.keys()].sort((a,b)=>a-b)){const cells=[...rm.get(r).entries()].sort((a,b)=>a[0]-b[0]);const line=`Fila ${r+1}: `+cells.map(([c,v])=>`[${col(c)}] ${v}`).join(' | ');if(chars+line.length>MAX){trunc=true;break;}lines.push(line);chars+=line.length+1;}blocks.push(`Archivo: ${fn}\\nHoja analizada: ${sn}${p.hidden?' (oculta)':''}\\n${lines.length?lines.join('\\n'):'(Sin contenido legible)'}`);}inventory.push({file:fn,sheets:names});}\nif(trunc)warn.push('Extracción XLSX truncada por límite de seguridad.');\nreturn [{json:{...base,spreadsheetAnalysis:blocks.join('\\n\\n').trim()||null,spreadsheetAnalysisError:blocks.length===0,spreadsheetSheetNames:inventory,spreadsheetExtractionWarnings:warn}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6528,
928
],
"id": "e25959cf-4a9d-440d-89e6-e77732472f69",
"name": "Agregar análisis XLSX email"
},
{
"parameters": {
"jsCode": "let metas=[];try{metas=$items(\"Mapear XLSX convertido email\");}catch{}const out=[],seen=new Set();for(const m0 of metas){const m=m0.json||{};for(const id0 of [m.tempGoogleSheetId,m.tempXlsxDriveId]){const id=String(id0||'').trim();if(id&&!seen.has(id)){seen.add(id);out.push({json:{deleteFileId:id}});}}}return out.length?out:[{json:{deleteFileId:null}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
6768,
928
],
"id": "959e39a9-fd46-4ae5-b9f5-2ee81f418988",
"name": "Preparar limpieza XLSX email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "873da85e-f479-4fe3-85b3-95c6f9c105e8",
"leftValue": "={{ !!$json.deleteFileId }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
7008,
928
],
"id": "c992c380-1830-4340-9adf-a54fc401df24",
"name": "¿Hay temporal XLSX?"
},
{
"parameters": {
"operation": "deleteFile",
"fileId": {
"__rl": true,
"value": "={{ $json.deleteFileId }}",
"mode": "id"
},
"options": {
"deletePermanently": true
}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
7248,
800
],
"id": "d924d82b-5ff6-4ab6-b84c-369cce1a95eb",
"name": "Eliminar temporal XLSX email",
"retryOnFail": true,
"maxTries": 2,
"waitBetweenTries": 1500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Agregar análisis XLSX email\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7488,
800
],
"id": "0d5af946-c85f-47f4-a11f-a947696196af",
"name": "Restaurar base tras limpieza XLSX"
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Agregar análisis XLSX email\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7248,
1040
],
"id": "8d0f1365-ea58-4f3f-9fcd-edcc09773181",
"name": "Restaurar base sin limpieza XLSX"
},
{
"parameters": {
"jsCode": "return [{json:{...$json,spreadsheetAnalysis:null,spreadsheetAnalysisError:false,spreadsheetSheetNames:[],spreadsheetExtractionWarnings:[]}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5088,
1248
],
"id": "3dfe6356-38d4-4be1-b08a-18ff31309002",
"name": "Sin XLSX email"
},
{
"parameters": {
"jsCode": "return [{json:$json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
7728,
1088
],
"id": "b447a80b-ee83-4c9d-850e-a2dfe62f1a9a",
"name": "Base email lista para agente"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_ingest",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_gmail_message_id:$json.gmailMessageId,p_sender_email:$json.senderEmail,p_sender_name:$json.senderName,p_subject:$json.subject,p_body_text:$json.bodyText,p_body_html:$json.bodyHtml||null,p_attachments:$json.attachmentMeta||[],p_country_code:$json.countryCode||null}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
7968,
1088
],
"id": "26cb64c2-0b25-4d30-b054-d2a991ba468f",
"name": "Supabase - Ingestar email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500
},
{
"parameters": {
"jsCode": "const base=$node[\"Base email lista para agente\"].json; const raw=$json||{}; const ing=raw.body&&typeof raw.body==='object'?raw.body:(raw.data&&typeof raw.data==='object'?raw.data:raw);\nconst parts=[String(base.bodyText||'').trim()];\nif(base.imageAnalysis)parts.push('[ANÁLISIS REAL DE IMÁGENES ADJUNTAS]\\n'+base.imageAnalysis);\nif(base.documentAnalysis)parts.push('[ANÁLISIS REAL DE PDF ADJUNTOS]\\n'+base.documentAnalysis);\nif(base.audioTranscription)parts.push('[TRANSCRIPCIÓN REAL DE AUDIO ADJUNTO]\\n'+base.audioTranscription);\nif(base.spreadsheetAnalysis)parts.push('[CONTENIDO REAL EXTRAÍDO DE XLSX ADJUNTO]\\n'+base.spreadsheetAnalysis);\nif((base.unsupportedAttachments||[]).length)parts.push('[ADJUNTOS NO ANALIZADOS AUTOMÁTICAMENTE]\\n'+base.unsupportedAttachments.map(a=>`${a.filename} (${a.mediaType})`).join('\\n'));\nreturn [{json:{...base,ingest:ing,agentRequest:{gmailThreadId:base.gmailThreadId,gmailMessageId:base.gmailMessageId,senderEmail:base.senderEmail,senderName:base.senderName,text:parts.filter(Boolean).join('\\n\\n'),attachments:[],countryCode:base.countryCode,history:Array.isArray(ing.history)?ing.history:[],context:ing.context&&typeof ing.context==='object'?ing.context:{},emailMeta:{subject:base.subject,to:base.to,cc:base.cc,sentAt:base.sentAt,attachmentMeta:base.attachmentMeta||[],spreadsheetSheetNames:base.spreadsheetSheetNames||[]}}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
8208,
1088
],
"id": "02146f13-9a85-4727-8d27-a81a1c3d07fa",
"name": "Construir solicitud agente email"
},
{
"parameters": {
"method": "POST",
"url": "https://agenteit.digitalcompass.agency/webhook/cotizador-wmc-email-agent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-WMC-Internal-Secret",
"value": "fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.agentRequest) }}",
"options": {
"timeout": 240000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
8448,
1088
],
"id": "d13eba8c-3cc5-4c21-a8f8-a60b048d15ee",
"name": "Agente WMC - Procesar email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 4000,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir solicitud agente email\"].json; const raw=$json||{}; const a=(raw.body&&typeof raw.body==='object')?raw.body:raw; const cfg=base.ingest?.config||{};\nconst disposition=String(a.emailDisposition||'process').toLowerCase(); const action=String(a.action||'chat'); const quote=a.quote&&typeof a.quote==='object'?a.quote:null; const total=Number(quote?.totalUsd||0)||0; const threshold=Number(cfg.approval_threshold_usd??cfg.approvalThresholdUsd??10000)||10000;\nconst nonTariff=[]; if(quote&&Array.isArray(quote.items)){for(const it of quote.items){const amount=Math.abs(Number(it?.totalUsd||0));if(!(amount>0))continue;const code=String(it?.metadata?.priceSourceCode||it?.priceSourceCode||'').toUpperCase();if(code!=='T')nonTariff.push({description:String(it?.description||''),code:code||'E',amount});}}\nconst reasons=[];if(total>threshold)reasons.push({code:'OVER_10000',text:`Total USD ${total.toFixed(2)} supera el umbral de USD ${threshold.toFixed(2)}.`});if(nonTariff.length)reasons.push({code:'NON_TARIFF',text:`${nonTariff.length} partida(s) usan referencia fuera del tarifario oficial.`,items:nonTariff});\nconst approvalRequired=!!quote && ['generate_quote','generate_proposal','generate_monthly_glm'].includes(action) && reasons.length>0;\nconst generatedActions=['generate_quote','generate_proposal','generate_monthly_glm','generate_image'];\nconst artifactFailure=generatedActions.includes(action) && !a.artifactUrl;\nif(artifactFailure){\n a.reply='No pude generar el archivo solicitado en este momento. Por favor responde a este mismo correo para reintentarlo.';\n a.warnings=[...(Array.isArray(a.warnings)?a.warnings:[]),'El artefacto no fue generado; no se envió ningún archivo.'];\n}\nlet customerMode='final'; if(disposition==='ignore')customerMode='ignore'; else if(action==='chat'||artifactFailure)customerMode='clarification'; else if(approvalRequired)customerMode='approval';\nconst artifactType=String(a.artifactType||''); const artifactId=String(a.artifactId||''); const shouldExport=!!artifactId&&['quote','proposal','monthly_glm'].includes(artifactType);\nreturn [{json:{...base,agent:a,config:cfg,customerMode,approvalRequired,approvalReasons:reasons,nonTariffItems:nonTariff,totalUsd:total,thresholdUsd:threshold,artifactType,artifactId,artifactUrl:a.artifactUrl||null,artifactTitle:a.title||quote?.project||'WMC',quote,shouldExport,artifactFailure}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
8688,
1088
],
"id": "339b335b-e1ad-4696-92a3-43c4bcb7d437",
"name": "Evaluar respuesta agente email"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "93182a6b-e065-4c35-93a8-e5c81bcddd2b",
"leftValue": "={{ $json.customerMode }}",
"rightValue": "ignore",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
8928,
1088
],
"id": "81685b4e-e097-456a-8a99-511234820fc6",
"name": "¿Ignorar correo?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
9168,
928
],
"id": "f80493b2-681c-491c-a844-605f26421534",
"name": "Fin - Correo fuera de alcance"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "257b6ccb-e648-4422-bd6d-025089fed298",
"leftValue": "={{ $json.approvalRequired }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9168,
1248
],
"id": "e8fc2f77-6ee2-4c75-916c-975c282e8fde",
"name": "¿Requiere aprobación interna?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_create_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_quote:$json.quote,p_document_url:$json.artifactUrl,p_artifact_id:$json.artifactId,p_artifact_type:$json.artifactType,p_artifact_title:$json.artifactTitle,p_customer_gmail_message_id:$json.gmailMessageId,p_reason:$json.approvalReasons}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
9408,
1488
],
"id": "d14f3a22-591f-495a-9f49-63f218e8dbe0",
"name": "Supabase - Crear aprobación email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500
},
{
"parameters": {
"jsCode": "const base=$node[\"Evaluar respuesta agente email\"].json;const raw=$json||{};const r=raw.body&&typeof raw.body==='object'?raw.body:raw;const approvalId=String(r.approvalId||'');\nconst esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));\nconst q=base.quote||{};const items=(base.nonTariffItems||[]).map(x=>`<li style=\"margin:5px 0\"><b>${esc(x.code)}</b> · ${esc(x.description)} · USD ${Number(x.amount||0).toFixed(2)}</li>`).join('');\nconst reasons=(base.approvalReasons||[]).map(x=>`<div style=\"margin:8px 0;padding:10px 12px;border-left:4px solid #FF8C00;background:#FFF8E1;color:#4A4A4A\">${esc(x.text)}</div>`).join('');\nconst html=`<div style=\"font-family:Arial,sans-serif;background:#f5f5f5;padding:24px\"><div style=\"max-width:720px;margin:auto;background:#fff;border:1px solid #e1e1e1;border-radius:14px;overflow:hidden\"><div style=\"height:6px;background:#6CC24A\"></div><div style=\"padding:26px 30px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" alt=\"GomezLee Marketing\" style=\"max-width:210px;height:auto\"><div style=\"margin-top:22px;color:#4F758B;font-size:12px;font-weight:bold;letter-spacing:1px\">COTIZADOR WALMART CONNECT · APROBACIÓN INTERNA</div><h2 style=\"color:#4F758B;margin:8px 0 4px\">Cotización pendiente de aprobación</h2><p style=\"color:#4A4A4A;margin-top:8px\">El agente preparó una cotización recibida por correo que no puede enviarse automáticamente.</p>${reasons}<table style=\"width:100%;border-collapse:collapse;margin:18px 0;font-size:14px\"><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold;width:32%\">Proyecto</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.project||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Anunciante</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.advertiser||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">País</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(q.country||q.countryCode||'—')}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Solicitante</td><td style=\"padding:9px;border-bottom:1px solid #eee\">${esc(base.senderEmail)}</td></tr><tr><td style=\"padding:9px;background:#EEF6E8;color:#4F758B;font-weight:bold\">Total</td><td style=\"padding:9px;font-size:18px;font-weight:bold;color:#4F758B\">USD ${Number(base.totalUsd||0).toFixed(2)}</td></tr></table>${items?`<div style=\"color:#4F758B;font-weight:bold;margin-top:16px\">Partidas fuera de tarifario</div><ul style=\"color:#4A4A4A\">${items}</ul>`:''}<div style=\"margin:20px 0;padding:14px;background:#D6E8F4;border-radius:10px;color:#4F758B\"><b>Para decidir, responde a este mismo correo:</b><br><b>APROBAR</b> · envía la cotización al cliente.<br><b>RECHAZAR</b> · no la envía.<br><b>CAMBIAR:</b> seguido de la modificación solicitada · el agente regenera el borrador y vuelve a pedir aprobación.</div>${base.artifactUrl?`<p><a href=\"${esc(base.artifactUrl)}\" style=\"color:#4F758B;font-weight:bold\">Abrir borrador en Google Workspace</a></p>`:''}<div style=\"margin-top:24px;border-top:1px solid #ddd;padding-top:12px;color:#6B8FA3;font-size:11px\">Referencia interna: ${esc(approvalId)}</div></div></div></div>`;\nconst approverEmails=(Array.isArray(base.config?.approver_emails)?base.config.approver_emails:(Array.isArray(base.emailConfig?.approver_emails)?base.emailConfig.approver_emails:['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'])).map(x=>String(x||'').trim()).filter(Boolean);return [{json:{...base,approvalId,requiredApprovals:Number(r.requiredApprovals||1),approvalSubject:`[APROBACIÓN WMC] ${q.project||q.advertiser||'Cotización'} · USD ${Number(base.totalUsd||0).toFixed(2)}`,approvalHtml:html,approverList:approverEmails.join(', '),approverEmails}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
9648,
1488
],
"id": "f15c6913-b9ee-47f9-9eb8-03529ff1b481",
"name": "Preparar correo aprobación GLM"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "dccfd9d3-857b-4b82-a269-6eef3029549d",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9888,
1488
],
"id": "5a76b54f-0585-438c-ad80-be0c812e27ad",
"name": "¿Adjuntar borrador a aprobación?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
10320,
1408
],
"id": "975d8649-99b7-41d0-993a-ce032b6fd94a",
"name": "Descargar borrador para aprobación",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar correo aprobación GLM\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}\nreturn [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10560,
1408
],
"id": "79448614-99a4-4125-a885-baf0f2da5d9f",
"name": "Preparar adjunto aprobación"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "7eb6cac5-d384-4161-9ac3-7b4ade92b248",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
11008,
1376
],
"id": "24d47913-b611-4203-ae4b-04be6e8311b9",
"name": "¿Borrador descargado?"
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11552,
1264
],
"id": "bf6b11ec-3341-42ad-b433-316684ad660c",
"name": "Gmail - Enviar aprobación con adjunto",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "64450f47-d0b4-424f-a091-341c4a34c2cd",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11776,
1472
],
"id": "cc24abfe-a768-4cb8-a227-575a8695bcd6",
"name": "Gmail - Enviar aprobación sin adjunto",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "b538ae39-7ec0-496a-a263-ce5263a9499f",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "return [{json:{...$json,exportOk:false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10992,
1856
],
"id": "5c3cec29-debb-4d98-8a51-6fcba1561663",
"name": "Preparar aprobación sin exportar"
},
{
"parameters": {
"sendTo": "=iaracena@gomezleemarketing.com",
"subject": "={{ $json.approvalSubject }}",
"message": "={{ $json.approvalHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect | GomezLee Marketing"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11232,
1856
],
"id": "78b06108-0570-4e13-939b-0c722ff2fdcb",
"name": "Gmail - Enviar aprobación solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "f13b8337-eee5-4a66-846d-908c2ea31ad9",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_set_approval_gmail_thread",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$node['Preparar correo aprobación GLM'].json.approvalId,p_approval_gmail_thread_id:$json.threadId,p_approval_gmail_message_id:$json.id}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13376,
1680
],
"id": "5a9dafcd-c828-433b-aa0b-1d7d56fc5316",
"name": "Supabase - Vincular hilo de aprobación",
"continueOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$node['Evaluar respuesta agente email'].json.gmailThreadId,p_gmail_message_id:'approval-out-'+$node['Preparar correo aprobación GLM'].json.approvalId,p_direction:'internal_out',p_from_email:'wmc@gomezlee.marketing',p_to_emails:$node['Preparar correo aprobación GLM'].json.approverEmails,p_subject:$node['Preparar correo aprobación GLM'].json.approvalSubject,p_body_text:'Solicitud de aprobación interna de cotización WMC.',p_body_html:$node['Preparar correo aprobación GLM'].json.approvalHtml,p_attachments:[],p_metadata:{approvalId:$node['Preparar correo aprobación GLM'].json.approvalId},p_status:'pending_approval'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13616,
1680
],
"id": "e7d604e0-1355-4350-8869-3c363498d708",
"name": "Supabase - Registrar solicitud aprobación",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
13856,
1680
],
"id": "c599c6f8-093e-459e-8390-b14279ccebe8",
"name": "Fin - Esperando aprobación"
},
{
"parameters": {
"jsCode": "const b=$json;const a=b.agent||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const name=String(b.senderName||'').trim();const greeting=name?`Hola ${esc(name.split(/\\s+/)[0])},`:'Hola,';const reply=esc(a.reply||'').replace(/\\n/g,'<br>');const isClar=b.customerMode==='clarification';const title=isClar?'Necesitamos una confirmación para continuar':'Cotización Walmart Connect';const intro=isClar?'Gracias por tu solicitud. Para continuar correctamente necesitamos confirmar lo siguiente:':'La solicitud fue procesada. Encontrarás el archivo correspondiente adjunto o disponible en el enlace incluido.';\nconst html=`<div style=\"font-family:Arial,sans-serif;background:#f5f7fa;padding:24px\"><div style=\"max-width:700px;margin:auto;background:#fff;border:1px solid #e5e8ec;border-radius:14px;overflow:hidden\"><div style=\"padding:26px 30px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/wallmart-logo.jpg\" alt=\"Walmart Connect\" style=\"max-width:230px;height:auto\"><h2 style=\"color:#041E42;margin:22px 0 8px\">${esc(title)}</h2><p style=\"color:#4A4A4A;line-height:1.55\">${greeting}</p><p style=\"color:#4A4A4A;line-height:1.55\">${esc(intro)}</p><div style=\"margin:18px 0;padding:14px 16px;border-left:4px solid #00BDE3;background:#F5FBFE;color:#041E42;line-height:1.55\">${reply||'Listo.'}</div>${!isClar&&b.artifactUrl?`<p style=\"margin:18px 0\"><a href=\"${esc(b.artifactUrl)}\" style=\"color:#0071CE;font-weight:bold\">Abrir archivo en Google Workspace</a></p>`:''}${isClar?'<p style=\"color:#4A4A4A\">Por favor responde a este mismo correo con la información solicitada y continuaremos desde aquí.</p>':'<p style=\"color:#4A4A4A\">Quedamos atentos a cualquier comentario o ajuste.</p>'}<div style=\"margin-top:26px;padding-top:14px;border-top:1px solid #e5e8ec;color:#6b7280;font-size:11px\">Walmart Connect · Gestión automatizada de cotizaciones</div></div></div></div>`;return [{json:{...b,customerHtml:html,customerSubject:b.subject}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
9408,
1168
],
"id": "ee0eab64-c0ec-4e4b-800b-e1942931944c",
"name": "Construir HTML cliente Walmart"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "e94406c9-0285-4541-ab19-a06c44a85b99",
"leftValue": "={{ $json.customerMode }}",
"rightValue": "clarification",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9648,
1168
],
"id": "b5f91adb-ca7d-4f7c-8680-a6697855b7d1",
"name": "¿Es aclaración?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
10192,
752
],
"id": "92fd8304-6172-4aa1-8067-cf2edc56905f",
"name": "Gmail - Responder aclaración cliente",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "160a5c37-d2e5-4ae9-8c18-327091bf22e5",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "1aebba2a-7e1b-47b2-b464-7835a163efe1",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
9888,
1280
],
"id": "f58741f6-91f1-4843-b35c-619046a2839e",
"name": "¿Adjuntar archivo al cliente?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
10208,
1008
],
"id": "f43c7d77-f75f-4e9c-b067-92d62b151074",
"name": "Descargar artefacto para cliente",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir HTML cliente Walmart\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}return [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
10448,
1008
],
"id": "3d6acf36-9b2a-46b2-8253-3bba8b2e09bc",
"name": "Preparar adjunto cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "f45ceb76-0896-4be4-bd24-03175f38373c",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
10736,
976
],
"id": "f9f98ee7-51c2-4c8d-948d-bfc26f480705",
"name": "¿Archivo cliente descargado?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11248,
656
],
"id": "c7b347ba-e3a0-47b7-87ec-5f60858a0162",
"name": "Gmail - Responder cliente con archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ced5a909-e80a-4a90-8da6-cdd9b9f2d13d",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
11088,
1088
],
"id": "d1706a6c-4fb8-46c7-aba1-2e0b63ccc99a",
"name": "Gmail - Responder cliente sin archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "541a4fe0-64c3-4eb0-acbe-65f3082d2845",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
10320,
1184
],
"id": "01ba8fb0-98c7-4f97-a5d6-1b0d754ddee8",
"name": "Gmail - Responder cliente solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "7520e58c-aa85-4301-be4d-b74d633610b4",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const base=$node[\"Construir HTML cliente Walmart\"].json;const g=$json||{};return [{json:{...base,sentGmailMessageId:String(g.id||''),sentGmailThreadId:String(g.threadId||base.gmailThreadId),sentOk:!!g.id}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
11632,
928
],
"id": "7ba23678-b7c4-4681-b8c5-75eadefb8977",
"name": "Postprocesar envío cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d974d8c2-6e06-41e0-880c-a2ab2f81f641",
"leftValue": "={{ !!$json.quote && $json.customerMode === \"final\" }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
11872,
928
],
"id": "793b94a2-a6d0-4c0b-8ca8-a611dc5c975f",
"name": "¿Guardar quote enviado?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_save_sent_quote",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_quote:$json.quote,p_document_url:$json.artifactUrl,p_artifact_id:$json.artifactId,p_artifact_type:$json.artifactType,p_artifact_title:$json.artifactTitle,p_sent_gmail_message_id:$json.sentGmailMessageId}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
12368,
800
],
"id": "d691d86e-23bc-4834-8651-3e35072b0c25",
"name": "Supabase - Guardar cotización enviada",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Postprocesar envío cliente\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
12608,
800
],
"id": "7698dbfb-1fac-4906-bf24-5a0a6316a48c",
"name": "Restaurar post envío tras guardar"
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Postprocesar envío cliente\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
12464,
1232
],
"id": "35274e8e-3527-4bb2-9b96-a23c40c6ab22",
"name": "Continuar sin guardar quote"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.gmailThreadId,p_gmail_message_id:$json.sentGmailMessageId,p_direction:'outbound',p_from_email:'wmc@gomezlee.marketing',p_to_emails:[$json.senderEmail],p_subject:$json.subject,p_body_text:$json.agent.reply||'',p_body_html:$json.customerHtml,p_attachments:$json.customerMode==='final'&&$json.artifactUrl?[{filename:$json.artifactTitle||'WMC',mediaType:$json.artifactType||'artifact',url:$json.artifactUrl}]:[],p_metadata:{action:$json.agent.action||'chat',artifactUrl:$json.artifactUrl||null},p_status:$json.customerMode==='clarification'?'awaiting_clarification':'sent'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
13408,
1248
],
"id": "5463d643-ff69-4a0e-bdcc-02a71bc746ec",
"name": "Supabase - Registrar respuesta al cliente",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
13648,
1248
],
"id": "87ab6e4b-9587-4a2d-abe9-011ba22e31b7",
"name": "Fin - Email cliente procesado"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_get_pending_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_gmail_thread_id:$json.gmailThreadId,p_approver_email:$json.senderEmail}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
720,
448
],
"id": "2885f662-e411-420a-bb10-e12588d7c594",
"name": "Supabase - Buscar aprobación pendiente",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const mail=$node[\"Normalizar correo entrante\"].json;\nconst raw=$json||{};\nconst r=raw.body&&typeof raw.body==='object'?raw.body:raw;\nconst found=!!r.found;\nconst normalize=v=>String(v||'').toLowerCase().normalize('NFD').replace(/[\\u0300-\\u036f]/g,'').replace(/\\s+/g,' ').trim();\nconst text=normalize(mail.bodyText||'');\nlet decision='change';\n// Se evalúa únicamente la respuesta nueva (el texto citado de Gmail ya fue retirado).\nif (/^(rechazar|rechazo|no aprobar|no apruebo|cancelar)\\b/.test(text)) decision='reject';\nelse if (/^(aprobar|apruebo|aprobado|confirmo|confirmado|adelante)\\b/.test(text)) decision='approve';\nelse if (/^(cambiar|cambio|modificar|ajustar|corregir)\\b/.test(text)) decision='change';\nreturn [{json:{...mail,pending:r,found,approval:r.approval||null,customerThread:r.customerThread||null,history:r.history||[],context:r.context||{},approvalDecision:decision,approvalInstructions:mail.bodyText}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
960,
448
],
"id": "87090417-f5f4-492a-a9f3-ee99a77f92d2",
"name": "Preparar respuesta de aprobación"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "2391c203-8c51-436b-a7c4-62e86f2963d1",
"leftValue": "={{ $json.found }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1200,
448
],
"id": "80a80c46-df48-4e3c-b658-db1f72f8bb8b",
"name": "¿Aprobación pendiente encontrada?"
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
1440,
208
],
"id": "2c48258c-8563-4f1b-9ca4-37d5ac6d93cc",
"name": "Fin - Sin aprobación pendiente"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$json.customerThread.gmailThreadId,p_gmail_message_id:$json.gmailMessageId,p_direction:'internal_in',p_from_email:$json.senderEmail,p_to_emails:['wmc@gomezlee.marketing'],p_subject:$json.subject,p_body_text:$json.bodyText,p_body_html:$json.bodyHtml||null,p_attachments:$json.attachmentMeta||[],p_metadata:{approvalId:$json.approval.id},p_status:'pending_approval'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1440,
528
],
"id": "a0fcc6ee-8aa6-4f58-8506-626bfbe42ba0",
"name": "Supabase - Registrar respuesta aprobador",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "return [{json:$node[\"Preparar respuesta de aprobación\"].json}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1680,
528
],
"id": "a362cd2f-e5ac-4bd5-a6e0-6279fef142b1",
"name": "Restaurar aprobación tras registro"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "70b77420-e9f5-45c2-a5ce-ba7c06d88ef9",
"leftValue": "={{ $json.approvalDecision }}",
"rightValue": "change",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
1920,
528
],
"id": "5be3f8fa-7c0b-4e38-b9fe-a4ce636fd7d2",
"name": "¿Solicita cambios internos?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_decide_approval",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_approver_email:$json.senderEmail,p_decision:$json.approvalDecision,p_note:$json.bodyText}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2160,
688
],
"id": "1d1234b9-dc97-480e-803f-8661b31645cb",
"name": "Supabase - Decidir aprobación",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Restaurar aprobación tras registro\"].json;const raw=$json||{};const r=raw.body&&typeof raw.body==='object'?raw.body:raw;return [{json:{...base,decisionResult:r,finalDecision:String(r.finalDecision||''),approvalFinalOk:r.ok!==false}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2400,
688
],
"id": "6230ea05-3cc2-4de8-a6f6-5cbd64936aa7",
"name": "Evaluar decisión interna"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "75942c37-1cb3-4221-a5ee-01dca0898f55",
"leftValue": "={{ $json.finalDecision }}",
"rightValue": "approved",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2640,
688
],
"id": "cc0e5278-4017-477d-944b-8531f812179d",
"name": "¿Aprobado final?"
},
{
"parameters": {
"jsCode": "const b=$json;const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const rejected=b.finalDecision==='rejected';const msg=rejected?'La cotización fue rechazada y no se enviará al cliente.':'La aprobación quedó registrada y continúa pendiente de las aprobaciones requeridas.';const html=`<div style=\"font-family:Arial,sans-serif;padding:20px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:190px\"><h3 style=\"color:#4F758B\">${rejected?'Cotización rechazada':'Aprobación registrada'}</h3><p style=\"color:#4A4A4A\">${esc(msg)}</p></div>`;return [{json:{...b,internalAckHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2880,
848
],
"id": "13d60b72-4de5-413f-8091-ac9a615d2b60",
"name": "Preparar confirmación decisión interna"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalAckHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3120,
848
],
"id": "c827ea05-0996-430d-818d-99c01e3decf6",
"name": "Gmail - Confirmar decisión al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "23dccd92-8d02-43bd-bca5-c96ce84abd6c",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3360,
848
],
"id": "63689e52-aad6-468f-8e61-9a851ae73c07",
"name": "Fin - Decisión interna registrada"
},
{
"parameters": {
"jsCode": "const b=$json;const a=b.approval||{};const q=a.candidateQuote||b.decisionResult?.candidateQuote||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const html=`<div style=\"font-family:Arial,sans-serif;background:#f5f7fa;padding:24px\"><div style=\"max-width:700px;margin:auto;background:white;border:1px solid #e5e8ec;border-radius:14px;padding:28px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/wallmart-logo.jpg\" style=\"max-width:230px\"><h2 style=\"color:#041E42\">Cotización Walmart Connect</h2><p style=\"color:#4A4A4A\">Hola,</p><p style=\"color:#4A4A4A;line-height:1.55\">Adjunto encontrarás la cotización solicitada para <b>${esc(q.project||'el proyecto indicado')}</b>.</p>${a.artifactUrl?`<p><a href=\"${esc(a.artifactUrl)}\" style=\"color:#0071CE;font-weight:bold\">Abrir cotización en Google Workspace</a></p>`:''}<p style=\"color:#4A4A4A\">Quedamos atentos a cualquier comentario o ajuste.</p></div></div>`;const type=String(a.artifactType||'');return [{json:{...b,quote:q,artifactId:a.artifactId,artifactUrl:a.artifactUrl,artifactType:type,artifactTitle:a.artifactTitle||q.project||'Cotizacion WMC',customerHtml:html,customerMessageId:a.customerGmailMessageId,shouldExport:!!a.artifactId&&['quote','proposal','monthly_glm'].includes(type)}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2880,
528
],
"id": "6325982d-9758-4b41-9b54-abb442790169",
"name": "Preparar envío aprobado al cliente"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d25c7755-c533-472c-b27e-62b8a46da16e",
"leftValue": "={{ $json.shouldExport }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
3120,
528
],
"id": "9fc5b7cf-f07f-48a3-96fe-dc48e432030d",
"name": "¿Adjuntar archivo aprobado?"
},
{
"parameters": {
"url": "={{ 'https://www.googleapis.com/drive/v3/files/' + encodeURIComponent($json.artifactId) + '/export?mimeType=' + encodeURIComponent($json.artifactType === 'proposal' ? 'application/pdf' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') }}",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
},
"timeout": 90000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3504,
272
],
"id": "3d9f2351-adea-48f2-a349-54d2fd3556ec",
"name": "Descargar artefacto aprobado",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 2500,
"credentials": {
"googleDriveOAuth2Api": {
"id": "g23xdGLZRzBGqKgH",
"name": "Isaac - Google Drive"
}
},
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar envío aprobado al cliente\"].json;const b=$binary?.data||null;if(b){b.fileName=(String(base.artifactTitle||'Cotizacion_WMC').replace(/[^a-zA-Z0-9._-]+/g,'_').slice(0,100))+(base.artifactType==='proposal'?'.pdf':'.xlsx');b.mimeType=base.artifactType==='proposal'?'application/pdf':'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';}return [{json:{...base,exportOk:!!b},binary:b?{data:b}:{}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3744,
272
],
"id": "074c1f03-b7bc-4d8d-a25c-76fa616db4d1",
"name": "Preparar adjunto aprobado"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "6d87afdd-9702-4c7a-809a-38f5b7331a0f",
"leftValue": "={{ $json.exportOk }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
4240,
224
],
"id": "14065d5b-400d-432f-b30e-83f3e408c1ff",
"name": "¿Archivo aprobado descargado?"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"attachmentsUi": {
"attachmentsBinary": [
{}
]
},
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
4480,
144
],
"id": "9b7f449f-2574-432c-b318-32c475f10ea7",
"name": "Gmail - Enviar aprobado con archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ab9cd32a-ae42-48f1-87ba-26e33714c900",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
4480,
352
],
"id": "a326b49f-39cd-41c1-aa43-670e4f348933",
"name": "Gmail - Enviar aprobado sin archivo",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "ff99c43e-af13-44ec-8ed5-63b891dbb5a5",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.customerMessageId }}",
"message": "={{ $json.customerHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3360,
640
],
"id": "7448f893-a0da-49d4-a0c8-6ac38f4a5459",
"name": "Gmail - Enviar aprobado solo enlace",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "0a92c11b-b768-4729-ac5a-d6547891db37",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {
"jsCode": "const base=$node[\"Preparar envío aprobado al cliente\"].json;const g=$json||{};return [{json:{...base,sentGmailMessageId:String(g.id||''),sentGmailThreadId:String(g.threadId||base.customerThread?.gmailThreadId||'')}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
5360,
384
],
"id": "506a308d-aaec-4d24-8634-9fdbe8aeeddc",
"name": "Postprocesar envío aprobado"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_mark_approval_sent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_sent_gmail_message_id:$json.sentGmailMessageId}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5600,
384
],
"id": "a1f193f6-61e8-42d9-a5dc-9dfa58b5da87",
"name": "Supabase - Marcar aprobación enviada",
"continueOnFail": true
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_record_message",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_gmail_thread_id:$node['Postprocesar envío aprobado'].json.customerThread.gmailThreadId,p_gmail_message_id:$node['Postprocesar envío aprobado'].json.sentGmailMessageId,p_direction:'outbound',p_from_email:'wmc@gomezlee.marketing',p_to_emails:[$node['Postprocesar envío aprobado'].json.customerThread.requesterEmail],p_subject:$node['Postprocesar envío aprobado'].json.customerThread.subject,p_body_text:'Cotización aprobada y enviada.',p_body_html:$node['Postprocesar envío aprobado'].json.customerHtml,p_attachments:[{filename:$node['Postprocesar envío aprobado'].json.artifactTitle,mediaType:$node['Postprocesar envío aprobado'].json.artifactType,url:$node['Postprocesar envío aprobado'].json.artifactUrl}],p_metadata:{approvalId:$node['Postprocesar envío aprobado'].json.approval.id},p_status:'sent'}) }",
"options": {
"timeout": 30000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
5840,
384
],
"id": "9299ffeb-f273-4512-8c6a-029931e7139f",
"name": "Supabase - Registrar envío aprobado cliente",
"continueOnFail": true
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
6080,
384
],
"id": "ad781ca1-ba7b-4850-ae31-2ed33cb7cf05",
"name": "Fin - Aprobación enviada al cliente"
},
{
"parameters": {
"jsCode": "const b=$node[\"Restaurar aprobación tras registro\"].json;const a=b.approval||{};return [{json:{...b,revisionRequest:{gmailThreadId:b.customerThread.gmailThreadId,gmailMessageId:b.gmailMessageId,senderEmail:b.senderEmail,senderName:b.senderName,text:`Revisión interna autorizada por ${b.senderEmail}:\\n${b.approvalInstructions}`,attachments:[],countryCode:b.customerThread.countryCode||null,history:b.history||[],context:b.context||{},emailMeta:{subject:b.customerThread.subject,internalApproval:true,approverEmail:b.senderEmail,requesterEmail:b.customerThread.requesterEmail},approvalRevision:{approvalId:a.id,approverEmail:b.senderEmail,instructions:b.approvalInstructions,candidateQuote:a.candidateQuote,artifactUrl:a.artifactUrl}}}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
368
],
"id": "3e523ab8-90fb-431e-ad5b-384ee83e03a7",
"name": "Preparar revisión interna para agente"
},
{
"parameters": {
"method": "POST",
"url": "https://agenteit.digitalcompass.agency/webhook/cotizador-wmc-email-agent",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-WMC-Internal-Secret",
"value": "fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify($json.revisionRequest) }}",
"options": {
"timeout": 240000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2400,
368
],
"id": "b9b37eb4-bedb-4bf4-b29e-983835b05c59",
"name": "Agente WMC - Aplicar cambios aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 4000,
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const b=$node[\"Preparar revisión interna para agente\"].json;const raw=$json||{};const a=raw.body&&typeof raw.body==='object'?raw.body:raw;const ready=!!(a.quote&&a.artifactUrl&&a.artifactId)&&a.action!=='chat';const q=a.quote||{};const nonT=[];for(const it of (q.items||[])){if(Number(it.totalUsd||0)>0){const c=String(it?.metadata?.priceSourceCode||'').toUpperCase()||'E';if(c!=='T')nonT.push({description:it.description,code:c,amount:Number(it.totalUsd||0)});}}const reasons=[];if(Number(q.totalUsd||0)>10000)reasons.push({code:'OVER_10000',text:`Total USD ${Number(q.totalUsd).toFixed(2)} supera USD 10,000.`});if(nonT.length)reasons.push({code:'NON_TARIFF',text:`${nonT.length} partida(s) fuera de tarifario.`,items:nonT});return [{json:{...b,revisionAgent:a,revisionReady:ready,revisionQuote:a.quote||null,revisionArtifactId:a.artifactId||null,revisionArtifactUrl:a.artifactUrl||null,revisionArtifactType:a.artifactType||null,revisionArtifactTitle:a.title||q.project||'WMC',revisionReasons:reasons}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2640,
368
],
"id": "6e2488a6-0781-45da-8fd5-e2ec64fab9ff",
"name": "Evaluar revisión interna"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "21c1085b-3260-4823-8161-2d59fba12d14",
"leftValue": "={{ $json.revisionReady }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
2880,
368
],
"id": "fe12a681-17e1-4863-aebe-eb77df9fec26",
"name": "¿Revisión regenerada?"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_replace_approval_candidate",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Authorization",
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08',p_approval_id:$json.approval.id,p_approver_email:$json.senderEmail,p_quote:$json.revisionQuote,p_document_url:$json.revisionArtifactUrl,p_artifact_id:$json.revisionArtifactId,p_artifact_type:$json.revisionArtifactType,p_artifact_title:$json.revisionArtifactTitle,p_reason:$json.revisionReasons}) }",
"options": {
"timeout": 40000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
3264,
-16
],
"id": "d2205239-e261-4540-89f3-8ec3b95bcae8",
"name": "Supabase - Reemplazar candidato aprobación",
"continueOnFail": true
},
{
"parameters": {
"jsCode": "const b=$node[\"Evaluar revisión interna\"].json;const q=b.revisionQuote||{};const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const html=`<div style=\"font-family:Arial,sans-serif;padding:22px;background:#f5f5f5\"><div style=\"max-width:700px;margin:auto;background:#fff;border-radius:12px;padding:26px;border-top:6px solid #6CC24A\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:200px\"><h2 style=\"color:#4F758B\">Borrador actualizado</h2><p style=\"color:#4A4A4A\">Se aplicaron los cambios solicitados. El nuevo total es <b>USD ${Number(q.totalUsd||0).toFixed(2)}</b>.</p>${b.revisionArtifactUrl?`<p><a href=\"${esc(b.revisionArtifactUrl)}\" style=\"color:#4F758B;font-weight:bold\">Abrir borrador actualizado</a></p>`:''}<div style=\"padding:14px;background:#D6E8F4;color:#4F758B;border-radius:8px\"><b>Responde a este hilo con APROBAR, RECHAZAR o CAMBIAR: ...</b></div></div></div>`;return [{json:{...b,internalRevisionHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3504,
-16
],
"id": "4b0e8f7e-8f97-4c15-b1dc-ad0cb3e6a3d0",
"name": "Preparar confirmación revisión GLM"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalRevisionHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3744,
-16
],
"id": "bd39629e-7f00-4024-8e06-b97b76da06ea",
"name": "Gmail - Enviar borrador actualizado al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "b5b19d95-d7d7-456e-ba99-2c60e80498a9",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3984,
-16
],
"id": "31181c4a-f6fe-43b0-96a2-784e0d809824",
"name": "Fin - Revisión pendiente nueva decisión"
},
{
"parameters": {
"jsCode": "const b=$json;const esc=s=>String(s??'').replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const msg=esc(b.revisionAgent?.reply||'Necesito una precisión adicional para aplicar el cambio.').replace(/\\n/g,'<br>');const html=`<div style=\"font-family:Arial,sans-serif;padding:22px\"><img src=\"https://dbit.digitalcompass.agency/storage/v1/object/public/public-assets/GLM_completo.png\" style=\"max-width:190px\"><h3 style=\"color:#4F758B\">Necesito confirmar un detalle del cambio</h3><div style=\"padding:12px;background:#D6E8F4;color:#4F758B\">${msg}</div><p style=\"color:#4A4A4A\">Responde a este mismo correo con la aclaración.</p></div>`;return [{json:{...b,internalRevisionHtml:html}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3152,
320
],
"id": "175d6f84-a294-41e3-bedd-9ebd7f3215d2",
"name": "Preparar aclaración cambio al aprobador"
},
{
"parameters": {
"operation": "reply",
"messageId": "={{ $json.gmailMessageId }}",
"message": "={{ $json.internalRevisionHtml }}",
"options": {
"appendAttribution": false,
"senderName": "Walmart Connect",
"replyToSenderOnly": true
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
3616,
464
],
"id": "5ecffd80-3047-438f-9855-30ee11bc5704",
"name": "Gmail - Pedir aclaración al aprobador",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000,
"webhookId": "e282116c-ad2a-4509-8f12-be7e95b06c14",
"credentials": {
"gmailOAuth2": {
"id": "8yUN5we9ms6Gjp3h",
"name": "WMC - Gmail - wmc@gomezlee.marketing"
}
}
},
{
"parameters": {},
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
3856,
464
],
"id": "f85e6ffd-e7f0-4732-b161-ceed68521561",
"name": "Fin - Esperando aclaración aprobador"
},
{
"parameters": {
"method": "POST",
"url": "https://dbit.digitalcompass.agency/rest/v1/rpc/cotizador_wmc_email_get_config",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"sendBody": true,
"contentType": "raw",
"rawContentType": "application/json",
"body": "={{ JSON.stringify({p_secret:'fLf-Fl4AcRL912NsWfC4wGwlfEZ9kvOXJ33ylUjXJ9prTuML4b2sSJt3tDrG5D08'}) }}",
"options": {
"timeout": 20000
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
-32,
528
],
"id": "74d66de7-d63a-4400-ba2b-498c01800035",
"name": "Supabase - Config canal email",
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 1500
},
{
"parameters": {
"jsCode": "const mail=$node[\"Normalizar correo entrante\"].json;\nconst raw=$json||{};\nconst cfg=(raw.body&&typeof raw.body==='object')?raw.body:(raw.data&&typeof raw.data==='object'?raw.data:raw);\nconst enabled=cfg.enabled===true || String(cfg.enabled||'').toLowerCase()==='true';\nconst allowTest=cfg.allow_test_sender===true || cfg.allowTestSender===true || String(cfg.allow_test_sender??cfg.allowTestSender??'').toLowerCase()==='true';\nconst testSender=String(cfg.test_sender_email??cfg.testSenderEmail??'iaracena@gomezleemarketing.com').trim().toLowerCase();\nconst walmartDomain=String(cfg.walmart_sender_domain??cfg.walmartSenderDomain??'walmart.com').trim().toLowerCase();\nconst approversRaw=cfg.approver_emails??cfg.approverEmails??['jgomez@gomezleemarketing.com','wlopez@gomezleemarketing.com'];\nconst approvers=(Array.isArray(approversRaw)?approversRaw:String(approversRaw||'').split(',')).map(x=>String(x||'').trim().toLowerCase()).filter(Boolean);\nconst sender=String(mail.senderEmail||'').trim().toLowerCase();\nconst domain=(sender.split('@')[1]||'').toLowerCase();\nconst isApprover=approvers.includes(sender);\nconst isSelf=sender==='wmc@gomezlee.marketing';\nconst isAllowedRequester=enabled && !isSelf && (domain===walmartDomain || (allowTest && sender===testSender));\nreturn [{json:{...mail,emailConfig:cfg,emailEnabled:enabled,allowTestSender:allowTest,testSender,walmartSenderDomain:walmartDomain,approvers,isApprover,isSelf,isAllowedRequester}}];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
208,
528
],
"id": "f0a4115a-e0c8-44ec-bf85-47cff0143b0a",
"name": "Aplicar configuración canal email"
}
],
"connections": {
"Gmail Trigger - WMC Inbox": {
"main": [
[
{
"node": "Normalizar correo entrante",
"type": "main",
"index": 0
}
]
]
},
"Normalizar correo entrante": {
"main": [
[
{
"node": "Supabase - Config canal email",
"type": "main",
"index": 0
}
]
]
},
"¿Respuesta de aprobador?": {
"main": [
[
{
"node": "Supabase - Buscar aprobación pendiente",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Remitente permitido?",
"type": "main",
"index": 0
}
]
]
},
"¿Remitente permitido?": {
"main": [
[
{
"node": "Preparar imágenes email",
"type": "main",
"index": 0
}
],
[
{
"node": "Fin - Remitente ignorado",
"type": "main",
"index": 0
}
]
]
},
"Preparar imágenes email": {
"main": [
[
{
"node": "¿Tiene imágenes email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene imágenes email?": {
"main": [
[
{
"node": "Gemini - Analizar imágenes email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin imágenes email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Analizar imágenes email": {
"main": [
[
{
"node": "Integrar análisis imágenes",
"type": "main",
"index": 0
}
]
]
},
"Integrar análisis imágenes": {
"main": [
[
{
"node": "Preparar PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Sin imágenes email": {
"main": [
[
{
"node": "Preparar PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Preparar PDFs email": {
"main": [
[
{
"node": "¿Tiene PDFs email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene PDFs email?": {
"main": [
[
{
"node": "Gemini - Analizar PDFs email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin PDFs email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Analizar PDFs email": {
"main": [
[
{
"node": "Integrar análisis PDFs",
"type": "main",
"index": 0
}
]
]
},
"Integrar análisis PDFs": {
"main": [
[
{
"node": "Preparar audio email",
"type": "main",
"index": 0
}
]
]
},
"Sin PDFs email": {
"main": [
[
{
"node": "Preparar audio email",
"type": "main",
"index": 0
}
]
]
},
"Preparar audio email": {
"main": [
[
{
"node": "¿Tiene audio email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene audio email?": {
"main": [
[
{
"node": "Gemini - Transcribir audio email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin audio email",
"type": "main",
"index": 0
}
]
]
},
"Gemini - Transcribir audio email": {
"main": [
[
{
"node": "Integrar transcripción audio",
"type": "main",
"index": 0
}
]
]
},
"Integrar transcripción audio": {
"main": [
[
{
"node": "Preparar XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Sin audio email": {
"main": [
[
{
"node": "Preparar XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Preparar XLSX email": {
"main": [
[
{
"node": "¿Tiene XLSX email?",
"type": "main",
"index": 0
}
]
]
},
"¿Tiene XLSX email?": {
"main": [
[
{
"node": "Expandir XLSX email",
"type": "main",
"index": 0
}
],
[
{
"node": "Sin XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Expandir XLSX email": {
"main": [
[
{
"node": "Subir XLSX email temporal a Drive",
"type": "main",
"index": 0
}
]
]
},
"Subir XLSX email temporal a Drive": {
"main": [
[
{
"node": "Mapear XLSX email temporal",
"type": "main",
"index": 0
}
]
]
},
"Mapear XLSX email temporal": {
"main": [
[
{
"node": "Convertir XLSX email a Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Convertir XLSX email a Google Sheets": {
"main": [
[
{
"node": "Mapear XLSX convertido email",
"type": "main",
"index": 0
}
]
]
},
"Mapear XLSX convertido email": {
"main": [
[
{
"node": "Leer todas las hojas XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Leer todas las hojas XLSX email": {
"main": [
[
{
"node": "Agregar análisis XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Agregar análisis XLSX email": {
"main": [
[
{
"node": "Preparar limpieza XLSX email",
"type": "main",
"index": 0
}
]
]
},
"Preparar limpieza XLSX email": {
"main": [
[
{
"node": "¿Hay temporal XLSX?",
"type": "main",
"index": 0
}
]
]
},
"¿Hay temporal XLSX?": {
"main": [
[
{
"node": "Eliminar temporal XLSX email",
"type": "main",
"index": 0
}
],
[
{
"node": "Restaurar base sin limpieza XLSX",
"type": "main",
"index": 0
}
]
]
},
"Eliminar temporal XLSX email": {
"main": [
[
{
"node": "Restaurar base tras limpieza XLSX",
"type": "main",
"index": 0
}
]
]
},
"Restaurar base tras limpieza XLSX": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Restaurar base sin limpieza XLSX": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Sin XLSX email": {
"main": [
[
{
"node": "Base email lista para agente",
"type": "main",
"index": 0
}
]
]
},
"Base email lista para agente": {
"main": [
[
{
"node": "Supabase - Ingestar email",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Ingestar email": {
"main": [
[
{
"node": "Construir solicitud agente email",
"type": "main",
"index": 0
}
]
]
},
"Construir solicitud agente email": {
"main": [
[
{
"node": "Agente WMC - Procesar email",
"type": "main",
"index": 0
}
]
]
},
"Agente WMC - Procesar email": {
"main": [
[
{
"node": "Evaluar respuesta agente email",
"type": "main",
"index": 0
}
]
]
},
"Evaluar respuesta agente email": {
"main": [
[
{
"node": "¿Ignorar correo?",
"type": "main",
"index": 0
}
]
]
},
"¿Ignorar correo?": {
"main": [
[
{
"node": "Fin - Correo fuera de alcance",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Requiere aprobación interna?",
"type": "main",
"index": 0
}
]
]
},
"¿Requiere aprobación interna?": {
"main": [
[
{
"node": "Supabase - Crear aprobación email",
"type": "main",
"index": 0
}
],
[
{
"node": "Construir HTML cliente Walmart",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Crear aprobación email": {
"main": [
[
{
"node": "Preparar correo aprobación GLM",
"type": "main",
"index": 0
}
]
]
},
"Preparar correo aprobación GLM": {
"main": [
[
{
"node": "¿Adjuntar borrador a aprobación?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar borrador a aprobación?": {
"main": [
[
{
"node": "Descargar borrador para aprobación",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar aprobación sin exportar",
"type": "main",
"index": 0
}
]
]
},
"Descargar borrador para aprobación": {
"main": [
[
{
"node": "Preparar adjunto aprobación",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto aprobación": {
"main": [
[
{
"node": "¿Borrador descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Borrador descargado?": {
"main": [
[
{
"node": "Gmail - Enviar aprobación con adjunto",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobación sin adjunto",
"type": "main",
"index": 0
}
]
]
},
"Preparar aprobación sin exportar": {
"main": [
[
{
"node": "Gmail - Enviar aprobación solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación con adjunto": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación sin adjunto": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobación solo enlace": {
"main": [
[
{
"node": "Supabase - Vincular hilo de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Vincular hilo de aprobación": {
"main": [
[
{
"node": "Supabase - Registrar solicitud aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar solicitud aprobación": {
"main": [
[
{
"node": "Fin - Esperando aprobación",
"type": "main",
"index": 0
}
]
]
},
"Construir HTML cliente Walmart": {
"main": [
[
{
"node": "¿Es aclaración?",
"type": "main",
"index": 0
}
]
]
},
"¿Es aclaración?": {
"main": [
[
{
"node": "Gmail - Responder aclaración cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "¿Adjuntar archivo al cliente?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar archivo al cliente?": {
"main": [
[
{
"node": "Descargar artefacto para cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Responder cliente solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Descargar artefacto para cliente": {
"main": [
[
{
"node": "Preparar adjunto cliente",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto cliente": {
"main": [
[
{
"node": "¿Archivo cliente descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Archivo cliente descargado?": {
"main": [
[
{
"node": "Gmail - Responder cliente con archivo",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Responder cliente sin archivo",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder aclaración cliente": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente con archivo": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente sin archivo": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Responder cliente solo enlace": {
"main": [
[
{
"node": "Postprocesar envío cliente",
"type": "main",
"index": 0
}
]
]
},
"Postprocesar envío cliente": {
"main": [
[
{
"node": "¿Guardar quote enviado?",
"type": "main",
"index": 0
}
]
]
},
"¿Guardar quote enviado?": {
"main": [
[
{
"node": "Supabase - Guardar cotización enviada",
"type": "main",
"index": 0
}
],
[
{
"node": "Continuar sin guardar quote",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Guardar cotización enviada": {
"main": [
[
{
"node": "Restaurar post envío tras guardar",
"type": "main",
"index": 0
}
]
]
},
"Restaurar post envío tras guardar": {
"main": [
[
{
"node": "Supabase - Registrar respuesta al cliente",
"type": "main",
"index": 0
}
]
]
},
"Continuar sin guardar quote": {
"main": [
[
{
"node": "Supabase - Registrar respuesta al cliente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar respuesta al cliente": {
"main": [
[
{
"node": "Fin - Email cliente procesado",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Buscar aprobación pendiente": {
"main": [
[
{
"node": "Preparar respuesta de aprobación",
"type": "main",
"index": 0
}
]
]
},
"Preparar respuesta de aprobación": {
"main": [
[
{
"node": "¿Aprobación pendiente encontrada?",
"type": "main",
"index": 0
}
]
]
},
"¿Aprobación pendiente encontrada?": {
"main": [
[
{
"node": "Supabase - Registrar respuesta aprobador",
"type": "main",
"index": 0
}
],
[
{
"node": "Fin - Sin aprobación pendiente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar respuesta aprobador": {
"main": [
[
{
"node": "Restaurar aprobación tras registro",
"type": "main",
"index": 0
}
]
]
},
"Restaurar aprobación tras registro": {
"main": [
[
{
"node": "¿Solicita cambios internos?",
"type": "main",
"index": 0
}
]
]
},
"¿Solicita cambios internos?": {
"main": [
[
{
"node": "Preparar revisión interna para agente",
"type": "main",
"index": 0
}
],
[
{
"node": "Supabase - Decidir aprobación",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Decidir aprobación": {
"main": [
[
{
"node": "Evaluar decisión interna",
"type": "main",
"index": 0
}
]
]
},
"Evaluar decisión interna": {
"main": [
[
{
"node": "¿Aprobado final?",
"type": "main",
"index": 0
}
]
]
},
"¿Aprobado final?": {
"main": [
[
{
"node": "Preparar envío aprobado al cliente",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar confirmación decisión interna",
"type": "main",
"index": 0
}
]
]
},
"Preparar confirmación decisión interna": {
"main": [
[
{
"node": "Gmail - Confirmar decisión al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Confirmar decisión al aprobador": {
"main": [
[
{
"node": "Fin - Decisión interna registrada",
"type": "main",
"index": 0
}
]
]
},
"Preparar envío aprobado al cliente": {
"main": [
[
{
"node": "¿Adjuntar archivo aprobado?",
"type": "main",
"index": 0
}
]
]
},
"¿Adjuntar archivo aprobado?": {
"main": [
[
{
"node": "Descargar artefacto aprobado",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobado solo enlace",
"type": "main",
"index": 0
}
]
]
},
"Descargar artefacto aprobado": {
"main": [
[
{
"node": "Preparar adjunto aprobado",
"type": "main",
"index": 0
}
]
]
},
"Preparar adjunto aprobado": {
"main": [
[
{
"node": "¿Archivo aprobado descargado?",
"type": "main",
"index": 0
}
]
]
},
"¿Archivo aprobado descargado?": {
"main": [
[
{
"node": "Gmail - Enviar aprobado con archivo",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail - Enviar aprobado sin archivo",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado con archivo": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado sin archivo": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar aprobado solo enlace": {
"main": [
[
{
"node": "Postprocesar envío aprobado",
"type": "main",
"index": 0
}
]
]
},
"Postprocesar envío aprobado": {
"main": [
[
{
"node": "Supabase - Marcar aprobación enviada",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Marcar aprobación enviada": {
"main": [
[
{
"node": "Supabase - Registrar envío aprobado cliente",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Registrar envío aprobado cliente": {
"main": [
[
{
"node": "Fin - Aprobación enviada al cliente",
"type": "main",
"index": 0
}
]
]
},
"Preparar revisión interna para agente": {
"main": [
[
{
"node": "Agente WMC - Aplicar cambios aprobador",
"type": "main",
"index": 0
}
]
]
},
"Agente WMC - Aplicar cambios aprobador": {
"main": [
[
{
"node": "Evaluar revisión interna",
"type": "main",
"index": 0
}
]
]
},
"Evaluar revisión interna": {
"main": [
[
{
"node": "¿Revisión regenerada?",
"type": "main",
"index": 0
}
]
]
},
"¿Revisión regenerada?": {
"main": [
[
{
"node": "Supabase - Reemplazar candidato aprobación",
"type": "main",
"index": 0
}
],
[
{
"node": "Preparar aclaración cambio al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Reemplazar candidato aprobación": {
"main": [
[
{
"node": "Preparar confirmación revisión GLM",
"type": "main",
"index": 0
}
]
]
},
"Preparar confirmación revisión GLM": {
"main": [
[
{
"node": "Gmail - Enviar borrador actualizado al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Enviar borrador actualizado al aprobador": {
"main": [
[
{
"node": "Fin - Revisión pendiente nueva decisión",
"type": "main",
"index": 0
}
]
]
},
"Preparar aclaración cambio al aprobador": {
"main": [
[
{
"node": "Gmail - Pedir aclaración al aprobador",
"type": "main",
"index": 0
}
]
]
},
"Gmail - Pedir aclaración al aprobador": {
"main": [
[
{
"node": "Fin - Esperando aclaración aprobador",
"type": "main",
"index": 0
}
]
]
},
"Supabase - Config canal email": {
"main": [
[
{
"node": "Aplicar configuración canal email",
"type": "main",
"index": 0
}
]
]
},
"Aplicar configuración canal email": {
"main": [
[
{
"node": "¿Respuesta de aprobador?",
"type": "main",
"index": 0
}
]
]
}
},
"authors": "Isaac Aracena",
"name": "Version 5c4f87b4",
"description": "",
"autosaved": true,
"workflowPublishHistory": [
{
"createdAt": "2026-08-30T00:40:38.081Z",
"id": 5317,
"workflowId": "p4rDtVLIWyPuK0LI",
"versionId": "5c4f87b4-f17a-4b66-9600-388931fcd2b9",
"event": "activated",
"userId": "0a88c0b1-928e-4412-896e-c5d1c99b2029"
}
]
}
}