AutomationFlowsData & Sheets › Classify Contracts and Track Renewals with Easybits, Google Drive and Sheets

Classify Contracts and Track Renewals with Easybits, Google Drive and Sheets

ByFelix @easybits on n8n.io

Drop a contract (PDF, JPG, PNG) into a watched Google Drive folder. easybits Extractor classifies it (SaaS / Lease / Service / Insurance / Other) and pulls every renewal-relevant field in a single call. A Set node calculates the contract's end date and the cancellation deadline.…

Event trigger★★★★☆ complexity19 nodes@Easybits/N8N Nodes ExtractorGoogle SheetsGoogle Drive TriggerGoogle Drive
Data & Sheets Trigger: Event Nodes: 19 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #15230 — we link there as the canonical source.

This workflow follows the Google Drive → Google Drive Trigger 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "Contract Renewal Watchdog Intake & Classification",
  "tags": [],
  "nodes": [
    {
      "id": "22fdac58-c444-43e4-b1ae-e42fdc7c448b",
      "name": "easybits: Classify & Extract Contract",
      "type": "@easybits/n8n-nodes-extractor.easybitsExtractor",
      "position": [
        -928,
        544
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b64df7fd-37aa-4e8e-8cd3-ab394fcd4c38",
      "name": "IF: Is Contract?",
      "type": "n8n-nodes-base.if",
      "position": [
        -320,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-is-contract",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.contract_type }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "33692a4a-606d-46ef-8a09-acf16aef6897",
      "name": "Log SaaS Contract",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        240
      ],
      "parameters": {
        "columns": {
          "value": {
            "End Date": "={{ $('Calculate End Date & Deadline').item.json.end_date }}",
            "Auto Renew": "={{ $('Calculate End Date & Deadline').item.json.data.auto_renew }}",
            "Start Date": "={{ $('Calculate End Date & Deadline').item.json.data.start_date }}",
            "Client Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_name }}",
            "Provider Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_name }}",
            "Contract Class": "={{ $('Calculate End Date & Deadline').item.json.data.contract_type }}",
            "Contract Value": "={{ $('Calculate End Date & Deadline').item.json.data.contract_value }}",
            "Notice Period Days": "={{ $('Calculate End Date & Deadline').item.json.data.notice_period_days }}",
            "Initial Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.initial_term_months }}",
            "Renewal Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.renewal_term_months }}",
            "Cancellation Deadline": "={{ $('Calculate End Date & Deadline').item.json.cancellation_deadline }}",
            "Client Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_signatory_name }}",
            "Provider Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_signatory_name }}"
          },
          "schema": [
            {
              "id": "Start Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Initial Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Initial Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Renew",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Auto Renew",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notice Period Days",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notice Period Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Renewal Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Renewal Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cancellation Deadline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cancellation Deadline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Class",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Class",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "SaaS"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "d8b60b4a-5c31-4dd3-b9e8-e78721ec04d0",
      "name": "Log Lease Contract",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        400
      ],
      "parameters": {
        "columns": {
          "value": {
            "End Date": "={{ $('Calculate End Date & Deadline').item.json.end_date }}",
            "Auto Renew": "={{ $('Calculate End Date & Deadline').item.json.data.auto_renew }}",
            "Start Date": "={{ $('Calculate End Date & Deadline').item.json.data.start_date }}",
            "Client Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_name }}",
            "Provider Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_name }}",
            "Contract Class": "={{ $('Calculate End Date & Deadline').item.json.data.contract_type }}",
            "Contract Value": "={{ $('Calculate End Date & Deadline').item.json.data.contract_value }}",
            "Notice Period Days": "={{ $('Calculate End Date & Deadline').item.json.data.notice_period_days }}",
            "Initial Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.initial_term_months }}",
            "Renewal Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.renewal_term_months }}",
            "Cancellation Deadline": "={{ $('Calculate End Date & Deadline').item.json.cancellation_deadline }}",
            "Client Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_signatory_name }}",
            "Provider Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_signatory_name }}"
          },
          "schema": [
            {
              "id": "Start Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Initial Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Initial Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Renew",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Auto Renew",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notice Period Days",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notice Period Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Renewal Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Renewal Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cancellation Deadline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cancellation Deadline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Class",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Class",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Leases"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "b76ac8c3-d398-4cac-9b19-11ca118dc844",
      "name": "Log Service Contract",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        560
      ],
      "parameters": {
        "columns": {
          "value": {
            "End Date": "={{ $('Calculate End Date & Deadline').item.json.end_date }}",
            "Auto Renew": "={{ $('Calculate End Date & Deadline').item.json.data.auto_renew }}",
            "Start Date": "={{ $('Calculate End Date & Deadline').item.json.data.start_date }}",
            "Client Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_name }}",
            "Provider Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_name }}",
            "Contract Class": "={{ $('easybits: Classify & Extract Contract').item.json.data.contract_type }}",
            "Contract Value": "={{ $('Calculate End Date & Deadline').item.json.data.contract_value }}",
            "Notice Period Days": "={{ $json.data.notice_period_days }}",
            "Initial Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.initial_term_months }}",
            "Renewal Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.renewal_term_months }}",
            "Cancellation Deadline": "={{ $('Calculate End Date & Deadline').item.json.cancellation_deadline }}",
            "Client Signatory Name": "={{ $('easybits: Classify & Extract Contract').item.json.data.client_signatory_name }}",
            "Provider Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_signatory_name }}"
          },
          "schema": [
            {
              "id": "Start Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Initial Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Initial Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Renew",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Auto Renew",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notice Period Days",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notice Period Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Renewal Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Renewal Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cancellation Deadline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cancellation Deadline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Class",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Class",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Services"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "91f70531-e442-400c-964e-07b56ed61407",
      "name": "Log Insurance Contract",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        720
      ],
      "parameters": {
        "columns": {
          "value": {
            "End Date": "={{ $('Calculate End Date & Deadline').item.json.end_date }}",
            "Auto Renew": "={{ $('Calculate End Date & Deadline').item.json.data.auto_renew }}",
            "Start Date": "={{ $('Calculate End Date & Deadline').item.json.data.start_date }}",
            "Client Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_name }}",
            "Provider Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_name }}",
            "Contract Class": "={{ $('Calculate End Date & Deadline').item.json.data.contract_type }}",
            "Contract Value": "={{ $('Calculate End Date & Deadline').item.json.data.contract_value }}",
            "Notice Period Days": "={{ $('Calculate End Date & Deadline').item.json.data.notice_period_days }}",
            "Initial Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.initial_term_months }}",
            "Renewal Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.renewal_term_months }}",
            "Cancellation Deadline": "={{ $('Calculate End Date & Deadline').item.json.cancellation_deadline }}",
            "Client Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_signatory_name }}",
            "Provider Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_signatory_name }}"
          },
          "schema": [
            {
              "id": "Start Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Initial Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Initial Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Renew",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Auto Renew",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notice Period Days",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notice Period Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Renewal Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Renewal Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cancellation Deadline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cancellation Deadline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Class",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Class",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Insurance"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "ac9b66f9-2b67-4f7f-bf38-90fbe9a22706",
      "name": "Log Other Contract",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        288,
        880
      ],
      "parameters": {
        "columns": {
          "value": {
            "End Date": "={{ $('Calculate End Date & Deadline').item.json.end_date }}",
            "Auto Renew": "={{ $('Calculate End Date & Deadline').item.json.data.auto_renew }}",
            "Start Date": "={{ $('Calculate End Date & Deadline').item.json.data.start_date }}",
            "Client Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_name }}",
            "Provider Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_name }}",
            "Contract Class": "={{ $('Calculate End Date & Deadline').item.json.data.contract_type }}",
            "Contract Value": "={{ $('Calculate End Date & Deadline').item.json.data.contract_value }}",
            "Notice Period Days": "={{ $('Calculate End Date & Deadline').item.json.data.notice_period_days }}",
            "Initial Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.initial_term_months }}",
            "Renewal Term Months": "={{ $('Calculate End Date & Deadline').item.json.data.renewal_term_months }}",
            "Cancellation Deadline": "={{ $('Calculate End Date & Deadline').item.json.cancellation_deadline }}",
            "Client Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.client_signatory_name }}",
            "Provider Signatory Name": "={{ $('Calculate End Date & Deadline').item.json.data.provider_signatory_name }}"
          },
          "schema": [
            {
              "id": "Start Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Start Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Initial Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Initial Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Auto Renew",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Auto Renew",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Notice Period Days",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Notice Period Days",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Renewal Term Months",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Renewal Term Months",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "End Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "End Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Cancellation Deadline",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Cancellation Deadline",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Contract Class",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Contract Class",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Client Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Provider Signatory Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Provider Signatory Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Other"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "47f63006-e0d8-4b59-9180-010e0225e6fb",
      "name": "Watch Contract Folder",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        -1408,
        544
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_DRIVE_FOLDER_ID"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dae6acb2-7d59-494b-a16a-69a46641f13b",
      "name": "Download Uploaded Contract File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        -1216,
        544
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {},
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "d1fecf5a-4b4f-4d1e-85a5-3ebe466c720e",
      "name": "Calculate End Date & Deadline",
      "type": "n8n-nodes-base.set",
      "position": [
        -624,
        544
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "801cffeb-0267-42e9-92b5-dd17397162f4",
              "name": "end_date",
              "type": "string",
              "value": "={{ DateTime.fromISO($json.data.start_date).plus({ months: $json.data.initial_term_months }).toISODate() }}"
            },
            {
              "id": "c219ab58-ab2f-494a-9184-41d735db64e7",
              "name": "cancellation_deadline",
              "type": "string",
              "value": "={{ DateTime.fromISO($json.data.start_date).plus({ months: $json.data.initial_term_months }).minus({ days: $json.data.notice_period_days || 0 }).toISODate() }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "c9548b6b-5319-4283-ad6d-1600e404dc07",
      "name": "Skip: Not a Contract",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -16,
        560
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "1e4ea278-e418-46a2-b7c5-5a02f8dd41f0",
      "name": "Route by Contract Class",
      "type": "n8n-nodes-base.switch",
      "position": [
        -16,
        256
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "SaaS",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cond-saas",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.contract_type }}",
                    "rightValue": "saas_subscription"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Lease",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cond-lease",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.contract_type }}",
                    "rightValue": "lease_agreement"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Service",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cond-service",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.contract_type }}",
                    "rightValue": "service_contract"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Insurance",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cond-insurance",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.contract_type }}",
                    "rightValue": "insurance_policy"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Other",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cond-other",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.contract_type }}",
                    "rightValue": "other"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "325c6eb7-4fbe-4da3-81f3-260b66ceac59",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1472,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 432,
        "content": "### \ud83d\udce5 Contract Upload\nWatches a specific Google Drive folder and fires whenever a new file is added. The file is then downloaded and passed as binary to the next step. Polls every minute \u2013 expect up to 1 min delay from upload to processing."
      },
      "typeVersion": 1
    },
    {
      "id": "44530874-b28e-4bc2-9c28-60f5f199aa2b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 432,
        "content": "### \ud83e\udde0 Classify & Extract\nOne call to **easybits Extractor** does both jobs: classifies the document into one of five contract classes (SaaS, Lease, Service, Insurance, Other) and extracts every renewal-relevant field \u2013 parties, value, term, notice period, auto-renew flag, signatories. Returns `null` on `contract_class` when the document isn't a contract at all."
      },
      "typeVersion": 1
    },
    {
      "id": "1367c05c-c410-4a12-8e9e-0b7bb8768ba0",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -720,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 432,
        "content": "### \ud83d\udcc5 Calculate Dates\nDerives two dates from the extracted values:\n- `end_date` = `start_date` + `initial_term_months`\n- `cancellation_deadline` = `end_date` \u2212 `notice_period_days`\n\nThese drive the Part 2 Slack watchdog."
      },
      "typeVersion": 1
    },
    {
      "id": "b9996bf7-5dca-4f12-b653-178c1dc8c1d7",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -416,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 432,
        "content": "### \u2753 Is It a Contract?\n`is not empty` on `contract_class` catches null, undefined, and empty string. The false branch stops silently \u2013 extend to a Slack alert if you want to flag non-contracts for review."
      },
      "typeVersion": 1
    },
    {
      "id": "4104d1e1-1b9c-4c67-bbd6-580c2628d287",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -112,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 448,
        "content": "### \ud83d\udd00 Route by Contract Class\nExpression-based Switch on `contract_class`. Each output feeds a dedicated Google Sheets tab so the classification routing is visible on the canvas and easy to debug."
      },
      "typeVersion": 1
    },
    {
      "id": "dddbbe86-ea77-4aa9-977e-2dfac28a67b5",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        192,
        80
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 976,
        "content": "### \ud83d\udcd2 Log to Sheet\nOne Google Sheet, one tab per contract class. Each row carries the extracted fields plus the two derived dates. Append-only \u2013 never overwrites existing rows."
      },
      "typeVersion": 1
    },
    {
      "id": "514caff1-b345-4c15-bd2e-4932e909bcb9",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2240,
        -144
      ],
      "parameters": {
        "width": 752,
        "height": 1344,
        "content": "## \ud83d\udcc4 Contract Renewal Watchdog \u2013 Intake & Classification\n(powered by easybits)\n\n**What this workflow does**\nDrop a contract (PDF, JPG, PNG) into a watched Google Drive folder. **easybits Extractor** classifies it (SaaS / Lease / Service / Insurance / Other) and pulls every renewal-relevant field in a single call. A Set node calculates the contract's end date and the cancellation deadline. The classified contract is appended to the matching tab in a single Google Sheet \u2013 your source of truth for every renewal in the company.\n\n### Setup guide\n**1. Install the easybits Extractor node**\n- **n8n Cloud:** Already available, no install needed.\n- **Self-hosted:** Settings \u2192 Community Nodes \u2192 install `@easybits/n8n-nodes-extractor`.\n\n\n**2. Create your easybits pipeline**\nGo to [extractor.easybits.tech](https://extractor.easybits.tech) and create a pipeline with these fields:\n\n- `contract_class` (string) \u2013 enum: `saas_subscription`, `lease_agreement`, `service_contract`, `insurance_policy`, `other`. Returns `null` if not a contract.\n- `client_name` (string)\n- `provider_name` (string)\n- `start_date` (string, ISO format YYYY-MM-DD)\n- `initial_term_months` (number)\n- `renewal_term_months` (number)\n- `auto_renew` (string \u2013 \"true\"/\"false\")\n- `notice_period_days` (number)\n- `contract_value` (number)\n- `client_signatory_name` (string)\n- `provider_signatory_name` (string)\n\n\nPaste your Pipeline ID and connect your credentials in the **easybits: Classify & Extract Contract** node.\n\n\n**3. Create your Google Drive folder**\nCreate a folder (e.g. \"Incoming Contracts\") and paste its ID into the **Watch Contract Folder** node.\n\n\n**4. Create your Google Sheet**\nCreate one Google Sheet with five tabs: `SaaS`, `Leases`, `Services`, `Insurance`, `Other`.\n\nHeader row on every tab:\n`Start Date | Client Name | Provider Name | Contract Value | Initial Term Months | Renewal Term Months | Auto Renew | Notice Period Days | End Date | Cancellation Deadline | Contract Class | Client Signatory Name | Provider Signatory Name`\n\nPaste the Sheet ID into all 5 Google Sheets nodes.\n\n\n**5. Connect credentials**\n- easybits Extractor \u2192 your easybits API key\n- Google Drive \u2192 OAuth (used by both trigger and download)\n- Google Sheets \u2192 OAuth\n\n\n**6. Activate and test**\nTurn the workflow on, drop a contract PDF into the watched folder, and watch the correct tab fill up.\n\n### Field notes\n- `auto_renew` stays as a string (\"true\"/\"false\") because the easybits Extractor doesn't yet expose a boolean type. Part 2 handles the conversion.\n- `notice_period_days` is critical \u2013 without it, the cancellation deadline defaults to the end date, which is usually too late for contracts with 60\u201390 day notice clauses.\n- Supports PDF, JPG, and PNG only. Dropping other file types (Word, ODS, etc.) will error \u2013 add a mime-type filter before the Extractor if that's a real concern for your setup."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "connections": {
    "IF: Is Contract?": {
      "main": [
        [
          {
            "node": "Route by Contract Class",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Skip: Not a Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Watch Contract Folder": {
      "main": [
        [
          {
            "node": "Download Uploaded Contract File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Contract Class": {
      "main": [
        [
          {
            "node": "Log SaaS Contract",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Lease Contract",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Service Contract",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Insurance Contract",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Other Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate End Date & Deadline": {
      "main": [
        [
          {
            "node": "IF: Is Contract?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Uploaded Contract File": {
      "main": [
        [
          {
            "node": "easybits: Classify & Extract Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "easybits: Classify & Extract Contract": {
      "main": [
        [
          {
            "node": "Calculate End Date & Deadline",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Drop a contract (PDF, JPG, PNG) into a watched Google Drive folder. easybits Extractor classifies it (SaaS / Lease / Service / Insurance / Other) and pulls every renewal-relevant field in a single call. A Set node calculates the contract's end date and the cancellation deadline.…

Source: https://n8n.io/workflows/15230/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Automatically process invoices and receipts using Gemini OCR, extracting data directly into Google Sheets from multiple sources including Google Drive, Gmail, and Telegram. This powerful workflow ensu

HTTP Request, Google Sheets, Google Drive +3
Data & Sheets

Sales and marketing teams seeking efficient, hands‑free generation of personalized slide decks for each prospect from CSV lead lists.

Google Drive, Google Sheets, Google Drive Trigger +1
Data & Sheets

OCR receipts from Google Drive. Uses httpRequest, googleDriveTrigger, googleDrive, googleSheets. Event-driven trigger; 10 nodes.

HTTP Request, Google Drive Trigger, Google Drive +1
Data & Sheets

This workflow allows you to recognize a folder with receipts or invoices (make sure your files are in .pdf, .png, or .jpg format). The workflow can be triggered via the "Test workflow" button, and it

HTTP Request, Google Drive Trigger, Google Drive +1
Data & Sheets

Research Paper Analyzer & Literature Review Assistant. Uses googleDriveTrigger, googleDrive, n8n-nodes-pdfvector, googleSheets. Event-driven trigger; 9 nodes.

Google Drive Trigger, Google Drive, N8N Nodes Pdfvector +2