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 generates LinkedIn post ideas and drafts with OpenAI, routes approvals through Gmail replies, tracks each content cycle in Google Sheets, and publishes the selected draft to LinkedIn as
This workflow automates invoice processing directly from your email inbox.
*Tags: AI Agent, Supply Chain, Logistics, Circular Economy, Route Planning, Transportation, GPS API*