This workflow corresponds to n8n.io template #10874 — we link there as the canonical source.
This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "UGSS5zt4TXxF32mr",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "GPT-4.1-mini Powered Invoice Processing from Gmail to Google Sheets with Slack Approval",
"tags": [],
"nodes": [
{
"id": "6a927310-5fc7-43bd-87af-424bd7c55cb0",
"name": "1. New Invoice Email Received",
"type": "n8n-nodes-base.gmailTrigger",
"position": [
-848,
-528
],
"parameters": {
"simple": false,
"filters": {
"q": "invoice",
"includeDrafts": false,
"includeSpamTrash": false
},
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
}
},
"typeVersion": 1.3
},
{
"id": "f8ccf24e-2bd0-45d7-8913-390017b8bb86",
"name": "2. Get Email Attachments",
"type": "n8n-nodes-base.gmail",
"position": [
-624,
-528
],
"parameters": {
"simple": false,
"options": {
"downloadAttachments": true
},
"messageId": "={{$json.id}}",
"operation": "get"
},
"typeVersion": 2.1
},
{
"id": "9735648c-b000-4609-ba2a-f3abf3f9ecf4",
"name": "3. Extract Text from PDF",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-400,
-528
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "attachment_0"
},
"typeVersion": 1
},
{
"id": "35f7be1c-4edf-439a-8fcb-0bca17c9572f",
"name": "4. Prepare Text for AI",
"type": "n8n-nodes-base.set",
"position": [
-176,
-528
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "80247922-4a11-451d-9aa6-605b7ca9042b",
"name": "clean_text",
"type": "string",
"value": "={{$json.text || $json.rawText || ''}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "d2e5f759-f7f1-4f1e-bdce-9953e010067a",
"name": "5. Extract Invoice Data with AI",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
48,
-528
],
"parameters": {
"text": "=You are a professional accounting data processor.\nExtract the specified items from the text below and output them in JSON format.\n\n# Instructions\n- Strictly adhere to the specified JSON object format.\n- You must only output the JSON object.\n- Do not include any explanatory text or code blocks like ```json before or after the JSON.\n- For any items not found in the text, use an empty string \"\" or 0.\n\n# Output Format\n{\n \"invoice_number\": \"\",\n \"issue_date\": \"\",\n \"bill_to_name\": \"\",\n \"total_amount\": 0,\n \"due_date\": \"\"\n}\n\n# Target Text\n{{ $json.clean_text }}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "1997c1a1-6d0b-4978-b016-e165bff3b9fe",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
64,
-304
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"typeVersion": 1.2
},
{
"id": "a0873ce5-7bc6-432c-9782-7f0f38cbbe36",
"name": "Webhook (Approve)",
"type": "n8n-nodes-base.webhook",
"position": [
-864,
-16
],
"parameters": {
"path": "approve",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "3c059939-48aa-4f1e-9885-ba4090a53c07",
"name": "Webhook (Reject)",
"type": "n8n-nodes-base.webhook",
"position": [
-864,
208
],
"parameters": {
"path": "reject",
"options": {}
},
"typeVersion": 2.1
},
{
"id": "084e5e25-96e7-481a-8bfc-41ebb99d1ca1",
"name": "10a. Send Approval Confirmation",
"type": "n8n-nodes-base.slack",
"position": [
-192,
-16
],
"parameters": {
"text": "=This invoice has been approved. ID: {{$json.invoice_id}}",
"select": "channel",
"channelId": "YOUR_SLACK_CHANNEL_ID",
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.3
},
{
"id": "3168c089-d89a-4649-b0d6-498417207953",
"name": "10b. Send Rejection Confirmation",
"type": "n8n-nodes-base.slack",
"position": [
-192,
208
],
"parameters": {
"text": "=This invoice has been rejected. ID: {{$json.invoice_id}}",
"select": "channel",
"channelId": "YOUR_SLACK_CHANNEL_ID",
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.3
},
{
"id": "61afe930-9395-4ca5-aebd-c610edc207eb",
"name": "6. Log Invoice to Google Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
400,
-528
],
"parameters": {
"columns": {
"value": {
"date": "={{$('5. Extract Invoice Data with AI').first().json.output.issue_date}}",
"amount": "={{$('5. Extract Invoice Data with AI').first().json.output.total_amount}}",
"status": "pending",
"company": "={{$('5. Extract Invoice Data with AI').first().json.output.bill_to_name}}",
"rawText": "={{$('4. Prepare Text for AI').first().json.clean_text}}",
"due_date": "={{$('5. Extract Invoice Data with AI').first().json.output.due_date}}",
"invoice_number": "={{$('5. Extract Invoice Data with AI').first().json.output.invoice_number}}"
},
"mappingMode": "defineBelow"
},
"options": {},
"operation": "append",
"sheetName": "YOUR_SHEET_NAME",
"documentId": "YOUR_GOOGLE_SHEET_ID"
},
"typeVersion": 4.7
},
{
"id": "67931763-dd8b-42e3-a2a5-c8bdf82e7e6f",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
192,
-304
],
"parameters": {
"jsonSchemaExample": "{\n \"invoice_number\": \"20241007-001\",\n \"issue_date\": \"2024-10-07\",\n \"bill_to_name\": \"\u682a\u5f0f\u4f1a\u793e DRIX\",\n \"total_amount\": 8800,\n \"due_date\": \"2024-10-31\"\n}\n"
},
"typeVersion": 1.3
},
{
"id": "1f145d04-12e7-4345-b67e-8621bf192800",
"name": "9a. Update Status to Approved",
"type": "n8n-nodes-base.googleSheets",
"position": [
-416,
-16
],
"parameters": {
"columns": {
"value": {
"status": "approved",
"invoice_number": "={{$json.invoice_id}}"
},
"mappingMode": "defineBelow",
"matchingColumns": [
"invoice_number"
]
},
"options": {},
"operation": "update",
"sheetName": "YOUR_SHEET_NAME",
"documentId": "YOUR_GOOGLE_SHEET_ID"
},
"typeVersion": 4.7
},
{
"id": "e9128567-5ea7-49b5-9ace-280e49026787",
"name": "9b. Update Status to Rejected",
"type": "n8n-nodes-base.googleSheets",
"position": [
-416,
208
],
"parameters": {
"columns": {
"value": {
"status": "rejected",
"invoice_number": "={{$json.invoice_id}}"
},
"mappingMode": "defineBelow",
"matchingColumns": [
"invoice_number"
]
},
"options": {},
"operation": "update",
"sheetName": "YOUR_SHEET_NAME",
"documentId": "YOUR_GOOGLE_SHEET_ID"
},
"typeVersion": 4.7
},
{
"id": "bfc86cd9-f0d2-4c01-8cca-24388245c93e",
"name": "7. Send Approval Request to Slack",
"type": "n8n-nodes-base.slack",
"position": [
624,
-528
],
"parameters": {
"text": "=A new invoice requires your approval.\n\n*Company:* {{$('5. Extract Invoice Data with AI').first().json.output.bill_to_name}}\n*Amount:* {{$('5. Extract Invoice Data with AI').first().json.output.total_amount}}\n*Due Date:* {{$('5. Extract Invoice Data with AI').first().json.output.due_date}}\n\nPlease click the links below to approve or reject.\n\n*Approve:*\nhttps://YOUR_WEBHOOK_BASE_URL/webhook/approve?id={{$('5. Extract Invoice Data with AI').first().json.output.invoice_number}}\n\n*Reject:*\nhttps://YOUR_WEBHOOK_BASE_URL/webhook/reject?id={{$('5. Extract Invoice Data with AI').first().json.output.invoice_number}}",
"select": "channel",
"channelId": "YOUR_SLACK_CHANNEL_ID",
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.3
},
{
"id": "20ac3190-2d82-43e9-b47b-69133ceb3af6",
"name": "8a. Extract Invoice ID",
"type": "n8n-nodes-base.set",
"position": [
-640,
-16
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "ded2aa43-262f-4f88-a1f2-0cb88777b8b0",
"name": "invoice_id",
"type": "string",
"value": "={{$json.query.id}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2d72c14f-cd66-4d2e-84a7-23c522787d57",
"name": "8b. Extract Invoice ID",
"type": "n8n-nodes-base.set",
"position": [
-640,
208
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d43309df-66c0-49fc-b3c2-8f095534e45f",
"name": "invoice_id",
"type": "string",
"value": "={{$json.query.id}}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "848586fb-b5c1-4595-abba-31de9a0f0497",
"name": "GPT-4.1-mini Powered Invoice Processing",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1696,
-1632
],
"parameters": {
"width": 944,
"height": 816,
"content": "This workflow automates your invoice processing pipeline. It triggers on a new Gmail invoice, uses AI to extract data, logs it to a Google Sheet, and sends a Slack message with approval/rejection links.\n\n## Who is it for?\nThis template is perfect for small business owners, finance teams, and freelancers looking to eliminate manual data entry and streamline their accounts payable process.\n\n## How it works\n1. **Trigger:** Starts when an email with a specific keyword (e.g., \"invoice\") arrives in Gmail.\n2. **Extraction & AI:** It downloads the PDF, extracts the text, and uses a GPT-4.1-mini model to pull key details like invoice number, company, amount, and dates.\n3. **Logging:** Appends the structured data to a Google Sheet with a `pending` status.\n4. **Approval:** Sends a Slack message with the invoice data and unique approve/reject links.\n5. **Update:** When a link is clicked, a Webhook updates the corresponding row in Google Sheets to `approved` or `rejected` and sends a confirmation to Slack.\n\n## Expected Google Sheet Structure\nYour Google Sheet should have the following columns to work with this template:\n- `invoice_number`\n- `company`\n- `amount`\n- `date`\n- `due_date`\n- `status`\n- `rawText`\n\n## How to set up\n1. **Credentials:** Add your credentials for Gmail, OpenAI, Google Sheets, and Slack.\n2. **Gmail Trigger:** Customize the search query (`q`) in the first node.\n3. **Google/Slack:** Enter your Sheet ID/Name and Slack Channel ID in the relevant nodes.\n4. **\u2757\ufe0f Activate Workflow & URLs:** This is a critical step. First, **activate the workflow** using the toggle in the top-right corner. Then, copy the **Production URLs** from the `Webhook (Approve)` and `Webhook (Reject)` nodes and paste them into the `7. Send Approval Request to Slack` node, replacing the `https://YOUR_WEBHOOK_BASE_URL` placeholder."
},
"typeVersion": 1
},
{
"id": "32b5eb12-99c5-4a84-a0fb-5864d8e89e44",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1152,
-784
],
"parameters": {
"color": 7,
"width": 480,
"height": 240,
"content": "## Trigger\nThis node starts the workflow when an email matching the filter arrives.\n\n**Setup:** \n1. Add Gmail credentials.\n2. Change the search query `q` to your invoice keyword (e.g., \"invoice\")."
},
"typeVersion": 1
},
{
"id": "b7352552-cca3-4f9c-99ef-d9441874d56f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-592,
-768
],
"parameters": {
"color": 7,
"width": 400,
"height": 192,
"content": "## Data Preparation\nThese nodes download the PDF from the email and extract its raw text content, preparing it for the AI."
},
"typeVersion": 1
},
{
"id": "ca5ed7e7-6d1c-4990-aa8f-0e30743ae11e",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-16,
-784
],
"parameters": {
"color": 7,
"width": 384,
"height": 224,
"content": "## AI Extraction & Logging\nAn AI model extracts structured data from the text, which is then appended to your Google Sheet.\n\n**Setup:**\n1. Add OpenAI & Google Sheets credentials.\n2. Enter your Sheet ID & Name."
},
"typeVersion": 1
},
{
"id": "d1fd4b75-a743-4b6f-a361-468fce76e6c6",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
544,
-800
],
"parameters": {
"color": 7,
"width": 368,
"height": 240,
"content": "## Slack Approval Request\nSends a message to Slack containing the invoice details and unique approval/rejection links.\n\n**Setup:**\n1. Add Slack credentials.\n2. Enter your Slack Channel ID.\n3. **IMPORTANT:** Replace the placeholder URLs with the Production URLs from the Webhook nodes."
},
"typeVersion": 1
},
{
"id": "24adce38-a0b9-4b2f-8c38-d90e1cbca515",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-864,
-176
],
"parameters": {
"color": 6,
"width": 640,
"height": 112,
"content": "## Approval/Rejection Handling\nThese nodes listen for clicks on the Slack links. They update the Google Sheet status to \"approved\" or \"rejected\" and send a final confirmation message back to Slack."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "f44fad42-eccd-4aa1-a29b-3c654b13c6a5",
"connections": {
"Webhook (Reject)": {
"main": [
[
{
"node": "8b. Extract Invoice ID",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "5. Extract Invoice Data with AI",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Webhook (Approve)": {
"main": [
[
{
"node": "8a. Extract Invoice ID",
"type": "main",
"index": 0
}
]
]
},
"4. Prepare Text for AI": {
"main": [
[
{
"node": "5. Extract Invoice Data with AI",
"type": "main",
"index": 0
}
]
]
},
"8a. Extract Invoice ID": {
"main": [
[
{
"node": "9a. Update Status to Approved",
"type": "main",
"index": 0
}
]
]
},
"8b. Extract Invoice ID": {
"main": [
[
{
"node": "9b. Update Status to Rejected",
"type": "main",
"index": 0
}
]
]
},
"2. Get Email Attachments": {
"main": [
[
{
"node": "3. Extract Text from PDF",
"type": "main",
"index": 0
}
]
]
},
"3. Extract Text from PDF": {
"main": [
[
{
"node": "4. Prepare Text for AI",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "5. Extract Invoice Data with AI",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"1. New Invoice Email Received": {
"main": [
[
{
"node": "2. Get Email Attachments",
"type": "main",
"index": 0
}
]
]
},
"9a. Update Status to Approved": {
"main": [
[
{
"node": "10a. Send Approval Confirmation",
"type": "main",
"index": 0
}
]
]
},
"9b. Update Status to Rejected": {
"main": [
[
{
"node": "10b. Send Rejection Confirmation",
"type": "main",
"index": 0
}
]
]
},
"6. Log Invoice to Google Sheet": {
"main": [
[
{
"node": "7. Send Approval Request to Slack",
"type": "main",
"index": 0
}
]
]
},
"5. Extract Invoice Data with AI": {
"main": [
[
{
"node": "6. Log Invoice to Google Sheet",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
AI-Powered Invoice Processing from Gmail to Google Sheets with Slack Approval This workflow completely automates your invoice processing pipeline. It triggers when a new invoice email arrives in Gmail, uses AI to extract key data from the PDF attachment, logs it in a Google…
Source: https://n8n.io/workflows/10874/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Enterprise-grade resume screening automation built for production environments. This workflow combines intelligent AI analysis with comprehensive error handling to ensure reliable processing of candid
Streamline customer support with a real-time, AI-powered answer engine that detects incoming support emails, classifies intent, identifies the customer’s GEO region, and generates a tailored reply rea
This workflow automates invoice processing directly from your email inbox.
*Tags: AI Agent, Supply Chain, Logistics, Circular Economy, Route Planning, Transportation, GPS API*
This template is for founders, finance teams, and solo operators who receive lots of invoices by email and want them captured automatically in a single, searchable source of truth. If you’re tired of