AutomationFlowsAI & RAG › Analyze Invoices From Google Drive with AI and Store Data in Google Sheets

Analyze Invoices From Google Drive with AI and Store Data in Google Sheets

ByStefan Joulien @stefanjoulien on n8n.io

This workflow is designed for teams and businesses that receive invoices in Google Drive and want to automatically extract structured financial data without manual processing. It is ideal for finance teams, operators, and founders who want a simple way to turn invoices into…

Event trigger★★★★☆ complexityAI-powered23 nodesTelegram TriggerGoogle Drive TriggerGoogle DriveOpenAIGoogle GeminiGoogle Sheets
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #13750 — we link there as the canonical source.

This workflow follows the Google Drive → Google Drive Trigger 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
{
  "id": "dS5GvIke0Pa53AgG",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Analyze invoices from Google Drive and store structured data in Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "ec461050-6e57-42d2-8da1-d821fc75bc45",
      "name": "Telegram Trigger",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -64,
        512
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {
          "download": true
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "11242a3f-7f0d-476c-85d2-726438bb1077",
      "name": "Google Drive Trigger",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -16,
        112
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": "1nh2jQR1YJLOfbtzlS86znKfbCTKFHg5Z",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1nh2jQR1YJLOfbtzlS86znKfbCTKFHg5Z",
          "cachedResultName": "Facturas practica de N8N"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e90299ba-e630-4154-bc63-a16b0a21d8e5",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        384,
        112
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "3bc8ed92-6d9a-475a-a6c8-6b736d0b8161",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        608,
        112
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Imagen png",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b8058f9b-5032-4fc6-a61b-f238683cefcb",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.fileExtension }}",
                    "rightValue": "png"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "PDF",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b1f0b32f-1c40-40ac-9afe-8553b057d76c",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.fileExtension }}",
                    "rightValue": "pdf"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Imagen jpg",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "90eb0f3f-086b-43e0-928f-561d1327d270",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.fileExtension }}",
                    "rightValue": "jpg"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "7380ef1f-7e54-459d-b094-1bfd1fd1264f",
      "name": "Edit Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1136,
        128
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "5ee4379f-8d6d-4044-b5c6-b3bef563b7d1",
              "name": "json",
              "type": "array",
              "value": "={{ (() => {\n  // 1) localizar el texto con el JSON (seg\u00fan tu screenshot)\n  const raw =\n    $json?.content?.parts?.[0]?.text ??\n    $json?.content?.[0]?.text ??\n    $json?.candidates?.[0]?.content?.parts?.[0]?.text ??\n    '';\n\n  // 2) limpiar fences ```json ... ``` y espacios\n  let s = String(raw).trim()\n    .replace(/^```json\\s*/i, '')\n    .replace(/^```/i, '')\n    .replace(/```$/i, '')\n    .trim();\n\n  // 3) intentar parseo directo; si falla, desescapar y reintentar\n  const tryParse = (t) => {\n    try {\n      const obj = JSON.parse(t);\n      return Array.isArray(obj) ? obj : [obj];\n    } catch (_) {\n      return null;\n    }\n  };\n\n  let arr = tryParse(s);\n  if (!arr) {\n    const unesc = s\n      .replace(/\\\\n/g, ' ')\n      .replace(/\\\\t/g, ' ')\n      .replace(/\\\\\"/g, '\"')\n      .replace(/^\"|\"$/g, '');\n    arr = tryParse(unesc);\n  }\n\n  return arr || []; // devolver SIEMPRE un array\n})() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "1833ff91-5dda-47cb-95cc-061faa0478de",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1536,
        128
      ],
      "parameters": {
        "amount": 7
      },
      "typeVersion": 1.1
    },
    {
      "id": "11253a75-40bb-4ce7-8199-a92caaae359d",
      "name": "Edit Fields1",
      "type": "n8n-nodes-base.set",
      "position": [
        1136,
        -32
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "693fe1e9-5aeb-4119-8328-cc014a569796",
              "name": "json",
              "type": "array",
              "value": "={{ (() => {\n  // 1) Leer salida del nodo de IA\n  const v = $json?.content ?? $json?.choices?.[0]?.message?.content ?? '';\n\n  // 2) Normalizar a string\n  let s = Array.isArray(v) ? String(v[0] ?? '') : String(v);\n\n  // 3) Quitar fences y espacios\n  s = s\n    .replace(/^```json\\s*/i, '')\n    .replace(/^```/i, '')\n    .replace(/```$/i, '')\n    .trim();\n\n  // 4) Si todo viene entrecomillado, quitar comillas exteriores y desescapar\n  if (s.startsWith('\"') && s.endsWith('\"')) {\n    s = s.slice(1, -1);\n  }\n  s = s.replace(/\\\\n/g, ' ')\n       .replace(/\\\\t/g, ' ')\n       .replace(/\\\\\"/g, '\"');\n\n  const toArray = (txt) => {\n    // a) intento directo\n    try {\n      const first = JSON.parse(txt);\n      return Array.isArray(first) ? first : [first];\n    } catch {}\n\n    // b) si era JSON dentro de string, parseo doble\n    try {\n      const inner = JSON.parse(txt);\n      if (typeof inner === 'string') {\n        const second = JSON.parse(inner);\n        return Array.isArray(second) ? second : [second];\n      }\n    } catch {}\n\n    // c) recorte entre llaves por si hay ruido\n    const i = txt.indexOf('{'), j = txt.lastIndexOf('}');\n    if (i >= 0 && j > i) {\n      try { return [ JSON.parse(txt.slice(i, j + 1)) ]; } catch {}\n    }\n    return [];\n  };\n\n  return toArray(s);\n})() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a4b0b8d3-2567-4dd5-a52d-eb3c8c43b74b",
      "name": "Edit Fields2",
      "type": "n8n-nodes-base.set",
      "position": [
        1136,
        320
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "693fe1e9-5aeb-4119-8328-cc014a569796",
              "name": "json",
              "type": "array",
              "value": "={{ (() => {\n  // 1) Leer salida del nodo de IA\n  const v = $json?.content ?? $json?.choices?.[0]?.message?.content ?? '';\n\n  // 2) Normalizar a string\n  let s = Array.isArray(v) ? String(v[0] ?? '') : String(v);\n\n  // 3) Quitar fences y espacios\n  s = s\n    .replace(/^```json\\s*/i, '')\n    .replace(/^```/i, '')\n    .replace(/```$/i, '')\n    .trim();\n\n  // 4) Si todo viene entrecomillado, quitar comillas exteriores y desescapar\n  if (s.startsWith('\"') && s.endsWith('\"')) {\n    s = s.slice(1, -1);\n  }\n  s = s.replace(/\\\\n/g, ' ')\n       .replace(/\\\\t/g, ' ')\n       .replace(/\\\\\"/g, '\"');\n\n  const toArray = (txt) => {\n    // a) intento directo\n    try {\n      const first = JSON.parse(txt);\n      return Array.isArray(first) ? first : [first];\n    } catch {}\n\n    // b) si era JSON dentro de string, parseo doble\n    try {\n      const inner = JSON.parse(txt);\n      if (typeof inner === 'string') {\n        const second = JSON.parse(inner);\n        return Array.isArray(second) ? second : [second];\n      }\n    } catch {}\n\n    // c) recorte entre llaves por si hay ruido\n    const i = txt.indexOf('{'), j = txt.lastIndexOf('}');\n    if (i >= 0 && j > i) {\n      try { return [ JSON.parse(txt.slice(i, j + 1)) ]; } catch {}\n    }\n    return [];\n  };\n\n  return toArray(s);\n})() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bdc033cb-233f-4f45-b8d8-22c5a47c7ba2",
      "name": "Mapeo",
      "type": "n8n-nodes-base.set",
      "position": [
        192,
        112
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1bec340-899d-4b5d-9da6-05f97689a9bf",
              "name": "Name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "2fb5c808-07a2-4524-b446-72632e6860d9",
              "name": "Url ",
              "type": "string",
              "value": "={{ $json.webViewLink || $json.webContentLink }}"
            },
            {
              "id": "cc22e9eb-3641-44a0-9283-bef5307571bc",
              "name": "Email",
              "type": "string",
              "value": "={{ $json.lastModifyingUser.emailAddress || $json.owners[0]?.emailAddress }}"
            },
            {
              "id": "946fc814-61af-4dce-b5f8-546698bd1150",
              "name": "Date and time",
              "type": "string",
              "value": "={{ $now.format(('dd/LL/yyyy h:nn a')) }}"
            },
            {
              "id": "06952825-24c4-430d-82d7-bab44bf174e5",
              "name": "=FileId",
              "type": "string",
              "value": "={{ $json.id }}"
            },
            {
              "id": "8fc7537d-3383-4eda-a90a-7abb34b53386",
              "name": "ParentFolderId",
              "type": "string",
              "value": "={{ $json.parents[0] }}"
            },
            {
              "id": "d6010710-8c07-477e-94e9-b7cd3dbe7923",
              "name": "MimeType",
              "type": "string",
              "value": "={{ $json.mimeType }}"
            },
            {
              "id": "e475d027-f561-45f2-a5bb-c0f885ffae25",
              "name": "SizeBytes",
              "type": "string",
              "value": "={{ $json.size }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "0a1e9300-a250-4e54-84fc-c85d2984f211",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -1328
      ],
      "parameters": {
        "width": 1216,
        "height": 976,
        "content": "## Who this template is for\n\nThis workflow is designed for teams and businesses that receive invoices in Google Drive and want to automatically extract structured financial data without manual processing. It is ideal for finance teams, operators, and founders who want a simple way to turn invoices into usable data.\n\nNo accounting software is required, and the workflow works with common invoice formats such as PDFs and images.\n\n## What this workflow does\n\nThis workflow monitors a Google Drive folder for newly uploaded invoices. When a file is detected, it uses AI to extract key invoice information such as issuer, date, total amount, taxes, currency, and description.\n\nThe extracted data is automatically cleaned, structured, and stored in Google Sheets, creating a centralized and searchable invoice database.\n\n## How it works\n\nThe workflow starts when a new file is added to a Google Drive folder. Each file is processed individually and classified based on its type (PDF or image). The file is then downloaded and analyzed using an AI model optimized for document and image understanding.\n\nThe AI output is normalized into structured fields and appended to a Google Sheets table. A short wait step ensures reliable sequential writes when multiple invoices are processed at the same time.\n\n## How to set up\n\n1. Select the Google Drive folder where invoices will be uploaded.\n2. Connect your OpenAI credentials for document and image analysis.\n3. Choose the Google Sheets file that will store the extracted invoice data.\n4. Activate the workflow and upload an invoice to test it.\n\n## Requirements\n\n- Google Drive account\n- Google Sheets account\n- OpenAI API credentials\n- n8n instance (cloud or self-hosted)\n\n## How to customize the workflow\n\nYou can adjust the fields extracted from invoices, add validation rules, connect the data to accounting tools, or extend the workflow with reporting and notification steps."
      },
      "typeVersion": 1
    },
    {
      "id": "947c9de7-c49d-48e4-8123-cd0792377a61",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -96,
        -192
      ],
      "parameters": {
        "color": 6,
        "width": 432,
        "height": 864,
        "content": "## A. Sticky: \u201cGoogle Drive file detection\u201d\n\nThis section monitors a Google Drive folder and extracts basic metadata from newly uploaded files to prepare them for processing."
      },
      "typeVersion": 1
    },
    {
      "id": "05ecb110-0ecd-4395-bc1e-7406e7b284e3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        -192
      ],
      "parameters": {
        "color": 6,
        "width": 944,
        "height": 864,
        "content": "This section handles invoice analysis for all supported file types (PDF and images).\n\nEach file is downloaded from Google Drive and processed using AI models optimized for document or image understanding. Key invoice fields such as issuer, date, total amount, taxes, currency, and description are extracted, normalized into structured data, and appended to Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "d8de7288-8080-4656-9f48-07cf63028c79",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        -192
      ],
      "parameters": {
        "color": 6,
        "width": 432,
        "height": 864,
        "content": "## B. Sticky: \u201cFile type classification\n\nThis step classifies each file based on its MIME type and routes it to the appropriate analysis flow for PDFs or images."
      },
      "typeVersion": 1
    },
    {
      "id": "39fe4265-9083-4c57-8764-31ea1d595f4f",
      "name": "download image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        816,
        -32
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "4ccf5557-b5de-4b8b-9e86-e722117b2c15",
      "name": "Download PDF",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        816,
        128
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "490fc439-0189-4d8a-9ee3-4cc32001341a",
      "name": "Download image",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        816,
        320
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "b7eefab8-4250-435a-ada3-e9e02e8f7786",
      "name": "analyze image",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        976,
        -32
      ],
      "parameters": {
        "text": "=Recibes un documento de una factura y debes extraer los siguientes campos, devolviendo solo un objeto JSON con las claves exactamente como se indican y en este orden:\n\nFecha: La fecha de emisi\u00f3n en formato DD/MM/AAAA (ej.: \"21/07/2025\").\n\nCategor\u00eda: Clasifica el gasto en una de las siguientes categor\u00edas: Software, Viajes, Suscripciones, Publicidad, Otros.\n\nEmisor: Nombre de la empresa/persona que emite la factura.\n\nDescripci\u00f3n: Breve explicaci\u00f3n del producto o servicio.\n\nPrecio (sin IVA): Importe neto antes de IVA, sin s\u00edmbolo de moneda, usando coma como separador decimal y nunca punto (ej.: \"1800,00\").\n\nIVA: El valor numerico del tipo de IVA, usando coma como separador de decimal y sin el simbolo del porcentaje.\nEjemplo: \"21,0\" prohibido poner \"21.0\" o \"21,0%\" Si no se aplica el IVA escribe \"0,0\"\n\nTotal: Total con impuestos, sin s\u00edmbolo de moneda, con coma decimal (ej.: \"2178,00\").\n\nMoneda: Abreviatura en may\u00fasculas (ej.: \"EUR\").\n\nNotas: Cualquier anotaci\u00f3n relevante. Si no aplica, devuelve \"N/A\".\n\nN\u00ba de contacto: el n\u00famero de telefono de la empresa o contacto\n\nReglas estrictas\n- Mant\u00e9n formato y nombres exactamente como arriba.\n- No incluyas s\u00edmbolos de moneda en valores num\u00e9ricos.\n- Usa coma como separador decimal siempre.\n- Si falta alg\u00fan dato, usa \"N/A\".\n\nResponde \u00fanicamente con el JSON (sin texto adicional, sin bloques de c\u00f3digo).\n\nEjemplo de salida v\u00e1lida\n{\"Fecha\":\"15/08/2024\",\"Categor\u00eda\":\"Software\",\"Emisor\":\"BlunexAI S.L.\",\"Descripci\u00f3n\":\"Implementaci\u00f3n de Agente IA para WhatsApp Business\",\"Precio (sin IVA)\":\"1800,00\",\"IVA\":\"21,0\",\"Total\":\"2178,00\",\"Moneda\":\"EUR\",\"Notas\":\"Pago a 30 d\u00edas; recargo 2% por retraso\"}",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "resource": "image",
        "inputType": "base64",
        "operation": "analyze"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "9781a28f-c81b-457d-8fa8-3cad71607869",
      "name": "analyze image1",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        976,
        320
      ],
      "parameters": {
        "text": "=Recibes un documento de una factura y debes extraer los siguientes campos, devolviendo solo un objeto JSON con las claves exactamente como se indican y en este orden:\n\nFecha: La fecha de emisi\u00f3n en formato DD/MM/AAAA (ej.: \"21/07/2025\").\n\nCategor\u00eda: Clasifica el gasto en una de las siguientes categor\u00edas: Software, Viajes, Suscripciones, Publicidad, Otros.\n\nEmisor: Nombre de la empresa/persona que emite la factura.\n\nDescripci\u00f3n: Breve explicaci\u00f3n del producto o servicio.\n\nPrecio (sin IVA): Importe neto antes de IVA, sin s\u00edmbolo de moneda, usando coma como separador decimal y nunca punto (ej.: \"1800,00\").\n\nIVA: El valor numerico del tipo de IVA, usando coma como separador de decimal y sin el simbolo del porcentaje.\nEjemplo: \"21,0\" prohibido poner \"21.0\" o \"21,0%\" Si no se aplica el IVA escribe \"0,0\"\n\nTotal: Total con impuestos, sin s\u00edmbolo de moneda, con coma decimal (ej.: \"2178,00\").\n\nMoneda: Abreviatura en may\u00fasculas (ej.: \"EUR\").\n\nNotas: Cualquier anotaci\u00f3n relevante. Si no aplica, devuelve \"N/A\".\n\nN\u00ba de contacto: el n\u00famero de telefono de la empresa o contacto\n\nReglas estrictas\n- Mant\u00e9n formato y nombres exactamente como arriba.\n- No incluyas s\u00edmbolos de moneda en valores num\u00e9ricos.\n- Usa coma como separador decimal siempre.\n- Si falta alg\u00fan dato, usa \"N/A\".\n\nResponde \u00fanicamente con el JSON (sin texto adicional, sin bloques de c\u00f3digo).\n\nEjemplo de salida v\u00e1lida\n{\"Fecha\":\"15/08/2024\",\"Categor\u00eda\":\"Software\",\"Emisor\":\"BlunexAI S.L.\",\"Descripci\u00f3n\":\"Implementaci\u00f3n de Agente IA para WhatsApp Business\",\"Precio (sin IVA)\":\"1800,00\",\"IVA\":\"21,0\",\"Total\":\"2178,00\",\"Moneda\":\"EUR\",\"Notas\":\"Pago a 30 d\u00edas; recargo 2% por retraso\"}",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "GPT-4O"
        },
        "options": {},
        "resource": "image",
        "inputType": "base64",
        "operation": "analyze"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "da92f962-968c-46bf-8203-af282f46e33c",
      "name": "analyze document",
      "type": "@n8n/n8n-nodes-langchain.googleGemini",
      "position": [
        976,
        128
      ],
      "parameters": {
        "text": "=Recibes un documento de una factura y debes extraer los siguientes campos, devolviendo solo un objeto JSON con las claves exactamente como se indican y en este orden:\n\nFecha: La fecha de emisi\u00f3n en formato DD/MM/AAAA (ej.: \"21/07/2025\").\n\nCategor\u00eda: Clasifica el gasto en una de las siguientes categor\u00edas: Software, Viajes, Suscripciones, Publicidad, Otros.\n\nEmisor: Nombre de la empresa/persona que emite la factura.\n\nDescripci\u00f3n: Breve explicaci\u00f3n del producto o servicio.\n\nPrecio (sin IVA): Importe neto antes de IVA, sin s\u00edmbolo de moneda, usando coma como separador decimal y nunca punto (ej.: \"1800,00\").\n\nIVA: El valor numerico del tipo de IVA, usando coma como separador de decimal y sin el simbolo del porcentaje.\nEjemplo: \"21,0\" prohibido poner \"21.0\" o \"21,0%\" Si no se aplica el IVA escribe \"0,0\"\n\nTotal: Total con impuestos, sin s\u00edmbolo de moneda, con coma decimal (ej.: \"2178,00\").\n\nMoneda: Abreviatura en may\u00fasculas (ej.: \"EUR\").\n\nNotas: Cualquier anotaci\u00f3n relevante. Si no aplica, devuelve \"N/A\".\n\nN\u00ba de contacto: el n\u00famero de telefono de la empresa o contacto\n\nReglas estrictas\n- Mant\u00e9n formato y nombres exactamente como arriba.\n- No incluyas s\u00edmbolos de moneda en valores num\u00e9ricos.\n- Usa coma como separador decimal siempre.\n- Si falta alg\u00fan dato, usa \"N/A\".\n\nResponde \u00fanicamente con el JSON (sin texto adicional, sin bloques de c\u00f3digo).\n\nEjemplo de salida v\u00e1lida\n{\"Fecha\":\"15/08/2024\",\"Categor\u00eda\":\"Software\",\"Emisor\":\"BlunexAI S.L.\",\"Descripci\u00f3n\":\"Implementaci\u00f3n de Agente IA para WhatsApp Business\",\"Precio (sin IVA)\":\"1800,00\",\"IVA\":\"21,0\",\"Total\":\"2178,00\",\"Moneda\":\"EUR\",\"Notas\":\"Pago a 30 d\u00edas; recargo 2% por retraso\"}",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "models/gemini-2.5-flash-lite-preview-06-17",
          "cachedResultName": "models/gemini-2.5-flash-lite-preview-06-17"
        },
        "options": {},
        "resource": "document",
        "inputType": "binary"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "315f2222-256e-4e36-8b06-987386b2863c",
      "name": "Put data in table",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1296,
        128
      ],
      "parameters": {
        "columns": {
          "value": {
            "IVA": "={{ $json.json[0].IVA }}",
            "URL": "={{ $('Google Drive Trigger').item.json.webContentLink }}",
            "Fecha": "={{ $json.json[0].Fecha }}",
            "Notas": "={{ $json.json[0].Notas }}",
            "Total": "={{ $json.json[0].Total }}",
            "Emisor": "={{ $json.json[0].Emisor }}",
            "Moneda": "={{ $json.json[0].Moneda }}",
            "Categor\u00eda": "={{ $json.json[0]['Categor\u00eda'] }}",
            "Descripci\u00f3n": "={{ $json.json[0]['Descripci\u00f3n'] }}",
            "N\u00ba contacto": "={{ $json.json[0]['N\u00ba de contacto'] }}",
            "Precio (sin IVA)": "={{ $json.json[0]['Precio (sin IVA)'] }}"
          },
          "schema": [
            {
              "id": "Fecha",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Categor\u00eda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Categor\u00eda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Emisor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Emisor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "N\u00ba contacto",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "N\u00ba contacto",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Descripci\u00f3n",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Descripci\u00f3n",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Precio (sin IVA)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Precio (sin IVA)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IVA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IVA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Moneda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Moneda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notas",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notas",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit#gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit?usp=drivesdk",
          "cachedResultName": "Facturas Demo_N8N"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "e5ee0470-1c77-4355-889c-bb946eb142cc",
      "name": "Put data in table1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1296,
        -32
      ],
      "parameters": {
        "columns": {
          "value": {
            "IVA": "={{ $json.json[0].IVA }}",
            "URL": "={{ $('Google Drive Trigger').item.json.webContentLink }}",
            "Fecha": "={{ $json.json[0].Fecha }}",
            "Notas": "={{ $json.json[0].Notas }}",
            "Total": "={{ $json.json[0].Total }}",
            "Emisor": "={{ $json.json[0].Emisor }}",
            "Moneda": "={{ $json.json[0].Moneda }}",
            "Categor\u00eda": "={{ $json.json[0]['Categor\u00eda'] }}",
            "Descripci\u00f3n": "={{ $json.json[0]['Descripci\u00f3n'] }}",
            "N\u00ba contacto": "={{ $json.json[0]['N\u00ba de contacto'] }}",
            "Precio (sin IVA)": "={{ $json.json[0]['Precio (sin IVA)'] }}"
          },
          "schema": [
            {
              "id": "Fecha",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Categor\u00eda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Categor\u00eda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Emisor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Emisor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "N\u00ba contacto",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "N\u00ba contacto",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Descripci\u00f3n",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Descripci\u00f3n",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Precio (sin IVA)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Precio (sin IVA)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IVA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IVA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Moneda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Moneda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notas",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notas",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit#gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit?usp=drivesdk",
          "cachedResultName": "Facturas Demo_N8N"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8bba59a8-e9fc-41f1-b162-595525370915",
      "name": "Put data in table2",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1296,
        320
      ],
      "parameters": {
        "columns": {
          "value": {
            "IVA": "={{ $json.json[0].IVA }}",
            "URL": "={{ $('Google Drive Trigger').item.json.webContentLink }}",
            "Fecha": "={{ $json.json[0].Fecha }}",
            "Notas": "={{ $json.json[0].Notas }}",
            "Total": "={{ $json.json[0].Total }}",
            "Emisor": "={{ $json.json[0].Emisor }}",
            "Moneda": "={{ $json.json[0].Moneda }}",
            "Categor\u00eda": "={{ $json.json[0]['Categor\u00eda'] }}",
            "Descripci\u00f3n": "={{ $json.json[0]['Descripci\u00f3n'] }}",
            "N\u00ba contacto": "={{ $json.json[0]['N\u00ba de contacto'] }}",
            "Precio (sin IVA)": "={{ $json.json[0]['Precio (sin IVA)'] }}"
          },
          "schema": [
            {
              "id": "Fecha",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Fecha",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Categor\u00eda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Categor\u00eda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Emisor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Emisor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "N\u00ba contacto",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "N\u00ba contacto",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Descripci\u00f3n",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Descripci\u00f3n",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Precio (sin IVA)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Precio (sin IVA)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IVA",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IVA",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Moneda",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Moneda",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notas",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Notas",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit#gid=0",
          "cachedResultName": "Hoja 1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/169BRMJpX0G-L5Ip3cBIj9FiUjQjzG8wF24DWEFREBwQ/edit?usp=drivesdk",
          "cachedResultName": "Facturas Demo_N8N"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f922cd0d-8aa8-42e3-b7a4-b1c4b2d18529",
      "name": "Save_drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        176,
        512
      ],
      "parameters": {
        "name": "={{ $now.format('yyyy-MM-dd') }}-{{ $json.message.photo[0].file_unique_id }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1nh2jQR1YJLOfbtzlS86znKfbCTKFHg5Z",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1nh2jQR1YJLOfbtzlS86znKfbCTKFHg5Z",
          "cachedResultName": "Facturas practica de N8N"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "53daf3db-4f24-45f1-a95c-9ab5197d76d5",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mapeo": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "download image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Download PDF",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Download image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Put data in table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download PDF": {
      "main": [
        [
          {
            "node": "analyze document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields1": {
      "main": [
        [
          {
            "node": "Put data in table1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields2": {
      "main": [
        [
          {
            "node": "Put data in table2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "analyze image": {
      "main": [
        [
          {
            "node": "Edit Fields1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download image": {
      "main": [
        [
          {
            "node": "analyze image1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "analyze image1": {
      "main": [
        [
          {
            "node": "Edit Fields2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "download image": {
      "main": [
        [
          {
            "node": "analyze image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Trigger": {
      "main": [
        [
          {
            "node": "Save_drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "analyze document": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put data in table": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put data in table1": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Put data in table2": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Drive Trigger": {
      "main": [
        [
          {
            "node": "Mapeo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

This workflow is designed for teams and businesses that receive invoices in Google Drive and want to automatically extract structured financial data without manual processing. It is ideal for finance teams, operators, and founders who want a simple way to turn invoices into…

Source: https://n8n.io/workflows/13750/ — 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

The Problem That it Solves

Google Drive Trigger, OpenAI, Google Drive +5
AI & RAG

Content creators, YouTubers, and social media managers who want to repurpose long form videos into short clips without doing it manually. Works on self hosted n8n instances.

Google Drive Trigger, Google Drive, N8N Nodes Renderio +3
AI & RAG

Monitor a Google Drive folder, process each image based on the prompt defined in and save the new image to the specified output Google Drive folder. Maintain a processing log in Google Sheets.

Google Drive Trigger, Google Drive, HTTP Request +2
AI & RAG

💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.

Telegram Trigger, HTTP Request, Google Drive +6
AI & RAG

💥 Automate YouTube thumbnail creation from video links -vide. Uses telegramTrigger, httpRequest, googleDrive, gmail. Event-driven trigger; 25 nodes.

Telegram Trigger, HTTP Request, Google Drive +6