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 →
{
"name": "Invoice Classifiaction Workflow (agentic approach)",
"nodes": [
{
"parameters": {
"select": "channel",
"channelId": {
"__rl": true,
"value": "YOUR_SLACK_CHANNEL_ID",
"mode": "list",
"cachedResultName": "your-review-channel"
},
"text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message_Text', ``, 'string') }}",
"otherOptions": {}
},
"type": "n8n-nodes-base.slackTool",
"typeVersion": 2.4,
"position": [
656,
448
],
"id": "b7b17f5e-a55a-47b8-9c2f-9141646935c5",
"name": "send_review_alert",
"credentials": {
"slackApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}",
"mode": "id"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_MEDICAL_FOLDER_ID",
"mode": "list",
"cachedResultName": "Medical",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_MEDICAL_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
1184,
-256
],
"id": "31ae3322-2d7e-4338-a8ed-697ee9832fcb",
"name": "move_to_medical",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_RESTAURANT_FOLDER_ID",
"mode": "list",
"cachedResultName": "Restaurant",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_RESTAURANT_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
1184,
-80
],
"id": "bf8adab0-af17-413f-99c3-28da6a42c9d9",
"name": "move_to_restaurant",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_HOTEL_FOLDER_ID",
"mode": "list",
"cachedResultName": "Hotel",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_HOTEL_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
1008,
-80
],
"id": "1a69cd7a-318f-49d6-82fa-0d6b65f6df27",
"name": "move_to_hotel",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_TRADES_FOLDER_ID",
"mode": "list",
"cachedResultName": "Trades",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_TRADES_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
832,
-80
],
"id": "0de1ad34-3da9-4a6a-a428-e0d4172a4d0a",
"name": "move_to_trades",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_TELECOM_FOLDER_ID",
"mode": "list",
"cachedResultName": "Telecom",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_TELECOM_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
656,
-80
],
"id": "c4087e24-957b-49d8-b36e-d4124ab3b22d",
"name": "move_to_telecom",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "move",
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('File', ``, 'string') }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_NEEDS_REVIEW_FOLDER_ID",
"mode": "list",
"cachedResultName": "Needs Review",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_NEEDS_REVIEW_FOLDER_ID"
}
},
"type": "n8n-nodes-base.googleDriveTool",
"typeVersion": 3,
"position": [
656,
288
],
"id": "dfcdc516-78af-42d4-8aed-70f932967ca7",
"name": "move_to_review",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"formTitle": "Image Upload",
"formFields": {
"values": [
{
"fieldLabel": "image",
"fieldType": "file"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.formTrigger",
"typeVersion": 2.5,
"position": [
-256,
32
],
"id": "8c8a172e-7296-46ea-98ff-115fb97d4d10",
"name": "Document Upload"
},
{
"parameters": {
"inputDataFieldName": "image",
"name": "={{ $('Document Upload').first().binary.image.fileName }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"folderId": {
"__rl": true,
"value": "YOUR_INCOMING_FOLDER_ID",
"mode": "list",
"cachedResultName": "Incoming",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_INCOMING_FOLDER_ID"
},
"options": {}
},
"type": "n8n-nodes-base.googleDrive",
"typeVersion": 3,
"position": [
48,
32
],
"id": "2fcf71a8-75b0-45f4-a427-32961247009b",
"name": "Upload to Incoming Folder",
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"promptType": "define",
"text": "={{ $json.name }} has been uploaded with file ID: {{ $json.id }}. Classify this document and move it to the correct folder.",
"options": {
"systemMessage": "You are a document classification agent. You will receive a Google Drive file ID and document name.\n\nYour job:\n1. Classify the document into one of: medical_invoice, restaurant_invoice, hotel_invoice, trades_invoice, telecom_invoice.\n2. Call the corresponding move tool (move_to_medical, move_to_restaurant, etc.) and pass the file ID.\n3. If you cannot confidently classify it, call move_to_review with the file ID, then call send_review_alert with a short explanation.\n\nAlways pass the file ID exactly as given. Do not respond with text \u2014 only tool calls.",
"passthroughBinaryImages": true
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3.1,
"position": [
288,
-112
],
"id": "8712562c-89fc-434c-93c4-1667ed658825",
"name": "AI Agent: Classify & Route"
},
{
"parameters": {
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"typeVersion": 1,
"position": [
352,
256
],
"id": "3338d589-f4ad-400e-b941-f00b43761914",
"name": "Gemini Chat Model",
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "## \ud83d\udce5 Document Upload\nHosts a web form with a single file upload field. Accepts PDF, PNG, or JPEG. The uploaded file is passed as binary to the next step for storage in Google Drive.",
"height": 384,
"width": 288,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-352,
-160
],
"typeVersion": 1,
"id": "bc5d99c8-0c6e-47f1-b45a-a7f3937939bc",
"name": "Sticky Note"
},
{
"parameters": {
"content": "## \ud83d\udcc2 Upload to Incoming\nUploads the original file to a temporary **Incoming** folder in Google Drive and returns a file ID. This ID is then passed to the agent so it can reference and move the file without ever handling the binary itself.",
"height": 384,
"width": 288,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-160
],
"typeVersion": 1,
"id": "006cbc7c-3eb2-4e07-8003-cc27b71da29e",
"name": "Sticky Note1"
},
{
"parameters": {
"content": "## \ud83e\udd16 AI Classification Agent\nReceives the file ID and filename, then uses **Gemini** to classify the document into one of the supported categories. Based on its classification, the agent calls the matching **Move** tool to route the file. If it can't confidently classify, it calls **Move to Needs Review** and sends a Slack alert.",
"height": 448,
"width": 288,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
-368
],
"typeVersion": 1,
"id": "395dfab1-0d05-4ffd-b5f1-b0fe7c00d413",
"name": "Sticky Note2"
},
{
"parameters": {
"content": "## \ud83e\udde0 Chat Model\nPowers the agent's reasoning. Swap in any tool-calling capable model (Gemini, GPT-4o, Claude) \u2013 just make sure it supports function calling.",
"height": 304,
"width": 288,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
256,
96
],
"typeVersion": 1,
"id": "4a2f8639-e2e2-4bbf-b448-03ed345a51b1",
"name": "Sticky Note3"
},
{
"parameters": {
"content": "## \ud83d\udcc1 Google Drive Move Tools\nEach tool moves the uploaded file from the **Incoming** folder into its matching category folder:\n\n- **Medical**\n- **Restaurant**\n- **Hotel**\n- **Trades**\n- **Telecom**\n\nThe agent picks exactly one based on its classification and passes the file ID.",
"height": 640,
"width": 784,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
-560
],
"typeVersion": 1,
"id": "2b44e6da-3a5f-4c55-8ff3-ac2620cd4ef1",
"name": "Sticky Note4"
},
{
"parameters": {
"content": "## \u26a0\ufe0f Needs Review\nWhen the agent can't confidently classify a document, it's moved to the **Needs Review** folder and a **Slack notification** is sent to the review channel with a short explanation of why it was flagged.",
"height": 496,
"width": 288,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
96
],
"typeVersion": 1,
"id": "f13e2a01-0367-415c-8712-234479cf531c",
"name": "Sticky Note5"
},
{
"parameters": {
"content": "# \ud83d\udcc4 Agentic Document Classification Workflow\n\n## What This Workflow Does\nUpload a document (PDF, PNG, JPEG) via a web form and let an **AI agent** classify it and route it to the correct Google Drive folder on its own. No rule-based routing, no Switch nodes \u2013 the agent decides the category and calls the matching move tool. Documents it can't confidently classify are moved to a **Needs Review** folder and flagged via **Slack**.\n\n## How It Works\n1. User uploads a file through the hosted web form\n2. The file is uploaded to a temporary **Incoming** folder in Google Drive\n3. The file ID and name are passed to the **AI Agent**\n4. The agent classifies the document and calls the matching **Move** tool (e.g. `move_to_medical`)\n5. If it can't confidently classify, it calls **Move to Needs Review** + sends a **Slack** alert\n\n**Supported categories:**\n`medical_invoice` \u00b7 `restaurant_invoice` \u00b7 `hotel_invoice` \u00b7 `trades_invoice` \u00b7 `telecom_invoice`\n\n## Setup Guide\n### 1. Create Your Google Drive Folders\nCreate one folder per category in Google Drive:\n- **Incoming** (temporary landing folder)\n- **Medical** \u00b7 **Restaurant** \u00b7 **Hotel** \u00b7 **Trades** \u00b7 **Telecom**\n- **Needs Review**\n\n### 2. Connect Google Drive\n1. In n8n, go to **Settings \u2192 Credentials** and create a **Google Drive OAuth2** credential\n2. This requires a **Client ID** and **Client Secret** from Google Cloud Console (APIs & Services \u2192 Credentials \u2192 OAuth 2.0 Client ID)\n3. Make sure the **Google Drive API** is enabled in your Google Cloud project\n4. Open the **Upload to Incoming Folder** node and select your Incoming folder\n5. Open each of the 6 Move tool nodes and select the correct target folder\n\n### 3. Connect Your Chat Model\n1. Add a credential for your chosen model (Gemini, OpenAI, Anthropic) in **Settings \u2192 Credentials**\n2. Open the **Chat Model** node and assign the credential\n3. Any tool-calling capable model will work \u2013 Gemini 1.5 Pro or GPT-4o recommended\n\n### 4. Connect Slack\n1. Create a **Slack API** credential in n8n (needs a Bot Token with `chat:write` scope)\n2. Create a channel for review notifications (e.g. `#document-review`)\n3. Invite the bot to that channel\n4. Open the **Slack: Notify Review Channel** node and select the correct channel\n\n### 5. Activate & Test\n1. Click **Active** in the top-right corner of n8n\n2. Open the form URL and upload a test document\n3. Check the execution log to confirm the classification and the move action\n4. Verify the file lands in the correct Google Drive folder\n5. Test with an unrecognizable document to confirm the Slack alert fires\n\n## Notes\n- The agent's classification quality depends on the filename and the chat model's reasoning. Descriptive filenames improve accuracy significantly.\n- This workflow is an **agentic demo** \u2013 it replaces deterministic routing with LLM decision-making. For production-grade document classification with structured extraction, per-field prompting, and explicit confidence scoring, check out the easybits Extractor community node.",
"height": 1424,
"width": 784
},
"type": "n8n-nodes-base.stickyNote",
"position": [
-1152,
-672
],
"typeVersion": 1,
"id": "cde013b7-79d2-4492-ba3f-a95ea589a786",
"name": "Sticky Note6"
}
],
"connections": {
"send_review_alert": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_medical": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_restaurant": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_hotel": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_trades": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_telecom": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"move_to_review": {
"ai_tool": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_tool",
"index": 0
}
]
]
},
"Document Upload": {
"main": [
[
{
"node": "Upload to Incoming Folder",
"type": "main",
"index": 0
}
]
]
},
"Upload to Incoming Folder": {
"main": [
[
{
"node": "AI Agent: Classify & Route",
"type": "main",
"index": 0
}
]
]
},
"Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent: Classify & Route",
"type": "ai_languageModel",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"availableInMCP": false,
"timeSavedMode": "fixed",
"callerPolicy": "workflowsFromSameOwner"
},
"versionId": "",
"meta": {
"templateCredsSetupCompleted": false
},
"id": "",
"tags": []
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleDriveOAuth2ApigooglePalmApislackApi
About this workflow
Invoice Classifiaction Workflow (agentic approach). Uses slackTool, googleDriveTool, formTrigger, googleDrive. Event-driven trigger; 18 nodes.
Source: https://github.com/felix-sattler-easybits/n8n-workflows/blob/2e9153b83d94fb1200a130f2c3b10a21298ed49b/agentic-document-classification-workflow/agentic_document_classification_workflow.json — original creator credit. Request a take-down →