Extraktion-von-Rechtsvertragsdaten-und-Versand-von-Erinnerungen-mit-VLM-Run,-Google-Workspace-und-Slack
Dies ist ein Automatisierungsworkflow mit 14 Nodes. Hauptsächlich werden Set, Code, Slack, Webhook, GoogleDrive und andere Nodes verwendet. Rechtliche Vertragsdaten extrahieren und Erinnerungen mit VLM Run, Google Workspace und Slack senden
- •Slack Bot Token oder Webhook URL
- •HTTP Webhook-Endpunkt (wird von n8n automatisch generiert)
- •Google Drive API-Anmeldedaten
- •Google Sheets API-Anmeldedaten
Verwendete Nodes (14)
Kategorie
{
"meta": {
"instanceId": "96d35e452e0d9a182973416b7532cfc5643239aaaa764a5bf74d52ca84f4a35c",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "bdfebade-893c-411c-80c6-0dace07f7dc9",
"name": "📁 Eingabeverarbeitungsdokumentation",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"color": 7,
"width": 400,
"height": 680,
"content": "## 📁 Input Processing\n\n**Monitors & downloads contract files from Google Drive.**\n\n**Process:**\n1. Watches designated Drive folder\n2. Auto-triggers on new uploads\n3. Downloads files for AI processing\n\n**Supported Formats:**\n- Images (JPG, PNG, WEBP)\n- PDF documents\n- Mobile camera uploads\n- Scanned contracts"
},
"typeVersion": 1
},
{
"id": "2fca40fa-ac4a-4515-a1e0-295cdcbfc595",
"name": "Vertragsuploads überwachen",
"type": "n8n-nodes-base.googleDriveTrigger",
"notes": "Monitors Google Drive folder for new receipt uploads and triggers processing automatically.",
"position": [
48,
480
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "1S6baavqJn98MjUlbB6KtmARCWuWEekIZ",
"cachedResultUrl": "https://drive.google.com/drive/folders/1S6baavqJn98MjUlbB6KtmARCWuWEekIZ",
"cachedResultName": "test_data"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "zYyIOFMdGz258avn",
"name": "Google Drive account 6"
}
},
"typeVersion": 1
},
{
"id": "95acb226-9205-4a21-9a2d-c9792bc81de4",
"name": "Vertragsdatei herunterladen",
"type": "n8n-nodes-base.googleDrive",
"notes": "Downloads receipt files from Google Drive for AI processing.",
"position": [
256,
480
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {
"binaryPropertyName": "data"
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"id": "zYyIOFMdGz258avn",
"name": "Google Drive account 6"
}
},
"typeVersion": 3
},
{
"id": "61fa2c83-72cd-44b0-a5cd-5fbaeef5dfb1",
"name": "🤖 KI-Extraktionsdokumentation",
"type": "n8n-nodes-base.stickyNote",
"position": [
512,
0
],
"parameters": {
"width": 416,
"height": 680,
"content": "## 🤖 VLM Run Contract Extraction\n\n**Uses VLM Run node to extract structured data from contract images/PDFs.**\n\n**Extracts:**\n- Contract ID\n- Title\n- Parties\n- Effective Date\n- Termination Date\n\n**Features:**\n- Handles poor quality images\n- Various receipt formats\n- OCR text recognition"
},
"typeVersion": 1
},
{
"id": "84d28c8a-b33c-4bc3-9489-846c3b412d4a",
"name": "VLM Run ContractParser",
"type": "@vlm-run/n8n-nodes-vlmrun.vlmRun",
"position": [
560,
480
],
"parameters": {
"operation": "executeAgent",
"agentPrompt": "extract data from the invoice or contract, Extract the key details from this lease contract. I am expecting the output to be in JSON format, with tags, using parameters : contract_id, title, parties (with role), property_address, effective_date, termination_date, rent_amount, security_deposit, payment_terms, governing_law . All the parameters should get values from the pdf of data file from the download contract file. \nNormalize dates to YYYY-MM-DD and amounts as numbers with currency. \nIf a field is missing, return null.",
"agentCallbackUrl": "https://playground.attensys.ai/webhook/b905e71d-8ea5-4fc2-a773-b0f92e5398e4"
},
"credentials": {
"vlmRunApi": {
"id": "B7ZYM8AfBgjnOEOl",
"name": "VLM Run account 5"
}
},
"typeVersion": 1
},
{
"id": "17996d92-afea-484c-88d3-9b2b673b1f4c",
"name": "📊 Speicherdokumentation",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
0
],
"parameters": {
"color": 7,
"width": 420,
"height": 680,
"content": "## 📊 Data Storage\n\n**Structures and stores extracted data in Google Sheets.**\n\n**Features:**\n- Clean, organized format\n- Centralized expense database\n- Auto-appends new entries\n- Analysis-ready data\n\n**Data Fields:**\n- ID\n- Title\n- Parties\n- Effective and Termination Date\n\n**Benefits:**\n- Real-time tracking\n- Easy exports\n- Mobile access"
},
"typeVersion": 1
},
{
"id": "70c2c9c5-d950-495f-9e91-5a0b402ef739",
"name": "In Ausgabendatenbank speichern",
"type": "n8n-nodes-base.googleSheets",
"notes": "Automatically saves extracted receipt data to Google Sheets for expense tracking.",
"position": [
1344,
480
],
"parameters": {
"columns": {
"value": {
"Title": "={{$node[\"Format Contract Data\"].json[\"Title\"]}}",
"Parties": "={{$node[\"Format Contract Data\"].json[\"Parties\"]}}",
"Contract ID": "={{$node[\"Format Contract Data\"].json[\"Contract ID\"]}}",
"Effective Date": "={{$node[\"Format Contract Data\"].json[\"Effective Date\"]}}",
"Termination Date": "={{$node[\"Format Contract Data\"].json[\"Termination Date\"]}}"
},
"schema": [
{
"id": "Contract ID",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Contract ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Title",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Parties",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Parties",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Effective Date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Effective Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Termination Date",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Termination Date",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Customer"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/11_VjMdhv_JN2eSRZiw_t0dIN-yShkn2jlCDwiG8eb14/edit#gid=0",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1lg0aJKvd7E2pbhumHNjcgxUfEQKvlBs9h1zZbhSeqas",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1lg0aJKvd7E2pbhumHNjcgxUfEQKvlBs9h1zZbhSeqas/edit?usp=drivesdk",
"cachedResultName": "test"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"id": "sdLQgQJjowDNfXMU",
"name": "Google Sheets account 7"
}
},
"typeVersion": 4.6
},
{
"id": "f752ffb1-d4eb-4d69-919d-2f4d72fb753e",
"name": "Vertragsdaten formatieren",
"type": "n8n-nodes-base.set",
"notes": "Transforms AI-extracted receipt data into clean, structured format for spreadsheet storage.",
"position": [
1136,
480
],
"parameters": {
"values": {
"string": [
{
"name": "Contract ID",
"value": "={{ $json.body.response.contract_id }}"
},
{
"name": "Title",
"value": "={{ $json.body.response.title }}"
},
{
"name": "Parties",
"value": "={{ $json.body.parties && $json.body.parties.length ? $json.body.parties.map(p => p.name + \" (\"+ p.role + \")\").join(\"; \") : \"\" }}"
},
{
"name": "Effective Date",
"value": "={{ $json.body.response.effective_date }}"
},
{
"name": "Termination Date",
"value": "={{ $json.body.response.termination_date }}"
}
]
},
"options": {},
"keepOnlySet": true
},
"typeVersion": 1
},
{
"id": "d04b627c-1b80-4692-91a3-2df61bec0b4d",
"name": "Nachricht senden",
"type": "n8n-nodes-base.slack",
"position": [
1712,
512
],
"webhookId": "6b8dcfb9-51a9-418b-8469-4bf5b5894f2a",
"parameters": {
"text": "=*New Contract Processed* 📄\n• Contract ID: {{$node[\"Format Contract Data\"].json[\"Contract ID\"] || \"N/A\"}}\n• Title: {{$node[\"Format Contract Data\"].json[\"Title\"] || \"N/A\"}}\n• Parties: {{$node[\"Format Contract Data\"].json[\"Parties\"] || \"N/A\"}}\n• Effective: {{$node[\"Format Contract Data\"].json[\"Effective Date\"] || \"N/A\"}}\n• Termination: {{$node[\"Format Contract Data\"].json[\"Termination Date\"] || \"N/A\"}}\n🔗 {{$node[\"Format Contract Data\"].json[\"Drive Link\"] || $node[\"Save to Expense Database\"].json[\"driveLink\"] || \"No drive link available\"}}\n",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C081Z0KL546",
"cachedResultName": "test"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"id": "M00QrTNTmnr6yiTS",
"name": "Slack account 11"
}
},
"typeVersion": 2.3
},
{
"id": "955768a3-5fac-4296-a5a3-d307a98b471c",
"name": "Kalenderereignisse vorbereiten",
"type": "n8n-nodes-base.code",
"position": [
1616,
336
],
"parameters": {
"jsCode": "// n8n Function node code\n// Reads from Format Contract Data node and returns 1..3 items, each has .json with summary, description, start, end (YYYY-MM-DD)\n\nconst fmt = $node[\"Format Contract Data\"].json;\nconst title = fmt[\"Title\"] || \"Untitled Contract\";\nconst cid = fmt[\"Contract ID\"] || \"\";\nconst parties = fmt[\"Parties\"] || \"\";\nconst drive = fmt[\"Drive Link\"] || \"\";\n\nfunction isoDate(d) {\n // return YYYY-MM-DD\n return d.toISOString().split('T')[0];\n}\n\nfunction makeAllDayDates(dateStr) {\n // Accepts YYYY-MM-DD (or other parseable), returns start and end for all-day event.\n if(!dateStr) return null;\n const d = new Date(dateStr + \"T00:00:00\");\n const start = isoDate(d);\n const endD = new Date(d);\n endD.setDate(endD.getDate() + 1); // exclusive end for all-day events\n const end = isoDate(endD);\n return { start, end };\n}\n\nconst items = [];\n\n// Effective Date event\nconst eff = makeAllDayDates(fmt[\"Effective Date\"]);\nif (eff) {\n items.push({\n json: {\n summary: `${title} — Effective Date`,\n description: `Contract ID: ${cid}\\nParties: ${parties}\\nDrive: ${drive}`,\n start: eff.start,\n end: eff.end,\n allDay: true,\n metaType: \"effective\"\n }\n });\n}\n\n// Termination Date event\nconst term = makeAllDayDates(fmt[\"Termination Date\"]);\nif (term) {\n items.push({\n json: {\n summary: `${title} — Termination Date`,\n description: `Contract ID: ${cid}\\nParties: ${parties}\\nDrive: ${drive}`,\n start: term.start,\n end: term.end,\n allDay: true,\n metaType: \"termination\"\n }\n });\n\n // Renewal review reminder 60 days before termination\n const termDate = new Date(fmt[\"Termination Date\"] + \"T00:00:00\");\n const reminderDate = new Date(termDate);\n reminderDate.setDate(reminderDate.getDate() - 60); // change 60 to your preferred days\n const remStart = isoDate(reminderDate);\n const remEndD = new Date(reminderDate);\n remEndD.setDate(remEndD.getDate() + 1);\n const remEnd = isoDate(remEndD);\n\n items.push({\n json: {\n summary: `${title} — Renewal Review (Reminder)`,\n description: `Contract ID: ${cid}\\nTermination Date: ${fmt[\"Termination Date\"]}\\nAction: Review & decide renewal.`,\n start: remStart,\n end: remEnd,\n allDay: true,\n metaType: \"renewal_reminder\"\n }\n });\n}\n\nreturn items;\n"
},
"typeVersion": 2
},
{
"id": "f3301d1a-5773-4598-ba4e-71019a4966bd",
"name": "Ereignis erstellen",
"type": "n8n-nodes-base.googleCalendar",
"position": [
1808,
336
],
"parameters": {
"end": "={{$json[\"end\"]}}",
"start": "={{$json[\"start\"]}}",
"calendar": {
"__rl": true,
"mode": "list",
"value": "sayonaraistata@gmail.com",
"cachedResultName": "sayonaraistata@gmail.com"
},
"additionalFields": {
"allday": "yes",
"summary": "={{$json[\"summary\"]}}",
"description": "={{$json[\"description\"]}}"
}
},
"credentials": {
"googleCalendarOAuth2Api": {
"id": "9TLut5ZDt3hcaQEo",
"name": "Google Calendar account 3"
}
},
"typeVersion": 1.3
},
{
"id": "dd656271-d2a3-4f8a-9df8-1da0596b2734",
"name": "📊 Speicherdokumentation1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1552,
0
],
"parameters": {
"color": 7,
"width": 420,
"height": 680,
"content": "## 🔔 Notifications Added:\n\n1. **Slack** → Posts contract details & AI-generated summary to #all-n8n-test for team visibility.\n\n2. **Google Calendar** → Auto-creates all-day events:\n • Effective Date\n • Termination Date\n • Renewal Reminder (30 days before)\n → Helps track key contract milestones.\n"
},
"typeVersion": 1
},
{
"id": "99fdd61d-c6a9-4e74-989a-e56b47caf2e9",
"name": "Haftnotiz3",
"type": "n8n-nodes-base.stickyNote",
"position": [
368,
704
],
"parameters": {
"color": 5,
"width": 704,
"height": 144,
"content": "## 📝 Set the Callback URL\n\nMake sure to paste the **Production URL** of your n8n Webhook node into the **Callback URL** field in VLM Run. This ensures that the extracted image links are securely and reliably sent back to your live workflow. Do **not** use localhost or development URLs, they won’t be reachable by VLM Run’s servers."
},
"typeVersion": 1
},
{
"id": "6d26e945-a724-4e3b-a8ff-c91dd8500f5f",
"name": "Vertrag empfangen",
"type": "n8n-nodes-base.webhook",
"position": [
784,
480
],
"webhookId": "b905e71d-8ea5-4fc2-a773-b0f92e5398e4",
"parameters": {
"path": "b905e71d-8ea5-4fc2-a773-b0f92e5398e4",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
}
],
"pinData": {},
"connections": {
"6d26e945-a724-4e3b-a8ff-c91dd8500f5f": {
"main": [
[
{
"node": "f752ffb1-d4eb-4d69-919d-2f4d72fb753e",
"type": "main",
"index": 0
}
]
]
},
"f752ffb1-d4eb-4d69-919d-2f4d72fb753e": {
"main": [
[
{
"node": "70c2c9c5-d950-495f-9e91-5a0b402ef739",
"type": "main",
"index": 0
}
]
]
},
"95acb226-9205-4a21-9a2d-c9792bc81de4": {
"main": [
[
{
"node": "84d28c8a-b33c-4bc3-9489-846c3b412d4a",
"type": "main",
"index": 0
}
]
]
},
"955768a3-5fac-4296-a5a3-d307a98b471c": {
"main": [
[
{
"node": "f3301d1a-5773-4598-ba4e-71019a4966bd",
"type": "main",
"index": 0
}
]
]
},
"2fca40fa-ac4a-4515-a1e0-295cdcbfc595": {
"main": [
[
{
"node": "95acb226-9205-4a21-9a2d-c9792bc81de4",
"type": "main",
"index": 0
}
]
]
},
"70c2c9c5-d950-495f-9e91-5a0b402ef739": {
"main": [
[
{
"node": "d04b627c-1b80-4692-91a3-2df61bec0b4d",
"type": "main",
"index": 0
},
{
"node": "955768a3-5fac-4296-a5a3-d307a98b471c",
"type": "main",
"index": 0
}
]
]
}
}
}Wie verwende ich diesen Workflow?
Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.
Für welche Szenarien ist dieser Workflow geeignet?
Fortgeschritten
Ist es kostenpflichtig?
Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.
Verwandte Workflows
Shahrear
@shahrearI’m Shahrear, a Software Engineer with over 5 years of experience in full-stack development and workflow automation. I specialize in building intelligent automations using n8n, helping teams streamline operations and boost productivity. I’m also an expert in developing custom n8n nodes, with published work on npm - including the @vlm-run/n8n-nodes-vlmrun package. Linkedin - https://www.linkedin.com/in/shahrear-amin/ Email - shahrearbinamin33@gmail.com
Diesen Workflow teilen