{"id":1771,"date":"2025-11-25T16:06:40","date_gmt":"2025-11-25T16:06:40","guid":{"rendered":"https:\/\/paoloronco.it\/?p=1771"},"modified":"2025-12-03T15:57:57","modified_gmt":"2025-12-03T15:57:57","slug":"n8n-template-automated-invoice-archiving","status":"publish","type":"post","link":"https:\/\/paoloronco.it\/en\/n8n-template-automated-invoice-archiving\/","title":{"rendered":"[n8n-template] Automated Invoice Archiving"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Automatically fetch, store, and extract key information from invoices received via email from your ISP or utility provider (electricity, gas, telecom, water, etc.).The workflow saves the invoices to Google Drive (or optionally to your personal FTP\/SFTP server) and logs all invoice details into Google Sheets via AI-powered extraction.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/paoloronco.it\/wp-content\/uploads\/2025\/11\/image-1-1024x353.png\" alt=\"\" class=\"wp-image-1857\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc68\ud83c\udffb\u200d\ud83d\udcbbGitHub: <a href=\"https:\/\/github.com\/paoloronco\/n8n-templates\/\">paoloronco\/n8n-templates<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udcfd\ufe0f<strong>Video<\/strong>: <a href=\"https:\/\/www.youtube.com\/watch?v=0s-95L8cmyE&amp;feature=youtu.be\">AI Video Automated Invoice Archiving &#8211; YouTube<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc65 n8n Community Template:&nbsp;<strong>Coming Soon<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Setup Guide:<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before configuring the workflow, you\u2019ll need:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>n8n instance<\/strong>\n<ul class=\"wp-block-list\">\n<li>Self-hosted or n8n Cloud, with access to credentials.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Google account<\/strong> with:\n<ul class=\"wp-block-list\">\n<li>Gmail access<\/li>\n\n\n\n<li>Google Drive<\/li>\n\n\n\n<li>Google Sheets<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>(Optional) FTP\/SFTP server<\/strong> if you want to keep a copy of each invoice outside Google.<\/li>\n\n\n\n<li><strong>LLM \/ AI provider<\/strong>\n<ul class=\"wp-block-list\">\n<li>For example <strong>OpenRouter<\/strong> or <strong>OpenAI<\/strong>, with:\n<ul class=\"wp-block-list\">\n<li>API key<\/li>\n\n\n\n<li>Sufficient credit \/ quota.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Invoice emails<\/strong>\n<ul class=\"wp-block-list\">\n<li>Your ISP\/utility provider should send invoices from a <strong>consistent email address<\/strong> (e.g., <code>billing@provider.com<\/code>).<\/li>\n\n\n\n<li>Invoices should be <strong>PDF attachments<\/strong>. Text-based PDFs work best.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Import the Workflow into n8n<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Download or copy the workflow JSON (<code>20-SaveInvoices-Templates.json<\/code>).<\/li>\n\n\n\n<li>In n8n, go to <strong>Workflows \u2192 Import from File \/ Clipboard<\/strong>.<\/li>\n\n\n\n<li>Import the JSON.<\/li>\n\n\n\n<li>Save the workflow (give it a clear name, e.g., <code>Automated Invoice Archiving<\/code>).<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">You should now see a flow that includes nodes like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Schedule Trigger<\/strong><\/li>\n\n\n\n<li><strong>Get many messages (Gmail)<\/strong><\/li>\n\n\n\n<li><strong>Filter-contains_attachment<\/strong><\/li>\n\n\n\n<li><strong>Gmail-Get_Invoice<\/strong><\/li>\n\n\n\n<li><strong>GoogleDrive-upload-file<\/strong><\/li>\n\n\n\n<li><strong>downloadFile<\/strong><\/li>\n\n\n\n<li><strong>FTP-upload-octopus<\/strong><\/li>\n\n\n\n<li><strong>Extract from File1<\/strong><\/li>\n\n\n\n<li><strong>OpenRouter Chat Model1<\/strong><\/li>\n\n\n\n<li><strong>AI_Agent-fields<\/strong><\/li>\n\n\n\n<li><strong>Code_extractFields<\/strong><\/li>\n\n\n\n<li><strong>GoogleSheets_save<\/strong><\/li>\n\n\n\n<li><strong>Delete a file1<\/strong><\/li>\n\n\n\n<li><strong>Delete a message<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The sticky notes in the canvas will help you visually understand each section.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Configure Credentials<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 Gmail (OAuth2)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This workflow uses the Gmail nodes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Get many messages<\/strong><\/li>\n\n\n\n<li><strong>Gmail-Get_Invoice<\/strong><\/li>\n\n\n\n<li><strong>Delete a message<\/strong><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Steps<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In n8n, go to <strong>Credentials \u2192 New \u2192 Gmail OAuth2<\/strong>.<\/li>\n\n\n\n<li>Follow the official guide to create OAuth credentials and connect Gmail:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.n8n.io\/integrations\/builtin\/app-nodes\/n8n-nodes-base.gmail\/\">Gmail Node Docs<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Once created, select this credential in all Gmail nodes in the workflow.<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Tip: Use a dedicated Gmail account or label for invoices if possible. That makes testing and monitoring easier.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 Google Drive<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Used by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GoogleDrive-upload-file<\/strong> \u2014 uploads the invoice PDF<\/li>\n\n\n\n<li><strong>Delete a file1<\/strong> \u2014 optionally cleans up the temp file from Drive<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Steps<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In n8n, create a <strong>Google Drive OAuth2<\/strong> credential.<\/li>\n\n\n\n<li>Follow:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.n8n.io\/integrations\/builtin\/app-nodes\/n8n-nodes-base.googledrive\/\">Google Drive Node Docs<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Open the <strong>GoogleDrive-upload-file<\/strong> node and select your Google Drive credential.<\/li>\n\n\n\n<li>In the node:\n<ul class=\"wp-block-list\">\n<li>Choose <strong>\u201cMy Drive\u201d<\/strong> or your desired drive<\/li>\n\n\n\n<li>Set the <strong>Folder ID<\/strong> where you want to store invoices.\n<ul class=\"wp-block-list\">\n<li>In Google Drive, open the folder \u2192 copy the ID from the URL, e.g.<br><code>https:\/\/drive.google.com\/drive\/folders\/ABC123...<\/code><br>\u2192 the part after <code>\/folders\/<\/code> is the ID.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Do the same credential selection for <strong>Delete a file1<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.3 FTP\/SFTP (Optional)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Used by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>FTP-upload-octopus<\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you don\u2019t need FTP, you can disable or remove this node. If you do:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In n8n, create a new <strong>SFTP<\/strong> or <strong>FTP<\/strong> credential with your server details (host, port, username, password or SSH key).<\/li>\n\n\n\n<li>Check the official docs if needed:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/docs.n8n.io\/integrations\/builtin\/core-nodes\/n8n-nodes-base.ftp\/\">FTP Node Docs<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In the <strong>FTP-upload-octopus<\/strong> node:\n<ul class=\"wp-block-list\">\n<li>Set <strong>Protocol<\/strong> to <code>sftp<\/code> (recommended) or <code>ftp<\/code>.<\/li>\n\n\n\n<li>Select your credential.<\/li>\n\n\n\n<li>In <strong>PATH<\/strong>, enter the directory where you want to store invoices, e.g.:\n<ul class=\"wp-block-list\">\n<li><code>\/home\/user\/invoices\/<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Keep the rest of the settings as they are unless you know you need to change them.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.4 AI Provider (OpenRouter \/ OpenAI \/ Other LLM)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Used by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OpenRouter Chat Model1<\/strong><\/li>\n\n\n\n<li><strong>AI_Agent-fields<\/strong> (LangChain Agent node referencing the chat model)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This pair of nodes is responsible for turning raw PDF text into structured JSON (vendor, date, amount, line items, taxes, etc.).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Steps<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Sign up \/ log in with your preferred provider (e.g., OpenRouter, OpenAI).<\/li>\n\n\n\n<li>Obtain an <strong>API key<\/strong>.<\/li>\n\n\n\n<li>In n8n, create a new credential for that provider (e.g., <strong>OpenRouter API<\/strong>).<\/li>\n\n\n\n<li>Open the <strong>OpenRouter Chat Model1<\/strong> node:\n<ul class=\"wp-block-list\">\n<li>Select your credential.<\/li>\n\n\n\n<li>Choose your preferred model. Suggested:\n<ul class=\"wp-block-list\">\n<li><code>gpt-4.1<\/code>, <code>gpt-4.1-mini<\/code><\/li>\n\n\n\n<li>or a strong <code>llama-3<\/code> variant.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Make sure the <strong>AI_Agent-fields<\/strong> node uses <strong>OpenRouter Chat Model1<\/strong> as its language model (already wired in the template).<\/li>\n<\/ol>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Note: The system prompt and extraction instructions are already configured in the template to return structured JSON with <code>vendor_name<\/code>, <code>invoice_date<\/code>, <code>total_amount<\/code>, <code>line_items<\/code>, tax fields, etc. You can tweak the prompt if your invoices follow specific formats.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3.5 Google Sheets (Service Account)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Used by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>GoogleSheets_save<\/strong> (append operation)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This node appends one row per processed invoice into a Google Sheet.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">3.5.1 Create a Sheet<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In Google Sheets, create a new spreadsheet.<\/li>\n\n\n\n<li>In the first row (header), create <strong>these columns<\/strong>:<\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>Vendor<\/code><\/li>\n\n\n\n<li><code>Type<\/code><\/li>\n\n\n\n<li><code>Date<\/code><\/li>\n\n\n\n<li><code>Amount<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can extend with more columns later (e.g., <code>Invoice Number<\/code>, <code>Tax<\/code>, etc.), but these four are what the template uses by default.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">3.5.2 Set up Service Account + Access<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In Google Cloud Console, create a <strong>Service Account<\/strong> and enable the Google Sheets API.<\/li>\n\n\n\n<li>Generate a JSON key and load it into n8n as a <strong>Google API<\/strong> credential.<\/li>\n\n\n\n<li>In Google Sheets, click <strong>Share<\/strong> and share the document with the Service Account email (usually something like <code>service-account-name@project-id.iam.gserviceaccount.com<\/code>) with <strong>edit<\/strong> access.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">3.5.3 Configure the Node<\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open <strong>GoogleSheets_save<\/strong> in n8n.<\/li>\n\n\n\n<li>Select your <strong>Google API<\/strong> credential.<\/li>\n\n\n\n<li>Set:\n<ul class=\"wp-block-list\">\n<li><strong>Document ID<\/strong> \u2014 from the Sheet URL\n<ul class=\"wp-block-list\">\n<li><code>https:\/\/docs.google.com\/spreadsheets\/d\/DOCUMENT_ID\/edit#gid=...<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Sheet Name<\/strong> \u2014 name of the tab where data should be added.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Check the mapping: by default, the workflow maps:<ul><li><code>Vendor<\/code> \u2190 <code>{{$json.vendor_name}}<\/code><\/li><li><code>Type<\/code> \u2190 <code>{{$json.line_items[0].description}}<\/code><\/li><li><code>Date<\/code> \u2190 <code>{{$json.invoice_date}}<\/code><\/li><li><code>Amount<\/code> \u2190 <code>{{$json.total_amount}}<\/code><\/li><\/ul>You can expand this mapping to include more fields (more columns in your Sheet + corresponding mapping in the node).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Configure Each Node (Step-by-Step)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now let\u2019s walk through the main nodes in execution order and confirm what you may need to change.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.1 Schedule Trigger<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Schedule Trigger<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: runs the workflow automatically.<\/li>\n\n\n\n<li>In this template it is set to run at a specific minute every hour.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the node.<\/li>\n\n\n\n<li>Adjust the <strong>interval<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Example: every <strong>1 hour<\/strong>, at minute <strong>25<\/strong>.<\/li>\n\n\n\n<li>Or once per day at a specific time.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Save.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.2 Get many messages (Gmail)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Get many messages<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: fetches emails from your inbox.<\/li>\n\n\n\n<li>Configured to:\n<ul class=\"wp-block-list\">\n<li>Use Gmail OAuth2 credential<\/li>\n\n\n\n<li>Filter by <strong>sender<\/strong> and <strong>PDF attachments<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Select your Gmail credential.<\/li>\n\n\n\n<li>Under <strong>Filters \u2192 Sender<\/strong>, set the email address that sends invoices, e.g.:\n<ul class=\"wp-block-list\">\n<li><code>billing@provider.com<\/code><\/li>\n\n\n\n<li><code>invoices@isp.com<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Keep <strong>downloadAttachments = true<\/strong> (the template already does this).<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.3 Filter-contains_attachment<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Filter-contains_attachment<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: ensures only messages <strong>with attachments<\/strong> proceed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This node uses a simple \u201cexists\u201d condition on the binary data of the previous node. Normally you don\u2019t need to change anything.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.4 Gmail-Get_Invoice<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Gmail-Get_Invoice<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: fetches the <strong>full email<\/strong> and <strong>downloads the attachment<\/strong> for each selected message.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Make sure the Gmail credential is selected.<\/li>\n\n\n\n<li>Confirm <code>downloadAttachments<\/code> is enabled.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The template already uses the ID from the <strong>Get many messages<\/strong> node, so there\u2019s nothing else to edit.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.5 GoogleDrive-upload-file<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>GoogleDrive-upload-file<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: uploads the invoice PDF to a specified Google Drive folder.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Select your Google Drive credential.<\/li>\n\n\n\n<li>Under <strong>Folder ID<\/strong>, paste the ID of your invoice folder.<\/li>\n\n\n\n<li>Name pattern is already set to something like:\n<ul class=\"wp-block-list\">\n<li><code>{{ $json.from.value[0].name }}-{{ $json.date }}<\/code><\/li>\n\n\n\n<li>You can leave this or change it.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.6 downloadFile<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>downloadFile<\/strong> (HTTP Request)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: downloads the file back from Google Drive based on its <code>webContentLink<\/code> so that it can be processed and\/or uploaded to FTP.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This node should work as-is; no configuration is usually required.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.7 FTP-upload-octopus (Optional)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>FTP-upload-octopus<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: saves the invoice PDF to your FTP\/SFTP server.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Set <strong>Protocol<\/strong> (<code>sftp<\/code> recommended).<\/li>\n\n\n\n<li>Choose your FTP\/SFTP credential.<\/li>\n\n\n\n<li>In <strong>Path<\/strong>, enter the directory (e.g. <code>\/invoices\/<\/code>), or a nested path.<\/li>\n\n\n\n<li>The file name is already cleaned and automatically given a <code>.pdf<\/code> extension if missing.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If you don\u2019t have or don\u2019t want FTP:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Either <strong>deactivate<\/strong> this node<\/li>\n\n\n\n<li>Or set the previous node (downloadFile) to connect directly to the next nodes, skipping FTP and subsequent Drive deletion.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.8 Delete a file1 (Optional)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Delete a file1<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: deletes the invoice PDF from Google Drive once it was uploaded to FTP and processed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You can:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Keep it active if you only want FTP + Sheets storage.<\/li>\n\n\n\n<li>Deactivate it if you prefer to keep invoices in Google Drive.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">It references the uploaded file ID from <strong>GoogleDrive-upload-file<\/strong>, so it should work without changes (as long as that node is configured).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.9 Delete a message (Optional)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Delete a message<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: deletes the original email from Gmail after successful processing.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to <strong>keep<\/strong> the emails in your inbox:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Simply <strong>deactivate<\/strong> this node.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Otherwise, leave it enabled \u2013 it uses the message ID from <strong>Get many messages<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.10 Extract from File1<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Extract from File1<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: extracts the text content from the PDF.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Mode: <code>pdf<\/code> (already set in the template).<\/li>\n\n\n\n<li>No additional configuration is usually needed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If your invoices are image-only PDFs, you\u2019ll need OCR support (e.g., via another service). For standard text-based invoices, this node is sufficient.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.11 AI_Agent-fields &amp; OpenRouter Chat Model1<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Nodes: <strong>OpenRouter Chat Model1<\/strong> \u2192 <strong>AI_Agent-fields<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose:\n<ul class=\"wp-block-list\">\n<li>Convert text into a structured JSON object.<\/li>\n\n\n\n<li>Extract fields like: <code>invoice_number<\/code>, <code>vendor_name<\/code>, <code>invoice_date<\/code>, <code>total_amount<\/code>, <code>tax_details<\/code>, <code>line_items<\/code>, etc.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In <strong>OpenRouter Chat Model1<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Select your credential and model.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In <strong>AI_Agent-fields<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Confirm the <strong>System Message<\/strong> describes your extraction needs.<\/li>\n\n\n\n<li>It already instructs the model to:\n<ul class=\"wp-block-list\">\n<li>Return <strong>only JSON<\/strong><\/li>\n\n\n\n<li>Include all required fields<\/li>\n\n\n\n<li>Ensure <code>line_total<\/code> values sum to <code>total_amount<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">You can adjust the prompt to match your country\u2019s invoice formats, additional fields, or specific tax rules.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.12 Code_extractFields<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>Code_extractFields<\/strong> (Code node)<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: cleans and parses the raw AI output into valid JSON, handling:\n<ul class=\"wp-block-list\">\n<li>Extra backticks<\/li>\n\n\n\n<li>Escaped characters<\/li>\n\n\n\n<li>Edge cases where the model wraps JSON in text.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">You usually don\u2019t need to edit this node. It returns a clean JSON object that the Google Sheets node can consume.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4.13 GoogleSheets_save<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Node: <strong>GoogleSheets_save<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Purpose: appends one row to your Google Sheet per invoice.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configure:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Select your <strong>Google API<\/strong> credential.<\/li>\n\n\n\n<li>Enter <strong>Document ID<\/strong> and <strong>Sheet Name<\/strong> (as described earlier).<\/li>\n\n\n\n<li>Verify \/ edit the column mapping:\n<ul class=\"wp-block-list\">\n<li><code>Vendor<\/code> \u2190 <code>{{$json.vendor_name}}<\/code><\/li>\n\n\n\n<li><code>Type<\/code> \u2190 <code>{{$json.line_items[0].description}}<\/code><\/li>\n\n\n\n<li><code>Date<\/code> \u2190 <code>{{$json.invoice_date}}<\/code><\/li>\n\n\n\n<li><code>Amount<\/code> \u2190 <code>{{$json.total_amount}}<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">To capture more fields:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add columns in Google Sheets<\/li>\n\n\n\n<li>Add the same fields to mapping in the node.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Testing the Workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before making it active on a schedule, test it manually.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.1 Send a Test Invoice<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Send yourself an email <strong>from the real sender address<\/strong> with a sample invoice PDF attached.<\/li>\n\n\n\n<li>Or forward an existing invoice to yourself while preserving the from-address (if possible).<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">5.2 Run the Workflow Once<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In n8n, click <strong>Execute Workflow<\/strong>.<\/li>\n\n\n\n<li>Watch each node:\n<ul class=\"wp-block-list\">\n<li><code>Get many messages<\/code> should output your test email.<\/li>\n\n\n\n<li><code>Filter-contains_attachment<\/code> should pass it through.<\/li>\n\n\n\n<li><code>Gmail-Get_Invoice<\/code> should show a <code>binary<\/code> entry containing the PDF.<\/li>\n\n\n\n<li><code>GoogleDrive-upload-file<\/code> should upload a file.<\/li>\n\n\n\n<li><code>Extract from File1<\/code> should output text.<\/li>\n\n\n\n<li><code>AI_Agent-fields<\/code> should output structured JSON.<\/li>\n\n\n\n<li><code>GoogleSheets_save<\/code> should append a row.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If something fails:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check credentials (expired tokens, incorrect keys).<\/li>\n\n\n\n<li>Check sender filter (email may not match the filter).<\/li>\n\n\n\n<li>Check PDF: if it\u2019s an image-only scan, text extraction may fail.<\/li>\n\n\n\n<li>Check the AI node for error messages (e.g., rate limits, invalid key).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Going Live &amp; Maintenance<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you\u2019re happy with the test:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Turn the workflow <strong>Active<\/strong> in n8n.<\/li>\n\n\n\n<li>Monitor a few runs:\n<ul class=\"wp-block-list\">\n<li>Confirm rows are being appended correctly in Sheets.<\/li>\n\n\n\n<li>Confirm files appear where you expect (Drive \/ FTP).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Adjust the <strong>Schedule Trigger<\/strong> to match your needs:\n<ul class=\"wp-block-list\">\n<li>More frequent for heavy billing periods<\/li>\n\n\n\n<li>Less frequent if invoices are rare.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Maintenance Tips<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>AI Costs:<\/strong> keep an eye on your LLM usage to avoid surprises.<\/li>\n\n\n\n<li><strong>Credentials:<\/strong> refresh OAuth tokens (Gmail\/Drive) as needed.<\/li>\n\n\n\n<li><strong>Schema Changes:<\/strong> when you add new columns to Sheets, update the node mapping accordingly.<\/li>\n\n\n\n<li><strong>Error Handling:<\/strong> consider adding an error workflow or extra logging nodes (e.g., send yourself an email if parsing fails).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Customization Ideas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once the base workflow is working, you can expand it:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Multiple Providers:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Duplicate the email section with different sender filters<\/li>\n\n\n\n<li>Use a <code>Merge<\/code> or a single Sheets logging path.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Tagging \/ Labeling Emails Instead of Deleting:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Replace <code>Delete a message<\/code> with a Gmail node that applies a label like <code>Processed-Invoices<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Additional Storage:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Upload to cloud storage like S3 or MinIO via HTTP or dedicated nodes.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>More Detailed Spreadsheet Data:<\/strong>\n<ul class=\"wp-block-list\">\n<li>Save <code>invoice_number<\/code>, <code>tax_breakdown<\/code>, or even individual line items in separate rows.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">You now have a fully documented, production-ready <strong>Automated Invoice Archiving<\/strong> workflow in n8n, with detailed configuration for Gmail, Google Drive, FTP\/SFTP, AI, and Google Sheets. Once active, it should quietly keep your invoices organized and your spending data ready for analysis.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Automatically fetch, store, and extract key information from invoices received via email from your ISP or utility provider (electricity, gas, telecom, water, etc.).The workflow saves the invoices to Google Drive (or optionally to your personal FTP\/SFTP server) and logs all invoice details into Google Sheets via AI-powered extraction. \ud83d\udc68\ud83c\udffb\u200d\ud83d\udcbbGitHub: paoloronco\/n8n-templates \ud83d\udcfd\ufe0fVideo: AI Video Automated Invoice &hellip; <a href=\"https:\/\/paoloronco.it\/en\/n8n-template-automated-invoice-archiving\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;[n8n-template] Automated Invoice Archiving&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22],"tags":[],"class_list":["post-1771","post","type-post","status-publish","format-standard","hentry","category-n8n-guides"],"_links":{"self":[{"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/posts\/1771","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/comments?post=1771"}],"version-history":[{"count":3,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/posts\/1771\/revisions"}],"predecessor-version":[{"id":1793,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/posts\/1771\/revisions\/1793"}],"wp:attachment":[{"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/media?parent=1771"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/categories?post=1771"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/paoloronco.it\/en\/wp-json\/wp\/v2\/tags?post=1771"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}