AutomationFlowsAI & RAG › Emision Y Autorizacion En Tiempo Real

Emision Y Autorizacion En Tiempo Real

1 - Emision y Autorizacion en Tiempo Real. Uses httpRequest, googleDrive, emailSend, agent. Webhook trigger; 18 nodes.

Webhook trigger★★★★☆ complexityAI-powered18 nodesHTTP RequestGoogle DriveEmail SendAgentGroq Chat
AI & RAG Trigger: Webhook Nodes: 18 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Agent → Emailsend recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "1 - Emision y Autorizacion en Tiempo Real",
  "nodes": [
    {
      "parameters": {
        "url": "={{ $('Preparar Respuesta Final').item.json.urlRide }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "rideData"
            }
          }
        }
      },
      "id": "7f2a18f7-017f-420b-84d7-297eb9d266f3",
      "name": "Descargar RIDE (PDF)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        320,
        -496
      ],
      "executeOnce": true,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "url": "={{ $('Preparar Respuesta Final').item.json.urlXml }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "xmlData"
            }
          }
        }
      },
      "id": "19ac47f6-f468-482f-8fac-fc1998f56762",
      "name": "Descargar XML",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        -496
      ],
      "executeOnce": false,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "inputDataFieldName": "rideData",
        "name": "={{ $json.claveAcceso + '_RIDE.pdf' }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "1mN1YwRk9Qdgh_V5P0TB3XYh9VGu3xUws",
          "mode": "id"
        },
        "options": {}
      },
      "id": "8e0e466a-9bed-4320-ba60-c1523713e6b4",
      "name": "Respaldar RIDE en Drive",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        560,
        -272
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "inputDataFieldName": "xmlData",
        "name": "={{ $json.claveAcceso + '_XML.xml' }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "folderId": {
          "__rl": true,
          "value": "1mN1YwRk9Qdgh_V5P0TB3XYh9VGu3xUws",
          "mode": "id"
        },
        "options": {}
      },
      "id": "9fe64a78-e8c0-4cb9-bd17-958be6056d92",
      "name": "Respaldar XML en Drive",
      "type": "n8n-nodes-base.googleDrive",
      "typeVersion": 3,
      "position": [
        720,
        -272
      ],
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "facturar",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "13c11157-49d1-46e4-85ae-21ebd7ea3dd1",
      "name": "Webhook Recibir Factura",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1376,
        -512
      ]
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst factura = items[0].json.body ?? items[0].json;\n\n// ============================================================\n// MANEJO DEL LOGO\n// ============================================================\n// Conservamos el Data URL completo:\n// data:image/png;base64,XXXX\n// data:image/jpeg;base64,XXXX\n// data:image/webp;base64,XXXX\n//\n// Esto permite que el server.js detecte correctamente el formato.\n// ============================================================\n\nif (!factura.emisor) {\n  factura.emisor = {};\n}\n\nif (factura.emisor.logo) {\n  const logoStr = String(factura.emisor.logo).trim();\n\n  // NO eliminamos \"data:image/...;base64,\"\n  // Se conserva el Data URL completo.\n  factura.emisor.logo = logoStr;\n}\n\n// ============================================================\n// FECHA DE EMISI\u00d3N\n// ============================================================\n\nconst fecha = new Date(\n  factura.fechaEmision || Date.now()\n);\n\nconst dd = String(\n  fecha.getDate()\n).padStart(2, '0');\n\nconst mm = String(\n  fecha.getMonth() + 1\n).padStart(2, '0');\n\nconst yyyy = String(\n  fecha.getFullYear()\n);\n\nconst fechaEmisionStr =\n  `${dd}${mm}${yyyy}`;\n\n// ============================================================\n// DATOS DEL COMPROBANTE\n// ============================================================\n\nconst tipoComprobante = '01';\n\nconst ruc = String(\n  factura.emisor.ruc ||\n  '1792146739001'\n)\n  .padStart(13, '0')\n  .slice(0, 13);\n\nconst ambiente = '1';\n\nconst establecimiento = String(\n  factura.emisor.establecimiento ||\n  '001'\n)\n  .padStart(3, '0');\n\nconst puntoEmision = String(\n  factura.emisor.puntoEmision ||\n  '001'\n)\n  .padStart(3, '0');\n\n// ============================================================\n// SECUENCIAL\n// ============================================================\n\nconst staticData =\n  $getWorkflowStaticData('global');\n\nstaticData.secuencial =\n  (staticData.secuencial || 0) + 1;\n\nconst secuencial = String(\n  staticData.secuencial\n).padStart(9, '0');\n\n// ============================================================\n// C\u00d3DIGO NUM\u00c9RICO\n// ============================================================\n\nconst codigoNumerico = String(\n  Math.floor(\n    Math.random() * 100000000\n  )\n).padStart(8, '0');\n\nconst tipoEmision = '1';\n\n// ============================================================\n// GENERAR CLAVE DE ACCESO DE 48 D\u00cdGITOS\n// ============================================================\n\nconst clave48 =\n  fechaEmisionStr +\n  tipoComprobante +\n  ruc +\n  ambiente +\n  establecimiento +\n  puntoEmision +\n  secuencial +\n  codigoNumerico +\n  tipoEmision;\n\n// ============================================================\n// M\u00d3DULO 11\n// ============================================================\n\nfunction calcularDigitoVerificadorModulo11(clave) {\n\n  const factores = [\n    2,\n    3,\n    4,\n    5,\n    6,\n    7,\n  ];\n\n  let factorIndex = 0;\n  let suma = 0;\n\n  for (\n    let i = clave.length - 1;\n    i >= 0;\n    i--\n  ) {\n\n    const digito = parseInt(\n      clave[i],\n      10\n    );\n\n    suma +=\n      digito *\n      factores[factorIndex];\n\n    factorIndex =\n      (factorIndex + 1) %\n      factores.length;\n  }\n\n  const modulo =\n    suma % 11;\n\n  let verificador =\n    11 - modulo;\n\n  if (verificador === 11) {\n    verificador = 0;\n  }\n\n  if (verificador === 10) {\n    verificador = 1;\n  }\n\n  return String(\n    verificador\n  );\n}\n\n// ============================================================\n// CLAVE DE ACCESO FINAL\n// ============================================================\n\nconst digitoVerificador =\n  calcularDigitoVerificadorModulo11(\n    clave48\n  );\n\nconst claveAcceso =\n  clave48 +\n  digitoVerificador;\n\n// ============================================================\n// VALIDAR LONGITUD\n// ============================================================\n\nif (\n  claveAcceso.length !== 49\n) {\n  throw new Error(\n    `La clave de acceso generada no tiene 49 digitos: ${claveAcceso.length}`\n  );\n}\n\n// ============================================================\n// SALIDA\n// ============================================================\n\nreturn [\n  {\n    json: {\n      claveAcceso,\n      secuencial,\n      factura,\n    },\n  },\n];"
      },
      "id": "1a761dc1-0f79-4e69-bcca-daff604ec2fe",
      "name": "Generar Clave de Acceso",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1200,
        -512
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:4000/api/sri/recepcion",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ { \"claveAcceso\": $json.claveAcceso, \"factura\": $json.factura } }}",
        "options": {}
      },
      "id": "6aa37cfa-bd80-4059-906a-7489a3d36943",
      "name": "SRI Recepcion",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -1024,
        -512
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "cond-recepcion-ok",
              "leftValue": "={{ $json.estado }}",
              "rightValue": "RECIBIDA",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "ec94f359-2a3c-4f57-8eb7-5df0f9e8cb4b",
      "name": "Recepcion OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -864,
        -496
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:4000/api/sri/autorizacion",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ { \"claveAcceso\": $('Generar Clave de Acceso').item.json.claveAcceso } }}",
        "options": {}
      },
      "id": "234d87f7-63f6-4aa8-bcb8-47d4fbac7044",
      "name": "SRI Autorizacion",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -672,
        -512
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:4000/api/sri/generar-xml",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ { \"claveAcceso\": $('Generar Clave de Acceso').item.json.claveAcceso, \"factura\": $('Generar Clave de Acceso').item.json.factura } }}",
        "options": {}
      },
      "id": "243fa2bf-94cb-4fbb-bcca-16878801ee18",
      "name": "SRI Generar XML",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -512,
        -512
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:4000/api/sri/generar-ride",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ {\n  \"claveAcceso\": $('Generar Clave de Acceso').item.json.claveAcceso,\n  \"factura\": $('Generar Clave de Acceso').item.json.factura\n} }}",
        "options": {}
      },
      "id": "86580e13-82c3-4517-84d2-1567eb990701",
      "name": "SRI Generar RIDE",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -352,
        -512
      ]
    },
    {
      "parameters": {
        "jsCode": "// Captura segura de datos previos usando .first()\nconst clave = $('Generar Clave de Acceso').first()?.json?.claveAcceso || '';\nconst factura = $('Generar Clave de Acceso').first()?.json?.factura || $('Webhook Recibir Factura').first()?.json?.body || {};\nconst autorizacion = $('SRI Autorizacion').first()?.json || {};\nconst xml = $('SRI Generar XML').first()?.json || {};\nconst ride = $('SRI Generar RIDE').first()?.json || {};\n\n// Capturamos la IA de forma ultra-segura desde el nodo AI Agent\nlet categoriaIa = 'General';\nlet asuntoEmail = '';\nlet cuerpoEmail = '';\n\ntry {\n  const aiItem = $('AI Agent').first()?.json;\n  if (aiItem && aiItem.output) {\n    const aiOutput = aiItem.output;\n    const aiData = typeof aiOutput === 'string' ? JSON.parse(aiOutput) : aiOutput;\n    \n    categoriaIa = aiData.categoria || 'General';\n    asuntoEmail = aiData.asunto_email || '';\n    cuerpoEmail = aiData.cuerpo_email || '';\n  }\n} catch (e) {\n  console.log(\"No se pudo parsear el resultado del AI Agent, usando valores por defecto.\");\n}\n\nreturn [\n  {\n    json: {\n      ok: true,\n      claveAcceso: clave,\n      factura: factura,\n      numeroAutorizacion: autorizacion.numeroAutorizacion || clave,\n      fechaAutorizacion: autorizacion.fechaAutorizacion || new Date().toISOString(),\n      urlRide: ride.urlRide || '',\n      urlXml: xml.urlXml || '',\n      // Enviamos la categor\u00eda en todas sus posibles variantes de nombre:\n      categoria: categoriaIa,\n      categoriaIa: categoriaIa,\n      categoria_ia: categoriaIa,\n      asunto: asuntoEmail || 'Factura Electr\u00f3nica Emitida',\n      mensaje: cuerpoEmail || 'Comprobante autorizado correctamente.',\n    },\n  },\n];"
      },
      "id": "fcae8117-460b-4322-b808-d5c3f94a4793",
      "name": "Preparar Respuesta Final",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        128,
        -624
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $('Preparar Respuesta Final').item.json }}",
        "options": {}
      },
      "id": "a30ec880-7772-421c-9a56-67f550455ea4",
      "name": "Responder al Cliente",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        304,
        -704
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { \"ok\": false, \"mensaje\": \"El SRI simulado rechazo el comprobante. Intenta nuevamente.\" } }}",
        "options": {
          "responseCode": 502
        }
      },
      "id": "e3fe27a2-01de-4a9a-92df-f19ed0b66e41",
      "name": "Responder Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        -720,
        -336
      ]
    },
    {
      "parameters": {
        "fromEmail": "kam.santana@yavirac.edu.ec",
        "toEmail": "={{ $('Preparar Respuesta Final').first().json.factura.cliente.correo }}",
        "subject": "={{ 'Tu factura electr\u00f3nica - Clave de acceso ' + $('Preparar Respuesta Final').item.json.claveAcceso }}",
        "html": "={{ $('Preparar Respuesta Final').first().json.mensaje }}",
        "options": {
          "attachments": "rideData, xmlData"
        }
      },
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        656,
        -496
      ],
      "id": "bce40f6a-f669-454a-812b-d46927628031",
      "name": "Send an Email",
      "executeOnce": true,
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "promptType": "define",
        "text": "=Procesa la compra del cliente {{ $('Webhook Recibir Factura').first().json.body.cliente.nombre }} en \"PROVEEDOR FERRETERO PROFERRET S.A.S.\".\n\n\u00cdtems comprados:\n{{ JSON.stringify($('Webhook Recibir Factura').first().json.body.items) }}\n\nDetermina la categor\u00eda (Herramientas, Servicios, Insumos o General) y genera el JSON de salida con el mensaje para el correo.",
        "options": {
          "systemMessage": "Eres el asistente virtual de Inteligencia Artificial de \"PROVEEDOR FERRETERO PROFERRET S.A.S.\". Tu trabajo es analizar los \u00edtems de una factura y generar un JSON con la categor\u00eda de la compra y un mensaje amigable para el correo del cliente.\n\nREGLA OBLIGATORIA: Responde \u00daNICAMENTE un JSON v\u00e1lido sin bloques de c\u00f3digo Markdown (no incluyas ```json ni comillas alrededor del bloque).\n\nEstructura requerida:\n{\n  \"asunto_email\": \"\u00a1Gracias por tu compra en PROFERRET S.A.S.!\",\n  \"cuerpo_email\": \"Estimado/a cliente, adjunto a este correo encontrar\u00e1 su comprobante electr\u00f3nico autorizado por el SRI. \u00a1Agradecemos su preferencia!\",\n  \"categoria\": \"<CATEGORIA>\"\n}\n\nReglas estrictas para <CATEGORIA>:\n- \"Insumos\": Pinturas, brochas, lijas, clavos, tornillos, tubos, cables, cemento, pegamentos o consumibles.\n- \"Herramientas\": Taladros, martillos, alicates, sierras, llaves, herramientas manuales o el\u00e9ctricas.\n- \"Servicios\": Mano de obra, fletes, alquileres, instalaciones.\n- \"General\": Solo si no encaja en las anteriores."
        }
      },
      "type": "@n8n/n8n-nodes-langchain.agent",
      "typeVersion": 3.1,
      "position": [
        -192,
        -512
      ],
      "id": "9682437f-8ff7-4752-8055-9a9a1f6e30c7",
      "name": "AI Agent"
    },
    {
      "parameters": {
        "model": "llama-3.1-8b-instant",
        "options": {}
      },
      "type": "@n8n/n8n-nodes-langchain.lmChatGroq",
      "typeVersion": 1,
      "position": [
        -192,
        -272
      ],
      "id": "7ac9ea7b-8027-49b7-b3e4-0b119485484e",
      "name": "Groq Chat Model",
      "credentials": {
        "groqApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "http://localhost:4000/api/sri/actualizar-ia",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"claveAcceso\": \"{{ $('SRI Autorizacion').first().json.claveAcceso || $('Generar Clave de Acceso').first().json.claveAcceso }}\",\n  \"categoriaIa\": \"{{ (() => { const raw = $json.output || $json.text || ''; if (raw.includes('Herramientas')) return 'Herramientas'; if (raw.includes('Servicios')) return 'Servicios'; if (raw.includes('Insumos')) return 'Insumos'; return 'General'; })() }}\",\n  \"estadoIa\": \"OK\",\n  \"iaOutput\": \"Clasificado exitosamente por el Agente IA Groq\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.4,
      "position": [
        128,
        -384
      ],
      "id": "ac80de2e-ca03-43c3-94b6-285d0d9212eb",
      "name": "HTTP Request"
    }
  ],
  "connections": {
    "Descargar RIDE (PDF)": {
      "main": [
        [
          {
            "node": "Descargar XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Descargar XML": {
      "main": [
        [
          {
            "node": "Send an Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Respaldar RIDE en Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respaldar RIDE en Drive": {
      "main": [
        [
          {
            "node": "Respaldar XML en Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook Recibir Factura": {
      "main": [
        [
          {
            "node": "Generar Clave de Acceso",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generar Clave de Acceso": {
      "main": [
        [
          {
            "node": "SRI Recepcion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SRI Recepcion": {
      "main": [
        [
          {
            "node": "Recepcion OK?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Recepcion OK?": {
      "main": [
        [
          {
            "node": "SRI Autorizacion",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Responder Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SRI Autorizacion": {
      "main": [
        [
          {
            "node": "SRI Generar XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SRI Generar XML": {
      "main": [
        [
          {
            "node": "SRI Generar RIDE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SRI Generar RIDE": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preparar Respuesta Final": {
      "main": [
        [
          {
            "node": "Responder al Cliente",
            "type": "main",
            "index": 0
          },
          {
            "node": "Descargar RIDE (PDF)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respaldar XML en Drive": {
      "main": [
        []
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Preparar Respuesta Final",
            "type": "main",
            "index": 0
          },
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Groq Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Send an Email": {
      "main": [
        []
      ]
    }
  },
  "active": true,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate"
  },
  "versionId": "a8c1ea88-7705-44a4-b14f-411bc285d3d4",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "IONb602IFhwXa2W0",
  "tags": []
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

1 - Emision y Autorizacion en Tiempo Real. Uses httpRequest, googleDrive, emailSend, agent. Webhook trigger; 18 nodes.

Source: https://github.com/kamsantana/PROYECTO-FACTURACION-N8N/blob/main/n8n-workflow/workflow-1-emision-y-autorizacion.json — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Automatically transforms your travel photos and notes into beautiful journals, highlight reels, and review drafts using Claude's vision and language capabilities. Trip Completion Trigger - Webhook or

HTTP Request, Google Sheets, Agent +3
AI & RAG

This workflow automates pre-dispatch customs document validation for international shipments. It ingests shipping document packages, extracts content from each file, uses Claude AI to cross-validate a

Google Drive Trigger, Google Drive, Agent +4
AI & RAG

This workflow ingests property document packages submitted via webhook or monitored cloud storage, extracts text from each file, runs Claude AI to verify legal compliance, detect missing or expired do

Google Drive Trigger, Google Drive, Agent +4
AI & RAG

Automatically converts your daily WhatsApp messages and photos from travels into beautifully structured travel stories, saved as documents in Google Drive. Receive WhatsApp Updates - Webhook captures

Google Drive, Agent, Anthropic Chat +2
AI & RAG

L&D_AgentsAI_ATIVO. Uses httpRequest, agent, googleCalendarTool, toolSerpApi. Webhook trigger; 93 nodes.

HTTP Request, Agent, Google Calendar Tool +9