{
  "id": "",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Smart Mailroom Workflow powered by easybits",
  "tags": [],
  "nodes": [
    {
      "id": "ceccb0f1-f81f-4e04-9865-b0b8e1d6d912",
      "name": "Extractor: Purchase Orders",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        1264,
        224
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "236c284d-88ac-42d7-bb83-880796b11c8a",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -144,
        0
      ],
      "parameters": {
        "simple": false,
        "filters": {},
        "options": {
          "downloadAttachments": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "9456f8f9-d8e9-4f44-9f18-7a9c760c997f",
      "name": "easybits: Classify Document",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        208,
        0
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "85bbb969-0d38-4e17-a423-49e9740fbadb",
      "name": "Route by Document Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        560,
        -16
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "02cfff2d-74a3-45c7-b655-d5c1efa10047",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.document_class }}",
                    "rightValue": "Invoice"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ade45c05-8ed4-4cdf-98dd-b8d12734e191",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.document_class }}",
                    "rightValue": "Contracts"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 3,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fef9adea-263b-424c-9be7-4d453dbafae3",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.document_class }}",
                    "rightValue": "Purchase Orders"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "7d28879f-8133-4d71-9570-df13ce423cd3",
      "name": "Merge: Invoice Binary",
      "type": "n8n-nodes-base.merge",
      "position": [
        912,
        -240
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "85b5d486-60c1-4a61-84d2-915f30fe0423",
      "name": "Merge: Contract Binary",
      "type": "n8n-nodes-base.merge",
      "position": [
        912,
        0
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "969b35c6-c5ea-4de0-9c69-905ba1eebb36",
      "name": "Merge: Purchase Order Binary",
      "type": "n8n-nodes-base.merge",
      "position": [
        912,
        224
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "59e7334f-2d44-4bdd-9b88-661ecf480de3",
      "name": "easybits: Extract Invoice",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        1264,
        -240
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "1e853791-89d8-4dc3-af3b-77f4691e7457",
      "name": "easybits: Extract Contract",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        1264,
        0
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "815a5109-5696-4175-9b39-136ec2f694a2",
      "name": "Merge: Invoice Data + File",
      "type": "n8n-nodes-base.merge",
      "position": [
        1616,
        -240
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "bcd1f111-90a6-466c-b575-e1c7acc292a6",
      "name": "Merge: Contract Data + File",
      "type": "n8n-nodes-base.merge",
      "position": [
        1616,
        0
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "3bef4105-24ea-4fc3-95c8-9537aa769cc4",
      "name": "Merge: Purchase Order Data + File",
      "type": "n8n-nodes-base.merge",
      "position": [
        1616,
        224
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "020e35dc-3e3c-46fa-beff-dff13ae8a2b6",
      "name": "Upload Invoice to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1968,
        -240
      ],
      "parameters": {
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_FOLDER_ID",
          "cachedResultUrl": "",
          "cachedResultName": "YOUR_FOLDER_NAME"
        },
        "inputDataFieldName": "attachment_0"
      },
      "typeVersion": 3
    },
    {
      "id": "2b37b79b-7241-4a51-bf1b-a18000a8612f",
      "name": "Upload Contract to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1968,
        0
      ],
      "parameters": {
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "e6d5b804-9f5c-4254-8978-851a3941317b",
      "name": "Upload Purchase Order to Drive",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        1968,
        224
      ],
      "parameters": {
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (Root folder)"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "85daecdd-24d1-4e2b-818b-de5f4ea6389e",
      "name": "Update Master Finance Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2320,
        -240
      ],
      "parameters": {
        "columns": {
          "value": {
            "Invoice Number": "={{ $('Merge: Invoice Data + File').item.json.data.invoice_number }}",
            "Final Amount (EUR)": "={{ $('Merge: Invoice Data + File').item.json.data.total_amount }}"
          },
          "schema": [
            {
              "id": "Invoice Number",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Invoice Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Original Amount",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Original Amount",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Exchange Rate",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Exchange Rate",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Final Amount (EUR)",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Final Amount (EUR)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "Invoice Number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_SPREADSHEET_ID",
          "cachedResultUrl": "",
          "cachedResultName": "YOUR_SPREADSHEET_NAME"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "2c3da541-18e2-4379-b2f1-8596d15d6636",
      "name": "Slack: Notify Sales \u2013 New Contract",
      "type": "n8n-nodes-base.slack",
      "position": [
        2320,
        0
      ],
      "parameters": {
        "select": "channel",
        "blocksUi": "=:page_facing_up: *New Contract Received*\n\n*Client:* {{ $('Merge: Contract Data + File').item.json.data.client_name }}\n*Type:* {{ $('Merge: Contract Data + File').item.json.data.contract_type }}\n*Value:* {{ $('Merge: Contract Data + File').item.json.data.contract_value }} {{ $('Merge: Contract Data + File').item.json.data.currency }}\n*Start Date:* {{ $('Merge: Contract Data + File').item.json.data.start_date }}\n*Notice Period:* {{ $('Merge: Contract Data + File').item.json.data.notice_period }}\n\n:file_folder: <{{ $('Upload Contract to Drive').item.json.webViewLink }}|View in Drive>",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_CHANNEL_ID",
          "cachedResultName": "YOUR_CHANNEL_NAME"
        },
        "messageType": "block",
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "2a4d8c2f-90fc-48cc-97e1-bd9eee092b88",
      "name": "Slack: Notify Team \u2013 Restock Update",
      "type": "n8n-nodes-base.slack",
      "position": [
        2320,
        224
      ],
      "parameters": {
        "select": "channel",
        "blocksUi": "=:package: *New Purchase Order Filed*\n\n*Supplier:* {{ $('Merge: Purchase Order Data + File').item.json.data.supplier_name }}\n*PO Number:* {{ $('Merge: Purchase Order Data + File').item.json.data.po_number }}\n*Order Date:* {{ $('Merge: Purchase Order Data + File').item.json.data.order_date }}\n*Expected Delivery:* {{ $('Merge: Purchase Order Data + File').item.json.data.expected_delivery_date }}\n*Total:* {{ $('Merge: Purchase Order Data + File').item.json.data.total_amount }} {{ $('Merge: Purchase Order Data + File').item.json.data.currency }}\n\n:file_folder: <{{ $('Upload Purchase Order to Drive').item.json.webViewLink }}|View in Drive>",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "YOUR_CHANNEL_ID",
          "cachedResultName": "YOUR_CHANNEL_NAME"
        },
        "messageType": "block",
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "4f4b838e-f861-4d3a-bf88-43359618d52c",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 432,
        "content": "## \ud83d\udce7 Email Intake\nPolls Gmail every minute for new emails. Downloads attachments automatically. The binary file is branched to all merge nodes so the original document stays available throughout the workflow."
      },
      "typeVersion": 1
    },
    {
      "id": "3eb38c43-2469-4e6a-a82a-bedeafd92efd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        96,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 432,
        "content": "## \ud83c\udff7\ufe0f Document Classification\nSends the email attachment to **easybits Extractor** configured for classification. Returns a `document_class` field with one of three values: `Invoice`, `Contracts`, or `Purchase Orders`. The Switch node routes the item down the matching path."
      },
      "typeVersion": 1
    },
    {
      "id": "88cd89d2-fc71-4a84-9628-b3ba7b99215b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        -240
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 432,
        "content": "## \ud83d\udd00 Route by Document Type\nReads the `document_class` returned by the classification step and routes the item to the matching path: **Invoice**, **Contract**, or **Purchase Order**. Each output connects to its own extraction and delivery pipeline."
      },
      "typeVersion": 1
    },
    {
      "id": "5f85c781-64da-404c-96cc-d5dc19376aed",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        800,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 896,
        "content": "## \ud83d\udd17 Merge: Restore Original File\nThe classification step strips the binary from the item. These Merge nodes reunite the original email attachment (from the Gmail Trigger) with the routed item so the Extractor receives both the document class and the actual file."
      },
      "typeVersion": 1
    },
    {
      "id": "06654027-24a1-4348-9830-fbd1b5e2a1c0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 896,
        "content": "## \ud83e\udd16 Document-Specific Extraction\nEach route has its own **easybits Extractor** pipeline configured for that document type. Invoices extract vendor, amount, due date. Contracts extract client, value, notice period. Purchase Orders extract supplier, items, delivery date."
      },
      "typeVersion": 1
    },
    {
      "id": "a5221886-245e-45ca-ba5c-cf7104ee95d4",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 896,
        "content": "## \ud83d\udd17 Merge: Combine Extracted Data + File\nThe Extractor returns structured JSON but strips the binary again. These Merge nodes recombine the extracted data with the original file so the Google Drive upload node has both the file to store and the JSON to pass downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "abbe021c-c4e6-412f-aeda-3c8db5a2b6b8",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 896,
        "content": "## \u2601\ufe0f Upload to Google Drive\nStores the original document in a dedicated folder per type: **Invoices**, **Contracts**, or **Purchase Orders**. The Drive link is passed to the next node for reference in Sheets or Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "a58997cf-579c-4dbe-a45e-266959e4a897",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2208,
        -464
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 896,
        "content": "## \ud83d\udce4 Notify & Log\nEach route ends with a different action: **Invoices** are appended to the Master Finance Sheet. **Contracts** trigger a Slack message to Mike with key terms and a Drive link. **Purchase Orders** post a restock update to the team channel."
      },
      "typeVersion": 1
    },
    {
      "id": "89143657-a827-49b0-8c65-44f303ced5ac",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        -736
      ],
      "parameters": {
        "width": 848,
        "height": 1520,
        "content": "# \ud83d\udcec Smart Mailroom: Auto-Classify & Route Documents with easybits\n\n## What This Workflow Does\nReceive any business document via email. The attachment is automatically **classified** (Invoice, Contract, or Purchase Order) using easybits Extractor, then **routed** down the correct path where a second Extractor pulls out document-specific data. Each route stores the file in Google Drive and triggers the appropriate action \u2013 Invoices go to a finance spreadsheet, Contracts and Purchase Orders trigger Slack notifications.\n\n## How It Works\n1. **Receive** \u2013 Gmail polls for new emails with attachments every minute\n2. **Classify** \u2013 easybits Extractor identifies the document type and returns a class label\n3. **Route** \u2013 A Switch node sends the item down the matching path (Invoice / Contract / PO)\n4. **Merge Binary** \u2013 The original file is merged back into the routed item (classification strips the binary)\n5. **Extract** \u2013 A second easybits Extractor pulls fields specific to that document type\n6. **Merge Data + File** \u2013 Extracted JSON and original binary are combined for upload\n7. **Store & Notify** \u2013 The file is uploaded to Google Drive; Invoices update a spreadsheet, Contracts and POs trigger Slack alerts\n\n---\n\n## Setup Guide\n\n### 1. Create Your easybits Classification Pipeline\n1. Go to **extractor.easybits.tech** and create a new pipeline\n2. Add **one field** called `document_class`\n3. In the field prompt, describe your classification categories and how to identify each one\n4. The prompt should instruct the model to return exactly one category label \u2013 no explanations, no extra text\n5. Adjust the categories and identification criteria to match your specific document types\n6. Copy your **Pipeline ID** and your **API Key** and connect the credential in the document classification node\n\n> \ud83d\udca1 **Tip:** The classification prompt is the heart of this workflow. The more specific your category descriptions and decision rules are, the more accurate your results will be.\n\n### 2. Create Three Extraction Pipelines\nCreate one pipeline per document type on **extractor.easybits.tech**:\n- **Invoice pipeline** \u2013 fields: `invoice_number`, `total_amount`, `currency`, `due_date`, `vendor_name`\n- **Contract pipeline** \u2013 fields: `client_name`, `contract_type`, `contract_value`, `currency`, `start_date`, `notice_period`\n- **Purchase Order pipeline** \u2013 fields: `supplier_name`, `po_number`, `order_date`, `expected_delivery_date`, `total_amount`, `currency`\n\nConnect each pipeline's credentials to the matching Extractor node.\n\n### 3. Set Up Gmail\nConnect your Gmail account via OAuth2. Optionally filter by label to only process specific emails. Make sure **Download Attachments** is enabled in the node options.\n\n### 4. Set Up Google Drive\nCreate three folders in Google Drive: **Invoices**, **Contracts**, **Purchase Orders**. Select the correct folder in each Upload node. Set the **Input Binary Field** to `attachment_0` (or whichever field carries the PDF).\n\n### 5. Set Up Google Sheets\nCreate a spreadsheet (or use an existing Master Finance File). Make sure the column headers match the field mappings in the \"Update Master Finance Sheet\" node.\n\n### 6. Set Up Slack\nConnect your Slack workspace. Select the channel for contract notifications (e.g. `#contracts`) and the channel for PO updates (e.g. `#operations`). Adjust the message templates if your extracted field names differ.\n\n### 7. Activate & Test\nSet the workflow to active and send a test email with an invoice, contract, and purchase order attached to verify each route works end to end."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "",
  "connections": {
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "easybits: Classify Document",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge: Invoice Binary",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge: Invoice Data + File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge: Contract Binary",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge: Purchase Order Binary",
            "type": "main",
            "index": 1
          },
          {
            "node": "Merge: Contract Data + File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge: Purchase Order Data + File",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge: Invoice Binary": {
      "main": [
        [
          {
            "node": "easybits: Extract Invoice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Contract Binary": {
      "main": [
        [
          {
            "node": "easybits: Extract Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Document Type": {
      "main": [
        [
          {
            "node": "Merge: Invoice Binary",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Merge: Contract Binary",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Merge: Purchase Order Binary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Invoice to Drive": {
      "main": [
        [
          {
            "node": "Update Master Finance Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Contract to Drive": {
      "main": [
        [
          {
            "node": "Slack: Notify Sales \u2013 New Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Extract Invoice": {
      "main": [
        [
          {
            "node": "Merge: Invoice Data + File",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Extractor: Purchase Orders": {
      "main": [
        [
          {
            "node": "Merge: Purchase Order Data + File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Invoice Data + File": {
      "main": [
        [
          {
            "node": "Upload Invoice to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Extract Contract": {
      "main": [
        [
          {
            "node": "Merge: Contract Data + File",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge: Contract Data + File": {
      "main": [
        [
          {
            "node": "Upload Contract to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Classify Document": {
      "main": [
        [
          {
            "node": "Route by Document Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Purchase Order Binary": {
      "main": [
        [
          {
            "node": "Extractor: Purchase Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload Purchase Order to Drive": {
      "main": [
        [
          {
            "node": "Slack: Notify Team \u2013 Restock Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge: Purchase Order Data + File": {
      "main": [
        [
          {
            "node": "Upload Purchase Order to Drive",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}