This workflow corresponds to n8n.io template #5801 — we link there as the canonical source.
This workflow follows the Gmail → Google Docs recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "PEldfy8Q5GiLQnfh",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Automate Legal Document Generation with Gemini AI, Apify, Playwright, and Google Docs",
"tags": [],
"nodes": [
{
"id": "be984026-22bd-46a2-b1d4-37fdf72bad6f",
"name": "Transform to base64",
"type": "n8n-nodes-base.extractFromFile",
"position": [
640,
180
],
"parameters": {
"options": {
"keepSource": "binary"
},
"operation": "binaryToPropery",
"binaryPropertyName": "=input_file"
},
"typeVersion": 1
},
{
"id": "27007f82-2c42-47d4-974d-fd444f33f897",
"name": "Approve Through Email",
"type": "n8n-nodes-base.gmail",
"position": [
2120,
180
],
"parameters": {
"sendTo": "=TODO",
"message": "Check/modify the generated content at TODO and then click \"Approve\" below.",
"options": {},
"subject": "Approval required"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "bb9dff19-aff9-4207-a7a2-a89d459d048a",
"name": "Get file for property",
"type": "n8n-nodes-base.httpRequest",
"position": [
440,
300
],
"parameters": {
"url": "={{ $json.file }}",
"options": {
"response": {
"response": {
"responseFormat": "file",
"outputPropertyName": "=input_file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "20b5382a-d97c-4088-a2b9-1772c577b9b3",
"name": "Apify Playwright script to find property info",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
200,
300
],
"parameters": {
"url": "https://api.apify.com/v2/acts/dinalevdev~property-lookup-king-county/run-sync-get-dataset-items",
"method": "POST",
"options": {},
"jsonBody": "= {\n \"address\": \"{{ $json.Address }}\",\n \"property_type\": \"{{ $json['What kind of address is this?'] }}\"\n }",
"sendBody": true,
"sendQuery": true,
"sendHeaders": true,
"specifyBody": "json",
"queryParameters": {
"parameters": [
{
"name": "token",
"value": "TODO"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "d69290c6-c288-41e0-9809-909bfde6c223",
"name": "Property metadata",
"type": "n8n-nodes-base.httpRequest",
"position": [
1300,
180
],
"parameters": {
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent",
"method": "POST",
"options": {},
"jsonBody": "={\n \"contents\": [{\n \"parts\":[\n {\"text\": \"Based on the information fetched so far and the attached PDF document for the property, return structured data containing your best guess of the Parcel number and owner's name. The parcel number from the link is {{ $('Apify Playwright script to find property info').item.json.parcel_no }} and from the detail page is {{ $('Apify Playwright script to find property info').item.json.parcel_number }} . Ensure the returned parcel number is numeric only with no dashes or other extraneous characters. The owner name scraped from the King County Property website is: {{ $('Apify Playwright script to find property info').item.json.owner_name }} . The owner's name may be formatted strangely in the site so use the attached PDF to provide best guess.\"},\n {\n \"inline_data\": {\n \"mime_type\": \"{{$('Apify Playwright script to find property info').item.json.mime_type}}\",\n \"data\": \"{{ $('Transform to base64').item.json.data }}\"\n }\n }\n ]\n }]\n}\n",
"sendBody": true,
"specifyBody": "=json",
"authentication": "genericCredentialType",
"bodyParameters": {
"parameters": [
{}
]
},
"genericAuthType": "httpQueryAuth"
},
"credentials": {
"oAuth2Api": {
"name": "<your credential>"
},
"httpQueryAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "f2926ac2-a475-4ea3-b584-096111f50ab2",
"name": "Call Gemini API for legal desc",
"type": "n8n-nodes-base.httpRequest",
"position": [
1080,
180
],
"parameters": {
"url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent",
"method": "POST",
"options": {},
"jsonBody": "={\n \"contents\": [{\n \"parts\":[\n {\"text\": \"What is the exact legal description of the property in the document, pulled directly from the provided PDF file? Do NOT include any other text in your response, just the extracted text itself. Remove any line breaks or newline characters (e.g., \\n ) that are an artifact of the PDF and not the text itself. Make sure the text returned does not have any blank lines or newline characters at the end.\"},\n {\n \"inline_data\": {\n \"mime_type\": \"{{ $('Get file for property').item.json.mime_type }}\",\n \"data\": \"{{ $('Transform to base64').item.json.data }}\"\n }\n }\n ]\n }]\n}\n",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpQueryAuth"
},
"credentials": {
"oAuth2Api": {
"name": "<your credential>"
},
"httpQueryAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "9d376366-3423-46d1-8317-e148b0cba684",
"name": "Google Gemini Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1620,
400
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash-lite"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "6671bb9e-bd6b-4614-a824-273660902c69",
"name": "Playwright error inform",
"type": "n8n-nodes-base.gmail",
"position": [
420,
500
],
"parameters": {
"sendTo": "TODO",
"message": "Check/modify the generated content at TODO and then update the Approval column to say \"Approved\" to generate documents.",
"options": {},
"subject": "Apify call failed"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "bbbfd9b5-2ce3-435d-a4ba-a2c6f2992f4e",
"name": "Property Information Extractor",
"type": "@n8n/n8n-nodes-langchain.informationExtractor",
"position": [
1520,
180
],
"parameters": {
"text": "={{ $json.candidates[0].content.parts[0].text }}",
"options": {
"systemPromptTemplate": "You are an expert extraction algorithm.\nOnly extract relevant information from the text.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value."
},
"schemaType": "fromJson",
"jsonSchemaExample": "{\n \"parcel_number\": \"2538840070\",\n \"owner_name\": \"Gerald Twoshoes\"\n}"
},
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "ab195330-ea1c-4379-8924-d3a5f9bff045",
"name": "Upload legal doc",
"type": "n8n-nodes-base.googleDrive",
"position": [
860,
180
],
"parameters": {
"name": "=Parcel {{ $('Apify Playwright script to find property info').item.json.parcel_number }} legal doc {{ $('Form submitted trigger').item.json.Timestamp.toDateTime().format('yyyy-MM-dd') }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1O_ttveJk1CGM9G_K_DZu0XQplLRg51YzXX7Akm3dT8zkhgrqfpPSdBlvQ6xvkdhWKAntbyFQ",
"cachedResultUrl": "https://drive.google.com/drive/folders/1O_ttveJk1CGM9G_K_DZu0XQplLRg51YzXX7Akm3dT8zkhgrqfpPSdBlvQ6xvkdhWKAntbyFQ",
"cachedResultName": "Legal Automation Input Form (File responses)"
},
"inputDataFieldName": "input_file"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "2ee92d0a-d85a-4d9c-a5ff-351d4522fcee",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-120,
-300
],
"parameters": {
"color": 3,
"width": 720,
"height": 1000,
"content": "## Trigger the workflow\nCall the Apify playwright actor to fetch the document from the site."
},
"typeVersion": 1
},
{
"id": "31b540e9-8a17-4e2c-94af-25b401dcdaad",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
620,
-300
],
"parameters": {
"color": 4,
"width": 620,
"height": 1000,
"content": "## Prepare document for upload \nPrepare to send document for interpretation by AI. Also keep document in storage in Google Drive for posterity."
},
"typeVersion": 1
},
{
"id": "a8159a38-29f4-4ec8-b62d-18d5371db7c8",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1260,
-300
],
"parameters": {
"color": 5,
"width": 1060,
"height": 1000,
"content": "## Process Information Received\nUpdate the intermediate storage sheet and inform user ready for review."
},
"typeVersion": 1
},
{
"id": "aa13bc59-0737-4aad-8892-817173d0cf4b",
"name": "Make Copy of Template",
"type": "n8n-nodes-base.googleDrive",
"position": [
660,
1200
],
"parameters": {
"name": "=Lien for {{ $('Intermediate data received').item.json['Association Name'] }} {{ $('Intermediate data received').item.json.Timestamp.toDateTime().format('yyyy-MM-dd') }}",
"fileId": {
"__rl": true,
"mode": "list",
"value": "1qqP5RzdUy3S_2ZaOeFdREVAdYgmyJh_kMhvN-O6yrXc",
"cachedResultUrl": "TODO",
"cachedResultName": "Lien Template Blank"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"operation": "copy",
"sameFolder": false
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "e747c01e-02a4-4206-b64e-4a3be13e2c82",
"name": "Change Custom Variables",
"type": "n8n-nodes-base.googleDocs",
"position": [
880,
1200
],
"parameters": {
"actionsUi": {
"actionFields": [
{
"text": "{{ASSOCIATION}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json['Association Name'] }}"
},
{
"text": "{{DEBT}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Debt.toLocaleString('en-US', {style: 'currency', currency: 'usd'} ) }}"
},
{
"text": "{{PROPERTY}}",
"action": "replaceAll",
"replaceText": "={{ $('If').item.json['Legal Description'] }}"
},
{
"text": "{{MONTH}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Timestamp.toDateTime().format('MMMM') }}"
},
{
"text": "{{YEAR}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Timestamp.toDateTime().format('yyyy') }}"
},
{
"text": "{{DAY}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Timestamp.toDateTime().format('d') }}"
},
{
"text": "{{PARCEL}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Parcel.toString() }}"
},
{
"text": "{{OWNER}}",
"action": "replaceAll",
"replaceText": "={{ $('Intermediate data received').item.json.Owner }}"
}
]
},
"operation": "update",
"documentURL": "={{ $json.id }}"
},
"credentials": {
"googleDocsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2
},
{
"id": "ff2d35fa-c7e9-40ca-967c-7c5dfbaebaca",
"name": "Generate PDF",
"type": "n8n-nodes-base.googleDrive",
"position": [
1100,
1200
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.documentId }}"
},
"options": {
"binaryPropertyName": "data",
"googleFileConversion": {
"conversion": {
"docsToFormat": "application/pdf",
"sheetsToFormat": "application/pdf",
"slidesToFormat": "application/pdf",
"drawingsToFormat": "image/png"
}
}
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "39aa9470-3058-498e-9f7c-925939e96234",
"name": "Add PDF To Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1320,
1200
],
"parameters": {
"name": "={{ $('Make Copy of Template').item.json.name }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create folder For Output Files').item.json.id }}"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "2028eb46-fbb7-47b0-95ed-48c2992b9aa9",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
220,
1200
],
"parameters": {
"options": {
"ignoreCase": true
},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "33c76535-e2a1-41af-aa12-6719ed98711e",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.Approval }}",
"rightValue": "=Approved"
},
{
"id": "77e646d4-96ed-490e-846e-7d7e4229cee8",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.Created }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "e76afcb8-3539-48d7-abc7-751c30a4ae1f",
"name": "Update Creation",
"type": "n8n-nodes-base.googleSheets",
"position": [
1760,
1200
],
"parameters": {
"columns": {
"value": {
"Created": "={{ $now }}",
"Doc link": "=https://drive.google.com/file/d/{{ $json.id }}/view?usp=drivesdk",
"Timestamp": "={{ $('Intermediate data received').item.json.Timestamp }}"
},
"schema": [
{
"id": "Timestamp",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Legal Description",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Legal Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Association Name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Association Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Debt",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Debt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Parcel",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Parcel",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Owner",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Owner",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Doc link",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Doc link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Approval",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Approval",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Created",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Timestamp"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "TODO",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1J4ToBxAwjY9q8q-wS3E7JzwbT1fBTJ-3X9yfOMWV-uI",
"cachedResultUrl": "TODO",
"cachedResultName": "Automation Output data Sheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "058efad7-2452-4a67-9a45-da95ce7266a1",
"name": "Move file in Google Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1540,
1200
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "url",
"value": "={{ $('Intermediate data received').item.json['Doc link'] }}"
},
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"folderId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Create folder For Output Files').item.json.id }}"
},
"operation": "move"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "0a021c28-991b-4c9e-b2b8-efe10adfda2e",
"name": "Notify complete",
"type": "n8n-nodes-base.gmail",
"position": [
2000,
1200
],
"parameters": {
"sendTo": "=TODO",
"message": "=Check/modify the generated content at TODO and then click \"Approve\" below.\n\n",
"options": {},
"subject": "Inform completion"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "563a5ad4-8230-4e92-bfc1-a4530d4954c0",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
780
],
"parameters": {
"color": 6,
"width": 1740,
"height": 920,
"content": "## Create new version of template document\n"
},
"typeVersion": 1
},
{
"id": "cd871266-4420-482e-bdea-899bda6945eb",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1720,
780
],
"parameters": {
"color": 2,
"width": 460,
"height": 920,
"content": "## Update Tracking of document generation + notify"
},
"typeVersion": 1
},
{
"id": "b9a72a1e-c1fa-40db-b7dd-bed8887cf310",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-380,
-40
],
"parameters": {
"color": 7,
"height": 140,
"content": "PART 1: Gather Info"
},
"typeVersion": 1
},
{
"id": "19e63b99-8f91-4b46-b81c-9d1e933c570b",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-380,
880
],
"parameters": {
"color": 7,
"content": "PART 2: Generate Docs"
},
"typeVersion": 1
},
{
"id": "06e971a1-2000-4d5a-9539-7010a56bf99d",
"name": "Intermediate data received",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
0,
1100
],
"parameters": {
"event": "rowUpdate",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "TODO",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1J4ToBxAwjY9q8q-wS3E7JzwbT1fBTJ-3X9yfOMWV-uI",
"cachedResultUrl": "TODO",
"cachedResultName": "Automation Output Data Sheet"
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "649b7ff0-284d-4bf3-b122-c42dced4d9b0",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1680,
-400
],
"parameters": {
"width": 1240,
"height": 2240,
"content": "# General Description\n\n### Automate Legal Lien Document Generation for HOAs with n8n, Apify, and AI\n\nThis tutorial details an end-to-end automation solution for streamlining the lien filing process for Homeowners Associations (HOAs) using an n8n workflow. It significantly reduces manual effort and potential errors for legal professionals by automating document retrieval, information extraction, and document generation.\n\n#### Who's it for\n\nThis template is ideal for legal professionals, law firms, and property management companies that frequently handle lien filings for Homeowners Associations. If you're looking to reduce manual document processing time, minimize errors, and improve efficiency in your legal operations, this workflow is for you.\n\n#### The Problem\n\nLegal professionals often allocate a significant portion of their time\u2014up to 40%\u2014to manual document processing tasks. The traditional process for filing a lien is particularly time-consuming (e.g., 15 minutes per case) and error-prone, involving steps like manual searching, downloading, extracting, and populating legal documents.\n\n#### The Automation Solution Overview\n\nThis automation leverages an n8n workflow in conjunction with external services like Playwright (via Apify), Google Drive, Google Sheets, Gmail, and the Gemini API. The primary objective is to automate the legal document generation process\u2014from initial data submission to final document generation and notification.\n\n#### Requirements\n\nBefore importing and running the n8n workflow, you need the following:\n\n* **n8n Instance:** A running n8n instance (self-hosted or cloud).\n* **Google Account:** With access to Google Sheets, Google Drive, and Gmail.\n* **Google Sheets:**\n * An **Input Sheet** to receive form responses (e.g., \"Legal Automation Input Form (Responses)\").\n * An **Output/Review Sheet** for extracted data and approval (e.g., \"Automation Output data Sheet\") with specific columns like \"Timestamp\", \"Legal Description\", \"Association Name\", \"Debt\", \"Parcel\", \"Owner\", \"Doc link\", \"Approval\", and \"Created\".\n* **Google Drive:**\n * A main folder for n8n outputs (e.g., \"N8N Folder\").\n * A Google Docs **Lien Template** with placeholders (e.g., `{{ASSOCIATION}}`, `{{DEBT}}`, `{{PROPERTY}}`, `{{MONTH}}`, `{{YEAR}}`, `{{DAY}}`, `{{PARCEL}}`, `{{OWNER}}`).\n* **Google Gemini API Key:** For text and image processing.\n* **Apify Account & Playwright Actor:** An Apify account with access to a Playwright actor capable of scraping property information from your target county's website.\n\n#### Setup Steps\n\n1. **n8n Credentials:**\n * Add Google Sheets, Google Drive, and Gmail credentials in your n8n instance.\n * Add an `HTTP Query Auth` credential for your Gemini API key (named \"Query Auth account\" in the template).\n * Ensure your Apify API token is configured within the `Apify Playwright script to find property info` node.\n2. **Google Sheets Configuration:**\n * Link the `Google Sheets Trigger` node to your **Input Sheet**.\n * Link the `Google Sheets` node (for appending data) and the `Intermediate data received` trigger to your **Output/Review Sheet**.\n3. **Google Drive Configuration:**\n * Update the `Create folder to output` node with the ID of your \"N8N Folder\".\n * Update the `Make Copy of Template` node with the ID of your Google Docs Lien Template.\n4. **Email Addresses:**\n * Update the recipient email addresses in the `Approve Through Email` and `Notify complete` nodes to your desired notification email.\n\n#### Detailed Tutorial Steps and n8n Workflow Breakdown Summary\n\nThis n8n workflow, \"Legal Document Generator E2E\", automates the process of generating legal lien documents, from initial data input to final document creation and notification.\n\n1. **Initiate Workflow:** The workflow starts with a `Google Sheets Trigger` node, which listens for new lien requests submitted via a form that populates a Google Sheet.\n2. **Gather Property Data:** An `Apify Playwright script to find property info` node fetches property details from county websites, and a `Get file for property` node downloads associated legal documents.\n3. **Process and Store Document:** The downloaded document is transformed to base64 using `Transform to base64` and then uploaded to Google Drive via `Upload legal doc` for storage and further processing.\n4. **Extract Information with AI:** `Call Gemini API for legal desc` and `Property metadata` nodes leverage the Gemini API to extract the precise legal description, parcel number, and owner's name from the document. This extracted data is then structured by the `Property Information Extractor`.\n5. **Review and Approve:** The extracted information is appended to an intermediate Google Sheet by the first `Google Sheets` node, and an email is sent via `Approve Through Email` to the user for review and approval.\n6. **Generate Documents on Approval:** A second `Intermediate data received` `Google Sheets Trigger` node monitors the approval status in the sheet. Once \"Approved\", an `If` node allows the workflow to proceed.\n7. **Create and Populate Documents:** A new client-specific folder is created in Google Drive using `Create folder to output`. A blank lien template is copied (`Make Copy of Template`), and its custom variables are populated with the extracted data using `Change Custom Variables`.\n8. **Finalize and Store Output:** The populated document is converted to PDF (`Generate PDF`), and both the new PDF (`Add PDF To Drive`) and the original source document (`Move file in Google Drive`) are saved to the client's new folder.\n9. **Update Records and Notify:** The `Update Creation` `Google Sheets` node marks the document as \"Created\" in the tracking sheet and updates the document link. Finally, `Notify complete` sends a notification email about the completion.\n\n#### How to Customize the Workflow\n\n* **Adjust Input Form Fields:** Modify the column names in your initial Google Sheet and update the expressions in the `Google Sheets Trigger` and `Apify Playwright script to find property info` nodes to match your form.\n* **Change County Website/Scraper:** If you need to fetch data from a different county or property database, you will need to modify the `Apify Playwright script to find property info` node to call a different Apify actor or configure a new HTTP Request node to interact with your chosen data source.\n* **Customize Document Template:** Update the placeholders in your Google Docs Lien Template to match your specific document needs. Ensure corresponding `replaceAll` actions are updated in the `Change Custom Variables` node.\n* **Modify AI Prompts:** Refine the prompts within the `Call Gemini API for legal desc` and `Property metadata` nodes to improve the accuracy of information extraction based on your document types.\n* **Notification Preferences:** Adjust the `sendTo` email addresses and `subject`/`message` content in the `Approve Through Email` and `Notify complete` nodes.\n\n#### Benefits of this Automation\n\nThis automation offers significant advantages for legal professionals:\n\n* **Streamlined Organization:** Ensures all relevant documents\u2014original source files, editable templates, and final PDFs\u2014are systematically organized, tracked, and easily accessible within Google Drive.\n* **Time-Saving and Efficiency:** Documents are quickly generated and ready for client sharing, leading to faster turnaround times and improved service delivery.\n* **Scalability:** Provides a scalable solution for handling a higher volume of document processing tasks without a proportional increase in manual effort.\n\n---\nLearn more about Chill Labs and our services on our website: [Chill Labs](https://www.chillaborate.com/)"
},
"typeVersion": 1
},
{
"id": "32d2c4b8-dcf4-4ecc-8208-910f3bc1e876",
"name": "Add Intermediate Info to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
1900,
180
],
"parameters": {
"columns": {
"value": {
"Debt": "={{ $('Form submitted trigger').item.json.Debt }}",
"Owner": "={{ $('Property Information Extractor').item.json.output.owner_name }}",
"Parcel": "={{ $('Property Information Extractor').item.json.output.parcel_number }}",
"Doc link": "={{ $('Upload legal doc').item.json.webViewLink }}",
"Timestamp": "={{ $now }}",
"Association Name": "={{ $('Form submitted trigger').item.json['Association Name'] }}",
"Legal Description": "={{ $('Call Gemini API for legal desc').item.json.candidates[0].content.parts[0].text }}"
},
"schema": [
{
"id": "Timestamp",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Timestamp",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Legal Description",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Legal Description",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Association Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Association Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Debt",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Debt",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Parcel",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Parcel",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Owner",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Owner",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Doc link",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Doc link",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Approval",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Approval",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Created",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Field"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "TODO",
"cachedResultName": "Sheet1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1J4ToBxAwjY9q8q-wS3E7JzwbT1fBTJ-3X9yfOMWV-uI",
"cachedResultUrl": "TODO",
"cachedResultName": "Automation Output data Sheet"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "758aaab8-ef6e-41b9-b86b-0ae4d2ea1864",
"name": "Create folder For Output Files",
"type": "n8n-nodes-base.googleDrive",
"position": [
440,
1200
],
"parameters": {
"name": "={{ $('Intermediate data received').item.json['Association Name'] }} Documents ",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "16kgM-BAk0K1eMCSej17JQ24YNvNWc1qH",
"cachedResultUrl": "https://drive.google.com/drive/folders/16kgM-BAk0K1eMCSej17JQ24YNvNWc1qH",
"cachedResultName": "N8N Folder"
},
"resource": "folder"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "c6e8c61d-ed3e-4bc7-a981-0ddb24de8bed",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
240,
0
],
"parameters": {
"color": 7,
"height": 100,
"content": "Set up:\n1. Intermediate Google Sheet\n2. Email to send notifications to"
},
"typeVersion": 1
},
{
"id": "76632705-5c9a-4a8a-acb6-fdcac218df20",
"name": "Form submitted trigger",
"type": "n8n-nodes-base.googleSheetsTrigger",
"position": [
-20,
260
],
"parameters": {
"event": "rowAdded",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1974496121,
"cachedResultUrl": "TODO",
"cachedResultName": "Form Responses 1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1hYq1pG_GhyfAwQhHhDGlQRisCOOMqnpV3fG4q3xlU_8",
"cachedResultUrl": "TODO",
"cachedResultName": "Legal Automation Input Form (Responses)"
}
},
"credentials": {
"googleSheetsTriggerOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2bcc9e8a-b609-4e2f-99c4-43b3cafb8609",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
420,
960
],
"parameters": {
"color": 7,
"height": 200,
"content": "Set up:\n1. Intermediate Google Sheet\n2. Template Google Doc for the legal document\n3. Drive Folder for Output\n4. Email to send notifications to"
},
"typeVersion": 1
},
{
"id": "44138f44-bcb2-4b99-978b-567e5bda68a3",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-40,
-40
],
"parameters": {
"color": 7,
"width": 220,
"height": 100,
"content": "Set up:\nSpreadsheet with form responses"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "UitqjHCH9sfLIduq",
"executionOrder": "v1"
},
"versionId": "b188a7f8-ffb9-44f9-9380-f26412ed2b0a",
"connections": {
"If": {
"main": [
[
{
"node": "Create folder For Output Files",
"type": "main",
"index": 0
}
]
]
},
"Generate PDF": {
"main": [
[
{
"node": "Add PDF To Drive",
"type": "main",
"index": 0
}
]
]
},
"Update Creation": {
"main": [
[
{
"node": "Notify complete",
"type": "main",
"index": 0
}
]
]
},
"Add PDF To Drive": {
"main": [
[
{
"node": "Move file in Google Drive",
"type": "main",
"index": 0
}
]
]
},
"Upload legal doc": {
"main": [
[
{
"node": "Call Gemini API for legal desc",
"type": "main",
"index": 0
}
]
]
},
"Property metadata": {
"main": [
[
{
"node": "Property Information Extractor",
"type": "main",
"index": 0
}
]
]
},
"Transform to base64": {
"main": [
[
{
"node": "Upload legal doc",
"type": "main",
"index": 0
}
]
]
},
"Get file for property": {
"main": [
[
{
"node": "Transform to base64",
"type": "main",
"index": 0
}
]
]
},
"Make Copy of Template": {
"main": [
[
{
"node": "Change Custom Variables",
"type": "main",
"index": 0
}
]
]
},
"Form submitted trigger": {
"main": [
[
{
"node": "Apify Playwright script to find property info",
"type": "main",
"index": 0
}
]
]
},
"Change Custom Variables": {
"main": [
[
{
"node": "Generate PDF",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model1": {
"ai_languageModel": [
[
{
"node": "Property Information Extractor",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Move file in Google Drive": {
"main": [
[
{
"node": "Update Creation",
"type": "main",
"index": 0
}
]
]
},
"Intermediate data received": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"Call Gemini API for legal desc": {
"main": [
[
{
"node": "Property metadata",
"type": "main",
"index": 0
}
]
]
},
"Create folder For Output Files": {
"main": [
[
{
"node": "Make Copy of Template",
"type": "main",
"index": 0
}
]
]
},
"Property Information Extractor": {
"main": [
[
{
"node": "Add Intermediate Info to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Add Intermediate Info to Google Sheets": {
"main": [
[
{
"node": "Approve Through Email",
"type": "main",
"index": 0
}
]
]
},
"Apify Playwright script to find property info": {
"main": [
[
{
"node": "Get file for property",
"type": "main",
"index": 0
}
],
[
{
"node": "Playwright error inform",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDocsOAuth2ApigoogleDriveOAuth2ApigooglePalmApigoogleSheetsOAuth2ApigoogleSheetsTriggerOAuth2ApihttpQueryAuthoAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This tutorial details an end-to-end automation solution for streamlining the lien filing process for Homeowners Associations (HOAs) using an n8n workflow. It significantly reduces manual effort and potential errors for legal professionals by automating document retrieval,…
Source: https://n8n.io/workflows/5801/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
📚 Learners and educators who want a fast overview of a creator’s entire catalog. 🧩 Research, SEO, and content ops teams building an intelligence layer on top of YouTube channels.
A customized n8n workflow inspired by the Lead Generation Agent template. It automates B2B lead scraping via Apify, extracts contact emails with AI, sends cold emails via Gmail, and logs every interac
Automate Sales Meeting Prep With Ai & Apify Sent To Whatsapp. Uses gmail, googleCalendar, lmChatOpenAi, informationExtractor. Event-driven trigger; 61 nodes.
This n8n template builds a meeting assistant that compiles timely reminders of upcoming meetings filled with email history and recent LinkedIn activity of other people on the invite. This is then disc
End-to-end lead pipeline (discovery → enrichment → outreach) Google Search–based LinkedIn discovery (safe approach) Batch processing with controlled loops AI-generated cold emails and follow-ups Googl