{
  "id": "Ozur6RRxL9nG7rbH",
  "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": {
          "name": "<your 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": {
          "name": "<your 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\u00b1hh: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": {
          "name": "<your 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": {
          "name": "<your 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 \u201ctax invoice.\u201d 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\u2014see 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\u00e9dito\nIT: fattura, nota di credito\nNL: factuur, creditnota\nPL/CZ: faktura\nNordics: faktura\nFI: lasku\nTR: fatura\nEL: \u03c4\u03b9\u03bc\u03bf\u03bb\u03cc\u03b3\u03b9\u03bf\nRU: \u0441\u0447\u0451\u0442-\u0444\u0430\u043a\u0442\u0443\u0440\u0430\nAR: \u0641\u0627\u062a\u0648\u0631\u0629\nZH: \u53d1\u7968, \u8d26\u5355\nJA: \u8acb\u6c42\u66f8\nKO: \uc138\uae08\uacc4\uc0b0\uc11c, \uc778\ubcf4\uc774\uc2a4\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\u201cInvoice\u201d, \u201cTax Invoice\u201d, \u201cRechnung\u201d, \u201cFacture\u201d, \u201cFattura\u201d, \u201cFactuur\u201d, \u201cFaktura\u201d, \u201c\u8acb\u6c42\u66f8\u201d\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: \u201cAmount due\u201d, \u201cPlease find attached invoice\u201d, \u201cYour invoice for [period]\u201d\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 \u201cinvoice below\u201d 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 \u201cNeither\u201d or \u201cUnsure\u201d 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: \u201cInvoice INV-1045 for March\u201d\nBody: \u201cPlease find attached invoice INV-1045. Due in 14 days.\u201d\nAttachments: INV-1045.pdf (application/pdf)\nExpected:\ncontains_invoice: \"yes\", location: \"attachment\", confidence: ~0.95\nEvidence cites filename \u201cINV-1045.pdf\u201d and body cue \u201cattached invoice INV-1045\u201d\nExample 2 (Body = YES):\n\nBody includes: \u201cTax Invoice\u201d, \u201cInvoice No: 2025-033\u201d, supplier details, total = \u201c\u20ac1,240.00\u201d\nNo attachments.\nExpected:\ncontains_invoice: \"yes\", location: \"body\", confidence: high\nEvidence cites invoice number, total, and header \u201cTax Invoice\u201d\nExample 3 (Neither):\n\nBody: \u201cYour monthly statement is ready. Log in to download your invoices.\u201d\nNo attachments.\nExpected:\ncontains_invoice: \"no\", location: \"neither\", confidence: high\nExample 4 (Unsure):\n\nSubject: \u201cRechnung\u201d\nBody: \u201cHier ist es.\u201d\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 \u201cno/neither\u201d.\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 \u201cReceipt\u201d/\u201cPayment receipt\u201d 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\u00b1hh: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 \u2192 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\u00b1hh: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": {
          "name": "<your 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": {
          "name": "<your 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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "195ac57c-2dad-415a-a432-6a7c7dc8edaf",
      "name": "Mark a message as read",
      "type": "n8n-nodes-base.gmail",
      "position": [
        3808,
        320
      ],
      "parameters": {
        "messageId": "={{ $('Gmail Trigger').all()[0].json.id }}",
        "operation": "markAsRead"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your 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 \u00fcberall '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\u2019s 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\u2019re tired of hunting through your inbox for invoice PDFs or \u201cthat one receipt from three months ago,\u201d 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 \u201cInvoice Recognition Agent\u201d 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 \u201cInvoice Data Extractor\u201d 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 \u201cservices\u201d, \u201csubscriptions\u201d) 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
      ],
      "parameters": {
        "simple": false,
        "options": {
          "downloadAttachments": true,
          "dataPropertyAttachmentsPrefixName": "attachment_"
        },
        "messageId": "={{ $json.id }}",
        "operation": "get"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your 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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    }
  ],
  "active": false,
  "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
          }
        ]
      ]
    }
  }
}