{
  "id": "Ozur6RRxL9nG7rbH",
  "meta": {
    "instanceId": "c000a2799023e596f7ce282858563b91e619d5adf24129f1308c87834a19b2c2"
  },
  "name": "Invoice_Documentation.",
  "tags": [
    {
      "id": "TCKKYVMOgx9uGMKp",
      "name": "sme",
      "createdAt": "2025-12-26T11:55:38.971Z",
      "updatedAt": "2025-12-26T11:55:38.971Z"
    },
    {
      "id": "NFU967j5P2mDCpoJ",
      "name": "invoice",
      "createdAt": "2025-12-26T11:55:40.979Z",
      "updatedAt": "2025-12-26T11:55:40.979Z"
    },
    {
      "id": "wFTB3v0YCIbDh7eq",
      "name": "ai",
      "createdAt": "2025-12-26T11:55:42.291Z",
      "updatedAt": "2025-12-26T11:55:42.291Z"
    },
    {
      "id": "DnyRoU6GThA6WV2P",
      "name": "finance",
      "createdAt": "2025-12-26T11:55:49.120Z",
      "updatedAt": "2025-12-26T11:55:49.120Z"
    }
  ],
  "nodes": [
    {
      "id": "6d9797e9-c99f-4efa-985a-c43cd4f8b6cc",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1632,
        512
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.1",
          "cachedResultName": "gpt-5.1"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "27af62f4-2621-4ef6-a632-6055b6cae33b",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1792,
        560
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"email_contains_invoice\": {\n      \"type\": \"boolean\",\n      \"description\": \"Whether the email body contains or describes an invoice\"\n    }\n  },\n  \"required\": [\"email_contains_invoice\"]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "7a128186-cb72-41ce-9763-cdd888e029bf",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2240,
        576
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ecfb06b1-c5f2-4803-99c4-007cc72938d8",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2224,
        416
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.1",
          "cachedResultName": "gpt-5.1"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "8a51021e-e72a-4bfb-9289-14779c1ba073",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        2464,
        528
      ],
      "parameters": {
        "autoFix": true,
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"properties\": {\n    \"date_email\": {\n      \"type\": \"string\",\n      \"format\": \"date-time\",\n      \"description\": \"Date and time when the email was sent, ISO 8601 (YYYY-MM-DDThh:mm:ss±hh:mm)\"\n    },\n    \"date_invoice\": {\n      \"type\": \"string\",\n      \"format\": \"date\",\n      \"description\": \"Invoice date, ISO 8601 (YYYY-MM-DD)\"\n    },\n    \"invoice_nr\": {\n      \"type\": \"string\",\n      \"description\": \"Invoice number exactly as shown on the invoice\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Short description of what the invoice is for\"\n    },\n    \"provider\": {\n      \"type\": \"string\",\n      \"description\": \"Invoice issuer / vendor\"\n    },\n    \"net_amount\": {\n      \"type\": \"number\",\n      \"description\": \"Net amount before VAT\"\n    },\n    \"vat\": {\n      \"type\": \"number\",\n      \"description\": \"VAT percentage (e.g. 20 for 20%)\"\n    },\n    \"gross_amount\": {\n      \"type\": \"number\",\n      \"description\": \"Total amount including VAT\"\n    },\n    \"label\": {\n      \"type\": \"string\",\n      \"enum\": [\"saas\", \"hardware\", \"other\"],\n      \"description\": \"Category of the invoice\"\n    },\n    \"currency\": {\n      \"type\": \"string\",\n      \"description\": \"ISO 4217 currency code, e.g. EUR, USD, CHF\"\n    }\n  },\n  \"required\": [\n    \"date_email\",\n    \"date_invoice\",\n    \"invoice_nr\",\n    \"description\",\n    \"provider\",\n    \"net_amount\",\n    \"vat\",\n    \"gross_amount\",\n    \"label\",\n    \"currency\"\n  ]\n}\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "a16933f8-7506-4549-95c8-efbea1550bdf",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        784,
        336
      ],
      "parameters": {
        "filters": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyHour"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "5b76b6d8-5a0a-4ee0-a2c1-73369af3b3a2",
      "name": "Upload file",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        3264,
        160
      ],
      "parameters": {
        "name": "=Invoice_{{ $('Document the invoice parameters').item.json.provider }}_{{ $('Document the invoice parameters').item.json.date_invoice }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1rbR8RAmXZDCbqQAhypq2m_YDxYbOiXGa",
          "cachedResultUrl": "https://drive.google.YOUR_AWS_SECRET_KEY_HERE_YDxYbOiXGa",
          "cachedResultName": "invoices"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "id": "credential-id",
          "name": "googleDriveOAuth2Api Credential"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "4e713889-d996-4436-a5a9-879d580ef64e",
      "name": "Invoice Recognition Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1648,
        288
      ],
      "parameters": {
        "text": "=You are a precise email classifier. Your task: determine if the email includes an invoice in the message body and/or as an attachment. Be strict and evidence-based.\n\n\nDefinitions\nInvoice: A document requesting payment for goods/services, typically with supplier details, invoice number, issue date, due date/terms, line items or description, and a total amount (with currency). Includes “tax invoice.” Credit notes/debit notes count as invoice-like if they settle or adjust an invoice.\nNot invoices: quotes/estimates, pro forma invoices (unless explicitly used as the payable document in that context), order confirmations, purchase orders, statements of account, shipping notices, delivery notes, receipts (unless your policy treats receipts as invoices—see Policy toggle), marketing emails, reminders without the invoice attached or shown.\nPolicy toggle: include_receipts = true if the receipt includes net, gross and a tax rate and fals if the receipt only includes payment confirmation without net; gross and vat rale.\nLanguages and synonyms (non-exhaustive)\nEN: invoice, tax invoice, bill, credit note, debit note, inv, inv#\nDE: Rechnung, Gutschrift\nFR: facture, avoir\nES/PT: factura/fatura, nota de crédito\nIT: fattura, nota di credito\nNL: factuur, creditnota\nPL/CZ: faktura\nNordics: faktura\nFI: lasku\nTR: fatura\nEL: τιμολόγιο\nRU: счёт-фактура\nAR: فاتورة\nZH: 发票, 账单\nJA: 請求書\nKO: 세금계산서, 인보이스\nRecognize abbreviations and filename hints: INV_2025-001.pdf, Rechnung_12345, Facture-2025, Fattura_345, faktura_*.pdf.\n\nAttachments to consider\nDocuments: pdf, pdf/a, doc, docx, xls, xlsx, csv\nImages: jpg/jpeg, png, tiff/tif, heic\nArchives: zip, rar, 7z (assume unknown unless contents listed)\nEmails: eml, msg (may contain invoice attachments)\nE-invoice/XML: xml (UBL 2.x, PEPPOL BIS, XRechnung, Factur-X/ZUGFeRD), json\nIf text extraction is unavailable (e.g., images, password-protected PDFs), rely on filename, MIME type, and surrounding body text cues. Do not assume OCR unless content is provided.\nPositive body indicators (examples)\n“Invoice”, “Tax Invoice”, “Rechnung”, “Facture”, “Fattura”, “Factuur”, “Faktura”, “請求書”\nPatterns like: Invoice No/Number/ID, INV-xxxx, Rechnungsnr., PO/Order reference, Due date/Net 30, VAT/Tax ID, subtotal/total, currency symbols/ISO codes (USD, EUR, GBP)\nClear payable context: “Amount due”, “Please find attached invoice”, “Your invoice for [period]”\nNegative/ambiguous cases (do NOT count as invoice unless clearly attached/shown)\nApproval reminders without the actual invoice\nPayment confirmations/receipts (default excluded)\nQuotes/estimates/pro forma (unless also a payable invoice is present)\nMonthly statements or balance summaries\nShipping/tracking notifications\nLinks to a portal to download the invoice (no in-body invoice, no attachment = NOT present)\nSpam/fraud cues with no concrete invoice content\nDecision rules\nBody = YES if the email body itself includes enough structured indicators that it is the invoice (e.g., labeled invoice, supplier details, invoice number/date, total due). A single phrase like “invoice below” without the actual invoice details is NOT enough.\nAttachment = YES if any attachment is very likely an invoice based on filename, type, or extracted content. For images or locked PDFs with no text, use filename + body context to decide likelihood.\nBoth = If invoice appears in body and an invoice file is attached.\nNeither = If none of the above applies.\nUnsure = If evidence is insufficient or contradictory.\nBe conservative. Support your decision with concrete evidence snippets (short quotes, filenames). Prefer “Neither” or “Unsure” over guessing.\n\nUse null for unknown extracted fields.\nIf multiple candidate attachments exist, include all in evidence. If multiple invoices are present, mention in notes.\nExamples\nExample 1 (Attachment = YES):\n\nSubject: “Invoice INV-1045 for March”\nBody: “Please find attached invoice INV-1045. Due in 14 days.”\nAttachments: INV-1045.pdf (application/pdf)\nExpected:\ncontains_invoice: \"yes\", location: \"attachment\", confidence: ~0.95\nEvidence cites filename “INV-1045.pdf” and body cue “attached invoice INV-1045”\nExample 2 (Body = YES):\n\nBody includes: “Tax Invoice”, “Invoice No: 2025-033”, supplier details, total = “€1,240.00”\nNo attachments.\nExpected:\ncontains_invoice: \"yes\", location: \"body\", confidence: high\nEvidence cites invoice number, total, and header “Tax Invoice”\nExample 3 (Neither):\n\nBody: “Your monthly statement is ready. Log in to download your invoices.”\nNo attachments.\nExpected:\ncontains_invoice: \"no\", location: \"neither\", confidence: high\nExample 4 (Unsure):\n\nSubject: “Rechnung”\nBody: “Hier ist es.”\nAttachment: image_1234.png (no text extraction)\nExpected:\ncontains_invoice: \"unsure\" or \"yes\" (low confidence) depending on filename/body context; note OCR unavailability.\nAdditional guidelines\nIgnore email signatures, legal disclaimers, and marketing footers.\nIf the email only contains a link to fetch the invoice, classify as “no/neither”.\nFor forwarded chains, if an earlier message includes an invoice in its body or as a nested attachment, you may classify accordingly and note it.\nIf policy include_receipts = true, treat “Receipt”/“Payment receipt” with clear amount and supplier as invoices; otherwise exclude.\n\nE-Mail Elements:\nsubject: {{ $('Get a message').all()[0].json.subject }}\ntext: {{ $('Get a message').all()[0].json.text }}\nFrom: {{ $('Get a message').all()[0].json.headers.from }}\nDate: {{ $('Get a message').all()[0].json.headers.date }}\n\nAttachment text extraction (if available):\n{{ $json.text }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "d2160eac-2baa-4121-9e42-8422a7c6d0e2",
      "name": "Invoice Data extractor",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2224,
        192
      ],
      "parameters": {
        "text": "=You are a precise information extraction system. Your task is to produce VALID JSON that conforms exactly to the schema below. All fields are required. Empty strings, null, or missing fields are strictly forbidden.\n\nIf a value is not explicitly stated in the invoice or the email, you must derive it logically (e.g., VAT %, net amount) or return the closest defensible interpretation. If none is possible, infer a conservative best-guess based on available invoice conventions (e.g., label = \"other\" if unclear).\n\nAlways normalize values strictly:\n\n- date_email: Convert email header Date to ISO 8601 date-time (YYYY-MM-DDThh:mm:ss±hh:mm)\n- date_invoice: Convert invoice date to ISO 8601 date (YYYY-MM-DD)\n- currency: Always use ISO 4217 code (EUR, USD, CHF). Convert from symbols if needed.\n- net_amount, gross_amount: Convert to numbers. Normalize thousand separators, decimal commas → decimal points.\n- vat: Must be a percentage number (e.g., 20). If the invoice gives only VAT amount and net amount, compute percentage.\n- description: Short neutral textual summary (max 1 sentence).\n- provider: Exact vendor name from the invoice.\n- label: \"saas\", \"hardware\", or \"other\". If unclear, choose \"other\".\n\nExtract ONLY based on:\n1. Invoice text: {{ $('Extract from File').item.json.text }}\n2. Email text: {{ $('Get a message').all()[0].json.text }}\n3. Email date header: {{ $('Get a message').all()[0].json.headers.date }}\n\nYour output must be 100% valid JSON and match this schema:\n\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"date_email\": {\n      \"type\": \"string\",\n      \"format\": \"date-time\",\n      \"description\": \"Date and time when the email was sent, ISO 8601 (YYYY-MM-DDThh:mm:ss±hh:mm)\"\n    },\n    \"date_invoice\": {\n      \"type\": \"string\",\n      \"format\": \"date\",\n      \"description\": \"Invoice date, ISO 8601 (YYYY-MM-DD)\"\n    },\n    \"invoice_nr\": {\n      \"type\": \"string\",\n      \"description\": \"Invoice number exactly as shown on the invoice\"\n    },\n    \"description\": {\n      \"type\": \"string\",\n      \"description\": \"Short description of what the invoice is for\"\n    },\n    \"provider\": {\n      \"type\": \"string\",\n      \"description\": \"Invoice issuer / vendor\"\n    },\n    \"net_amount\": {\n      \"type\": \"number\",\n      \"description\": \"Net amount before VAT\"\n    },\n    \"vat\": {\n      \"type\": \"number\",\n      \"description\": \"VAT percentage (e.g. 20 for 20%)\"\n    },\n    \"gross_amount\": {\n      \"type\": \"number\",\n      \"description\": \"Total amount including VAT\"\n    },\n    \"label\": {\n      \"type\": \"string\",\n      \"enum\": [\"saas\", \"hardware\", \"other\"],\n      \"description\": \"Category of the invoice\"\n    },\n    \"currency\": {\n      \"type\": \"string\",\n      \"description\": \"ISO 4217 currency code, e.g. EUR, USD, CHF\"\n    }\n  },\n  \"required\": [\n    \"date_email\",\n    \"date_invoice\",\n    \"invoice_nr\",\n    \"description\",\n    \"provider\",\n    \"net_amount\",\n    \"vat\",\n    \"gross_amount\",\n    \"label\",\n    \"currency\"\n  ]\n}\n\n",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "cf993c5d-b98c-45ef-ad61-45ca641a39dc",
      "name": "Extract from File",
      "type": "n8n-nodes-base.extractFromFile",
      "onError": "continueRegularOutput",
      "position": [
        1376,
        336
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1.1
    },
    {
      "id": "5684ec8f-fdd4-48dc-8572-368aa5f58f26",
      "name": "Check wether it is an invoice",
      "type": "n8n-nodes-base.if",
      "position": [
        1984,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e5910b6f-1042-46d2-a435-bac8392d0942",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.output.email_contains_invoice }}",
              "rightValue": false
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "7c8cae1c-643f-4284-a5c8-f98b3df1624e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 496,
        "height": 688,
        "content": "## Gmail Trigger based on user customized interval\n**then get the gmail parameter inclusive text and attachments and extract all pdf files from attachments with js-code"
      },
      "typeVersion": 1
    },
    {
      "id": "fc0c1a5c-dfae-4807-8f84-668c716c3c9f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 688,
        "content": "## Extract the text from the pdf attachment if exists\n**otherwise ignore and further process"
      },
      "typeVersion": 1
    },
    {
      "id": "8a5f7033-49ce-4e64-9296-1f3cb3711b69",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1600,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 688,
        "content": "## Analyse the context of the mail and the attachments and process further in case it is an invoice\n**otherwise ignore and stop the process"
      },
      "typeVersion": 1
    },
    {
      "id": "315a69ed-fe06-4630-984e-042b724599a3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2160,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 336,
        "height": 688,
        "content": "## Extract the relevant invoice parameters\n**date_email, date_invoice, invoice_nr, description, provider, net_amount, vat, gross_amount, label, currency\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1a0e84bb-ef25-41f4-9e53-f743761991dd",
      "name": "Check wether it was a file-invoice or text invoice",
      "type": "n8n-nodes-base.if",
      "position": [
        2560,
        320
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "dbba29ee-79b0-43ba-84ab-10296a941ce8",
              "operator": {
                "type": "object",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $('Get a message').all()[0].binary }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ac9ec995-a6fb-459a-ba7c-7cd93ca607ef",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2496,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 688,
        "content": "## Was the invoice in attachments or in the mail body?\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0e389153-4102-466a-8851-7f694292909b",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 976,
        "height": 336,
        "content": "## Document the paramters in sheet, uoload the invoice file to drive and update the sheet with the invoice-url in your drive, and finally mark the invoice message as read in you gmail\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fc7ab85c-d7b8-4452-9e4f-60f53a0ef0fb",
      "name": "Document the invoice parameters",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2800,
        144
      ],
      "parameters": {
        "columns": {
          "value": {
            "vat": "={{ $json.output.vat }}",
            "label": "={{ $json.output.label }}",
            "currency": "={{ $json.output.currency }}",
            "provider": "={{ $json.output.provider }}",
            "date_email": "={{ $json.output.date_email }}",
            "invoice_nr": "={{ $json.output.invoice_nr }}",
            "net_amount": "={{ $json.output.net_amount }}",
            "description": "={{ $json.output.description }}",
            "date_invoice": "={{ $json.output.date_invoice }}",
            "gross_amount": "={{ $json.output.gross_amount }}"
          },
          "schema": [
            {
              "id": "date_email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date_invoice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_invoice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "invoice_nr",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "invoice_nr",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "provider",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "net_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "net_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "vat",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "vat",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "gross_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "gross_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "label",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "label",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "link",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "=gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1 your_spreadsheet_id",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1 your_spreadsheet_id/edit?usp=drivesdk",
          "cachedResultName": "invoices"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "39eb6c11-d75c-4967-97cc-3f6078fa2cee",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2704,
        384
      ],
      "parameters": {
        "color": 7,
        "width": 976,
        "height": 336,
        "content": "## Document the paramters in sheet, generate a link to the email\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a2305d63-67c3-4743-a2e0-ed738a6f5b1a",
      "name": "Update Invoice parameters",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3472,
        160
      ],
      "parameters": {
        "columns": {
          "value": {
            "vat": "={{ $('Merge').item.json.vat }}",
            "link": "=https://drive.google.com/file/d/{{ $json.id }}/view",
            "label": "={{ $('Merge').item.json.label }}",
            "currency": "={{ $('Merge').item.json.currency }}",
            "provider": "={{ $('Merge').item.json.provider }}",
            "date_email": "={{ $('Merge').item.json.date_email }}",
            "invoice_nr": "={{ $('Merge').item.json.invoice_nr }}",
            "net_amount": "={{ $('Merge').item.json.net_amount }}",
            "description": "={{ $('Merge').item.json.description }}",
            "date_invoice": "={{ $('Merge').item.json.date_invoice }}",
            "gross_amount": "={{ $('Merge').item.json.gross_amount }}"
          },
          "schema": [
            {
              "id": "date_email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date_invoice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_invoice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "invoice_nr",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "invoice_nr",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "provider",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "net_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "net_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "vat",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "vat",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "gross_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "gross_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "label",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "label",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "link",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "invoice_nr"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1 your_spreadsheet_id/edit#gid=0",
          "cachedResultName": "Tabellenblatt1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1 your_spreadsheet_id",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1 your_spreadsheet_id/edit?usp=drivesdk",
          "cachedResultName": "invoices"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3f3616f4-f2e5-415d-9cf6-b2944780cefe",
      "name": "Update text Invoice parameters",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3104,
        528
      ],
      "parameters": {
        "columns": {
          "value": {
            "vat": "={{ $json.output.vat }}",
            "link": "={{ 'https://mail.google.com/mail/u/0/#inbox/' + $('Get a message').first().json.id }}",
            "label": "={{ $json.output.label }}",
            "currency": "={{ $json.output.currency }}",
            "provider": "={{ $json.output.provider }}",
            "date_email": "={{ $json.output.date_email }}",
            "invoice_nr": "={{ $json.output.invoice_nr }}",
            "net_amount": "={{ $json.output.net_amount }}",
            "description": "={{ $json.output.description }}",
            "date_invoice": "={{ $json.output.date_invoice }}",
            "gross_amount": "={{ $json.output.gross_amount }}"
          },
          "schema": [
            {
              "id": "date_email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date_invoice",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_invoice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "invoice_nr",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "invoice_nr",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "description",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "description",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "provider",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "provider",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "net_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "net_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "vat",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "vat",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "gross_amount",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "gross_amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "label",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "label",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "invoice_nr"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1 your_spreadsheet_id/edit#gid=0",
          "cachedResultName": "Tabellenblatt1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1 your_spreadsheet_id",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1 your_spreadsheet_id/edit?usp=drivesdk",
          "cachedResultName": "invoices"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "credential-id",
          "name": "googleSheetsOAuth2Api Credential"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "195ac57c-2dad-415a-a432-6a7c7dc8edaf",
      "name": "Mark a message as read",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3808,
        320
      ],
      "webhookId": "2e9d50e4-28bd-4f2a-a574-eb3b5ff91550",
      "parameters": {
        "messageId": "={{ $('Gmail Trigger').all()[0].json.id }}",
        "operation": "markAsRead"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "b8f65fe4-0be2-4e40-84c3-7b3cc4988236",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "onError": "continueRegularOutput",
      "position": [
        1136,
        336
      ],
      "parameters": {
        "jsCode": "// Function (nicht Function Item)\nreturn items.flatMap(item => {\n  const bin = item.binary || {};\n  const keys = Object.keys(bin).filter(k => k.startsWith('attachment_')).sort();\n  return keys.map(k => ({\n    json: {\n      attachmentKey: k,\n      fileName: bin[k]?.fileName,\n      mimeType: bin[k]?.mimeType,\n    },\n    binary: { data: bin[k] }, // jetzt heisst die Binary-Property überall 'data'\n  }));\n});"
      },
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "e0923dcc-5e65-4b5c-982a-1f5054eba3a9",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3056,
        160
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "c7b9e396-e66a-43df-8fe3-eb867b5084c5",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -192,
        -176
      ],
      "parameters": {
        "width": 784,
        "height": 1360,
        "content": "## Who’s it for\n\nThis template is for founders, finance teams, and solo operators who receive lots of invoices by email and want them captured automatically in a single, searchable source of truth. If you’re tired of hunting through your inbox for invoice PDFs or “that one receipt from three months ago,” this is for you.\n\n## What it does / How it works\n\nThe workflow polls your Gmail inbox on a schedule and fetches new messages including their attachments. A JavaScript Code node restructures all attachments, and a PDF extraction node reads any attached PDFs.  \nAn AI “Invoice Recognition Agent” then analyzes the email body and attachments to decide whether the email actually contains an invoice. If not, the workflow stops.\n\nIf it is an invoice, a second AI “Invoice Data Extractor” pulls structured fields such as `date_email`, `date_invoice`, `invoice_nr`, `description`, `provider`, `net_amount`, `vat`, `gross_amount`, `label` (saas/hardware/other), and `currency`. Depending on whether the invoice is in an attachment or directly in the email text, the workflow either:\n\n- uploads the invoice file to Google Drive, or  \n- document a direct link to the mail,\n\nthen appends/updates a row in Google Sheets with all invoice parameters plus a Drive link, and finally marks the Gmail message as read.\n\n## How to set up\n\n1. Add and authenticate:\n   - Gmail credentials  \n   - Google Sheets credentials  \n   - Google Drive credentials  \n   - OpenAI (or compatible) credentials for the AI nodes\n2. Create or select a Google Sheet with the expected columns (date_email, date_invoice, invoice_nr, description, provider, net_amount, vat, gross_amount, label, currency, link).\n3. Create or select a Google Drive folder where invoices/docs should be stored.\n4. Adjust the Gmail Trigger filters (labels, search query, polling interval) to match the mailbox you want to process.\n5. Update node credentials and resource IDs (Sheet, Drive folder) via the node UIs, not hardcoded in HTTP nodes.\n\n## Requirements\n\n- n8n instance (cloud or self-hosted)  \n- Gmail account with OAuth2 setup  \n- Google Drive and Google Sheets access  \n- OpenAI (or compatible) API key configured in n8n  \n- Sufficient permissions to read emails, read/write Drive files, and edit the target Sheet\n\n## How to customize the workflow\n\n- **Change invoice categories**: Extend the `label` enum (e.g., add “services”, “subscriptions”) in the extraction schema and adjust any downstream logic.\n- **Refine invoice detection**: Tweak the AI prompts to be more or less strict about what counts as an invoice or receipt.\n- **Add notifications**: After updating the Sheet, send a Slack/Teams message or email summary for high-value invoices.\n- **Filter by sender or subject**: Narrow the Gmail Trigger to specific vendors, labels, or keywords.\n- **Extend the data model**: Add fields (e.g., cost center, project code) to the extractor prompt and Sheet mapping to fit your bookkeeping setup."
      },
      "typeVersion": 1
    },
    {
      "id": "615cac4d-1a01-4a0e-ad83-0d2699cb904b",
      "name": "Get a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        944,
        336
      ],
      "webhookId": "55284935-3cf2-49d7-8191-21b9a178deeb",
      "parameters": {
        "simple": false,
        "options": {
          "downloadAttachments": true,
          "dataPropertyAttachmentsPrefixName": "attachment_"
        },
        "messageId": "={{ $json.id }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "credential-id",
          "name": "gmailOAuth2 Credential"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "ca5f4e6a-320e-4ff5-b289-226f02a4b1f2",
      "name": "OpenAI Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2528,
        752
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.1",
          "cachedResultName": "gpt-5.1"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "credential-id",
          "name": "openAiApi Credential"
        }
      },
      "typeVersion": 1.3
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "31c9f7ea-d08f-4280-8881-76f94089ded8",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Upload file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload file": {
      "main": [
        [
          {
            "node": "Update Invoice parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a message": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "Get a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from File": {
      "main": [
        [
          {
            "node": "Invoice Recognition Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Invoice Recognition Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Extract from File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Invoice Data extractor",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "Structured Output Parser1",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Invoice Data extractor": {
      "main": [
        [
          {
            "node": "Check wether it was a file-invoice or text invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Invoice Recognition Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Invoice Recognition Agent": {
      "main": [
        [
          {
            "node": "Check wether it is an invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Invoice Data extractor",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Update Invoice parameters": {
      "main": [
        [
          {
            "node": "Mark a message as read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check wether it is an invoice": {
      "main": [
        [
          {
            "node": "Invoice Data extractor",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update text Invoice parameters": {
      "main": [
        [
          {
            "node": "Mark a message as read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document the invoice parameters": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check wether it was a file-invoice or text invoice": {
      "main": [
        [
          {
            "node": "Document the invoice parameters",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update text Invoice parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}