Workflow: Attachments Gmail to drive and google sheets
Integrations: extractFromFile, gmail, gmailTrigger, googleDrive, googleSheets, httpRequest, if, noOp, set, stickyNote

{"id": "XnGZZfT5u0Cw1X3p", "meta": {"instanceId": "workflow-43deb4b3", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:44.717821", "updatedAt": "2025-09-29T07:07:44.717853", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "Attachments Gmail to drive and google sheets", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "0404ef0a-9750-495a-8798-98d4b059a083", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [-580, -420], "parameters": {"height": 440, "content": "## Setup\n1. Setup your **Gmail** and **Google Drive** credentials\n2. Setup your **Google Sheets** credentials\n3. Setup your **Openai** api key"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "8751a7f1-aae4-4746-aae7-3d8563845b8c", "name": "Gmail Trigger1", "type": "n8n-nodes-base.gmailTrigger", "position": [-640, 120], "parameters": {"simple": false, "filters": {"readStatus": "unread"}, "options": {"downloadAttachments": true}, "pollTimes": {"item": [{"mode": "everyMinute"}]}}, "credentials": {"gmailOAuth2": {"id": "v8YJP3VfeGtRk5la", "name": "Gmail account"}}, "typeVersion": 1.1, "notes": "This gmailTrigger node performs automated tasks as part of the workflow."}, {"id": "40f62192-5acb-4915-aa07-e5a0dfeb7581", "name": "Setup1", "type": "n8n-nodes-base.set", "position": [-300, 120], "parameters": {"options": {}, "assignments": {"assignments": [{"id": "4cca07a2-6a70-4011-a025-65246e652fb9", "name": "url_to_drive_folder", "type": "string", "value": "1fCWCdqrFP3WrjjLc-gJtxMaiaF5lh8Ko"}]}, "includeOtherFields": true}, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "d928e797-8851-4ab4-9199-cd555a40eae9", "name": "Upload PDF to Drive1", "type": "n8n-nodes-base.httpRequest", "maxTries": 5, "position": [220, 0], "parameters": {"url": "{{ $env.API_BASE_URL }}", "method": "POST", "options": {}, "sendBody": true, "sendQuery": true, "contentType": "binaryData", "authentication": "{{ $credentials.predefinedCredentialType }}", "queryParameters": {"parameters": [{"name": "uploadType", "value": "media"}]}, "inputDataFieldName": "={{ $binary.attachment_0.mimeType === \"application/pdf\"\n     ? \"attachment_0\"\n     : \"attachment_1\" }}", "nodeCredentialType": "YOUR_CREDENTIAL_HERE"}, "credentials": {"googleDriveOAuth2Api": {"id": "p5I6S4YkJps1zvwz", "name": "Google Drive account 2"}}, "retryOnFail": true, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow."}, {"id": "22df6933-a0c7-4cce-8114-5332038a14c3", "name": "Rename file1", "type": "n8n-nodes-base.googleDrive", "position": [400, 0], "parameters": {"fileId": {"__rl": true, "mode": "id", "value": "={{ $json.id }}"}, "options": {}, "operation": "update", "newUpdatedFileName": "={{ $('Setup1').item.json.subject }}_invoice_{{ $now.format('yyyy-MM-dd') }}.pdf"}, "credentials": {"googleDriveOAuth2Api": {"id": "p5I6S4YkJps1zvwz", "name": "Google Drive account 2"}}, "typeVersion": 3, "notes": "This googleDrive node performs automated tasks as part of the workflow."}, {"id": "ce6a6a4c-17ba-4cf7-b07a-97b9d8d80844", "name": "Move to the correct folder1", "type": "n8n-nodes-base.googleDrive", "position": [580, 0], "parameters": {"fileId": {"__rl": true, "mode": "id", "value": "={{ $json.id }}"}, "driveId": {"__rl": true, "mode": "list", "value": "My Drive", "cachedResultUrl": "{{ $env.WEBHOOK_URL }}", "cachedResultName": "My Drive"}, "folderId": {"__rl": true, "mode": "list", "value": "1fCWCdqrFP3WrjjLc-gJtxMaiaF5lh8Ko", "cachedResultUrl": "", "cachedResultName": "2025"}, "operation": "move"}, "credentials": {"googleDriveOAuth2Api": {"id": "p5I6S4YkJps1zvwz", "name": "Google Drive account 2"}}, "typeVersion": 3, "notes": "This googleDrive node performs automated tasks as part of the workflow."}, {"id": "e64aac5c-a314-46b6-b7db-fc0d6f450e1f", "name": "Gmail", "type": "n8n-nodes-base.gmail", "position": [1240, 0], "webhookId": "556cbee3-8de0-4645-9e91-e7c0c252f2ab", "parameters": {"messageId": "={{ $('Gmail Trigger1').item.json.id }}", "operation": "markAsRead"}, "credentials": {"gmailOAuth2": {"id": "v8YJP3VfeGtRk5la", "name": "Gmail account"}}, "typeVersion": 2.1, "notes": "This gmail node performs automated tasks as part of the workflow."}, {"id": "ea74cfc1-0305-418d-9f5f-bffcfb3bb2c7", "name": "Extract from File2", "type": "n8n-nodes-base.extractFromFile", "position": [1200, -180], "parameters": {"options": {}, "operation": "pdf"}, "typeVersion": 1, "notes": "This extractFromFile node performs automated tasks as part of the workflow."}, {"id": "0398d982-78fd-4830-b5cf-271195af80fd", "name": "Google Drive", "type": "n8n-nodes-base.googleDrive", "position": [800, 0], "parameters": {"fileId": {"__rl": true, "mode": "id", "value": "={{ $json.id }}"}, "options": {}, "operation": "download"}, "credentials": {"googleDriveOAuth2Api": {"id": "p5I6S4YkJps1zvwz", "name": "Google Drive account 2"}}, "typeVersion": 3, "notes": "This googleDrive node performs automated tasks as part of the workflow."}, {"id": "3b4a96d4-a6ee-486a-a795-fe410ccc38b2", "name": "OpenAI Model", "type": "n8n-nodes-base.noOp", "position": [1740, 20], "parameters": {"model": {"__rl": true, "mode": "list", "value": "gpt-4o", "cachedResultName": "gpt-4o"}, "options": {"temperature": 0}}, "credentials": {"openAiApi": {"id": "XJdxgMSXFgwReSsh", "name": "n8n key"}}, "typeVersion": 1, "notes": "This lmOpenAi node performs automated tasks as part of the workflow."}, {"id": "a7dd0d95-5e79-4bd2-a8a6-2178264d19fc", "name": "Structured Output Parser", "type": "n8n-nodes-base.noOp", "position": [1940, 40], "parameters": {"jsonSchema": "{\n  \"Invoice date\": { \"type\": \"date\" },\n  \"Invoice description\": { \"type\": \"string\" },\n  \"Total price\": { \"type\": \"number\" },\n  \"Fichero\": { \"type\": \"string\" }\n}"}, "typeVersion": 1.1, "notes": "This outputParserStructured node performs automated tasks as part of the workflow."}, {"id": "68d98f4c-e679-48e3-a1a1-529cda4e31a4", "name": "Append to Reconciliation Sheet", "type": "n8n-nodes-base.googleSheets", "position": [2280, -140], "parameters": {"columns": {"value": {}, "schema": [{"id": "Invoice date", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Invoice date", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Invoice Description", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Invoice Description", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Total price", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Total price", "defaultMatch": false, "canBeUsedToMatch": true}, {"id": "Fichero", "type": "string", "display": true, "removed": false, "required": false, "displayName": "Fichero", "defaultMatch": false, "canBeUsedToMatch": true}], "mappingMode": "autoMapInputData", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": false}, "options": {}, "operation": "append", "sheetName": {"__rl": true, "mode": "id", "value": "gid=0"}, "documentId": {"__rl": true, "mode": "list", "value": "1gIUnjSWUhsoTOVVd4ZoVjARCGQfGE8s7FWcju3lNajM", "cachedResultUrl": "", "cachedResultName": "facturas"}}, "credentials": {"googleSheetsOAuth2Api": {"id": "3IOU2VjBnR4hGohx", "name": "Google Sheets account"}}, "typeVersion": 4.3, "notes": "This googleSheets node performs automated tasks as part of the workflow."}, {"id": "80e1c8f4-b593-4c5f-b9e2-f3b7996ee6d4", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [1680, -400], "parameters": {"color": 7, "width": 805.0578351924228, "height": 656.5014186128178, "content": "## 3. Use LLMs to Extract Values from Data\n[Read more about Basic LLM Chain]({{ $env.WEBHOOK_URL }}\n\nLarge language models are perfect for data extraction tasks as they can work across a range of document layouts without human intervention. The extracted data can then be sent to a variety of datastores such as spreadsheets, accounting systems and/or CRMs.\n\n**Tip:** The \"Structured Output Parser\" ensures the AI output can be\ninserted to our spreadsheet without additional clean up and/or formatting. "}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "3754e10e-a233-4ce0-bc79-bb5c01db9695", "name": "Map Output", "type": "n8n-nodes-base.set", "position": [2080, -140], "parameters": {"mode": "raw", "options": {}, "jsonOutput": "={{ $json.output }}"}, "typeVersion": 3.3, "notes": "This set node performs automated tasks as part of the workflow."}, {"id": "a42ff16f-d0df-4b6d-9a36-849f85d1facc", "name": "Apply Data Extraction Rules", "type": "n8n-nodes-base.noOp", "position": [1740, -140], "parameters": {"text": "=Given the following invoice in the <invoice> xml tags, extract the following information as listed below.\nIf you cannot the information for a specific item, then leave blank and skip to the next. \n\n* Invoice date\n* Invoice Description: {{ $('Rename file1').item.json.name }}\n* Total price\n* Fichero: =HYPERLINK(\"{{ $env.WEBHOOK_URL }}{{ $('Move to the correct folder1').item.json.id }}/view\", \"Ver Documento\")\n\n\n<invoice>{{ $json.text }}</invoice>", "promptType": "define", "hasOutputParser": true}, "typeVersion": 1.4, "notes": "This chainLlm node performs automated tasks as part of the workflow."}, {"id": "f6de5d5a-d2dc-4590-8f46-3f250b8fca9f", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [1860, 0], "parameters": {"width": 192.26896179623753, "height": 213.73043662572252, "content": "\n\n\n\n\n\n\n\n\n\n\n\n**Need more attributes?**\nChange it here!"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "255fe8c1-5bd7-41cc-b1f9-c8956b5ad101", "name": "Only invoice mails with attachments", "type": "n8n-nodes-base.if", "position": [0, 120], "parameters": {"options": {}, "conditions": {"options": {"version": 1, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "or", "conditions": [{"id": "229200d1-ec13-4970-ae0e-2c8e17da0bdf", "operator": {"type": "string", "operation": "contains"}, "leftValue": "={{ $('Gmail Trigger1').item.json.headers['content-type'] }}", "rightValue": "multipart/mixed"}, {"id": "new-condition", "operator": {"type": "boolean", "operation": "isNotEmpty"}, "leftValue": "={{ $json.attachments }}"}]}}, "typeVersion": 2.1, "notes": "This if node performs automated tasks as part of the workflow."}], "active": true, "pinData": {}, "settings": {"executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "eb152808-e993-4e18-9dd8-10f21df57bf1", "connections": {"d928e797-8851-4ab4-9199-cd555a40eae9": {"main": [[{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-5853f890", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-9e152d18", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-eb6a46fd", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-0f3219b8", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-100dbead", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-015dacf6", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-c733ff38", "type": "main", "index": 0}], [{"node": "error-handler-d928e797-8851-4ab4-9199-cd555a40eae9-f8f68a08", "type": "main", "index": 0}]]}, "22df6933-a0c7-4cce-8114-5332038a14c3": {"main": [[{"node": "error-handler-22df6933-a0c7-4cce-8114-5332038a14c3-07668709", "type": "main", "index": 0}]]}, "ce6a6a4c-17ba-4cf7-b07a-97b9d8d80844": {"main": [[{"node": "error-handler-ce6a6a4c-17ba-4cf7-b07a-97b9d8d80844-e6512321", "type": "main", "index": 0}]]}, "ea74cfc1-0305-418d-9f5f-bffcfb3bb2c7": {"main": [[{"node": "error-handler-ea74cfc1-0305-418d-9f5f-bffcfb3bb2c7-a34c0fd0", "type": "main", "index": 0}]]}, "0398d982-78fd-4830-b5cf-271195af80fd": {"main": [[{"node": "error-handler-0398d982-78fd-4830-b5cf-271195af80fd-bf3c41b4", "type": "main", "index": 0}]]}, "3b4a96d4-a6ee-486a-a795-fe410ccc38b2": {"main": [[{"node": "error-handler-3b4a96d4-a6ee-486a-a795-fe410ccc38b2-2e556eea", "type": "main", "index": 0}]]}, "68d98f4c-e679-48e3-a1a1-529cda4e31a4": {"main": [[{"node": "error-handler-68d98f4c-e679-48e3-a1a1-529cda4e31a4-e5879d17", "type": "main", "index": 0}]]}}, "description": "Automated workflow: Attachments Gmail to drive and google sheets. This workflow integrates 13 different services: stickyNote, httpRequest, gmailTrigger, chainLlm, googleDrive. It contains 25 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Attachments Gmail to drive and google sheets. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}