This workflow follows the Google Sheets → HTTP Request 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 →
{
"name": "WF_UNIFIED_LEGAL_AUTOMATION",
"nodes": [
{
"parameters": {
"path": "case/create",
"httpMethod": "POST",
"responseMode": "responseNode"
},
"name": "CASE_CREATE_AND_FOLDERS :: Webhook Case Create",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
220,
300
]
},
{
"parameters": {
"operation": "read",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0434\u0435\u043b\u0430!A:G"
},
"name": "CASE_CREATE_AND_FOLDERS :: GS Read Cases",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
460,
300
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const raw = $items('Webhook Case Create')[0].json;\nconst body = (raw && typeof raw.body === 'object' && raw.body !== null) ? raw.body : raw;\nconst rows = items.map(i => i.json);\nconst code = String(body.case_code || '').trim();\nconst exists = rows.some(r => String(r['\u043a\u043e\u0434_\u0434\u0435\u043b\u0430'] || '').trim() === code);\nreturn [{ ...body, case_code: code, exists }];"
},
"name": "CASE_CREATE_AND_FOLDERS :: Check Case Code",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
300
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.exists}}",
"value2": true
}
]
}
},
"name": "CASE_CREATE_AND_FOLDERS :: IF Exists",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
920,
300
]
},
{
"parameters": {
"respondWith": "json",
"responseCode": 409,
"responseBody": "={\"error\":\"case_code already exists\"}"
},
"name": "CASE_CREATE_AND_FOLDERS :: Respond 409",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1140,
200
]
},
{
"parameters": {
"jsCode": "const code = $json.case_code; return [{...$json, incoming:`/Cases/${code}/01_Incoming`, outgoing:`/Cases/${code}/02_Outgoing`, evidence:`/Cases/${code}/03_Evidence`, created_at:new Date().toISOString()}];"
},
"name": "CASE_CREATE_AND_FOLDERS :: Build Paths",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1140,
380
]
},
{
"parameters": {
"url": "=http://158.160.191.139/remote.php/dav/files/Vardkes{{$json.incoming}}",
"method": "MKCOL"
},
"name": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Incoming",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1360,
320
],
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=http://158.160.191.139/remote.php/dav/files/Vardkes{{$json.outgoing}}",
"method": "MKCOL"
},
"name": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Outgoing",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1560,
320
],
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=http://158.160.191.139/remote.php/dav/files/Vardkes{{$json.evidence}}",
"method": "MKCOL"
},
"name": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Evidence",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1760,
320
],
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0434\u0435\u043b\u0430!A:G",
"columns": {
"mappingMode": "defineBelow",
"value": {
"\u043a\u043e\u0434_\u0434\u0435\u043b\u0430": "={{$json.case_code}}",
"\u043a\u043b\u0438\u0435\u043d\u0442_id": "={{$json.client_ref || \"\"}}",
"\u044e\u0440\u0438\u0441\u0442_id": "={{$json.lawyer_ref || \"\"}}",
"\u0442\u0438\u043f_\u0434\u0435\u043b\u0430": "={{$json.case_type || \"\"}}",
"\u044e\u0440\u0438\u0441\u0434\u0438\u043a\u0446\u0438\u044f": "={{$json.jurisdiction || \"\"}}",
"\u0441\u0442\u0430\u0442\u0443\u0441": "={{$json.status || \"new\"}}",
"\u0441\u043e\u0437\u0434\u0430\u043d\u043e_\u0432": "={{$json.created_at}}"
}
}
},
"name": "CASE_CREATE_AND_FOLDERS :: GS Append Case",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1960,
260
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043f\u0430\u043f\u043a\u0438_\u0434\u0435\u043b!A:E",
"columns": {
"mappingMode": "defineBelow",
"value": {
"\u043a\u043e\u0434_\u0434\u0435\u043b\u0430": "={{$json.case_code}}",
"\u043f\u0443\u0442\u044c_\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435": "={{$json.incoming}}",
"\u043f\u0443\u0442\u044c_\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435": "={{$json.outgoing}}",
"\u043f\u0443\u0442\u044c_\u0434\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0430": "={{$json.evidence}}",
"\u0441\u043e\u0437\u0434\u0430\u043d\u043e_\u0432": "={{$json.created_at}}"
}
}
},
"name": "CASE_CREATE_AND_FOLDERS :: GS Append Folders",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
2160,
260
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "json",
"responseCode": 201,
"responseBody": "={\"status\":\"created\",\"case_code\":$json.case_code}"
},
"name": "CASE_CREATE_AND_FOLDERS :: Respond 201",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
2360,
260
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$env.YC_METADATA_MIRROR === '1' && !!$env.YC_METADATA_API_URL}}",
"value2": true
}
]
}
},
"name": "CASE_CREATE_AND_FOLDERS :: IF YC Mirror Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2380,
400
]
},
{
"parameters": {
"url": "={{$env.YC_METADATA_API_URL + '/cases/upsert'}}",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { case_code: $json.case_code, client_ref: $json.client_ref, lawyer_ref: $json.lawyer_ref, case_type: $json.case_type, jurisdiction: $json.jurisdiction, status: $json.status || 'new', incoming_path: $json.incoming, outgoing_path: $json.outgoing, evidence_path: $json.evidence, created_at: $json.created_at } }}"
},
"name": "CASE_CREATE_AND_FOLDERS :: YC Mirror Case Upsert",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
2600,
360
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"path": "case/event/create",
"httpMethod": "POST",
"responseMode": "responseNode"
},
"name": "CASE_EVENT_CREATE :: Webhook Event",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
220,
1090
]
},
{
"parameters": {
"jsCode": "const raw = $json || {};\nconst b = (raw && typeof raw.body === 'object' && raw.body !== null) ? raw.body : raw;\nconst event_id = String(Date.now());\nconst event_type = b.event_type || 'court_hearing';\nconst timezone = b.timezone || 'Europe/Moscow';\nconst event_date = b.event_date || null;\nconst start_time = b.start_time || null;\nconst end_time = b.end_time || null;\nconst start_at = b.start_at || (event_date && start_time ? `${event_date}T${start_time}:00+03:00` : null);\nconst end_at = b.end_at || (event_date && end_time ? `${event_date}T${end_time}:00+03:00` : null);\nif (!start_at || !end_at) {\n throw new Error('\u0414\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043d\u0443\u0436\u043d\u044b start_at \u0438 end_at (\u0438\u043b\u0438 event_date + start_time + end_time).');\n}\nreturn [{\n ...b,\n event_type,\n event_id,\n timezone,\n event_date,\n start_time,\n end_time,\n start_at,\n end_at,\n reminder_24h: b.reminder_24h !== false,\n reminder_2h: b.reminder_2h !== false,\n reminder_30m: b.reminder_30m === true,\n custom_reminder_minutes: Number(b.custom_reminder_minutes || 0) || 0,\n created_at: new Date().toISOString()\n}];"
},
"name": "CASE_EVENT_CREATE :: Prepare",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
1090
]
},
{
"parameters": {
"url": "=https://caldav.yandex.ru/calendars/astrarav%40yandex.ru/events-36560758/{{$json.event_id}}.ics",
"method": "PUT",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "text/calendar; charset=utf-8"
}
]
},
"sendBody": true,
"specifyBody": "string",
"body": "=BEGIN:VCALENDAR\\nVERSION:2.0\\nPRODID:-//n8n//Legal Workflow//RU\\nBEGIN:VEVENT\\nUID:{{$json.event_id}}\\nDTSTAMP:{{$now.toFormat(\"yyyyMMdd'T'HHmmss'Z'\")}}\\nSUMMARY:[{{$json.case_code}}] {{$json.event_type}}\\nDTSTART:{{DateTime.fromISO($json.start_at).toUTC().toFormat(\"yyyyMMdd'T'HHmmss'Z'\")}}\\nDTEND:{{DateTime.fromISO($json.end_at).toUTC().toFormat(\"yyyyMMdd'T'HHmmss'Z'\")}}\\nEND:VEVENT\\nEND:VCALENDAR"
},
"name": "CASE_EVENT_CREATE :: Calendar Create",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
700,
1090
],
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0441\u043e\u0431\u044b\u0442\u0438\u044f_\u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044f!A:G",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.event_id}}",
"\u043a\u043e\u0434_\u0434\u0435\u043b\u0430": "={{$json.case_code}}",
"\u0442\u0438\u043f_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.event_type}}",
"\u043d\u0430\u0447\u0430\u043b\u043e": "={{$json.start_at}}",
"\u043a\u043e\u043d\u0435\u0446": "={{$json.end_at}}",
"\u0432\u043d\u0435\u0448\u043d\u0438\u0439_id_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.id}}",
"\u0441\u043e\u0437\u0434\u0430\u043d\u043e_\u0432": "={{$json.created_at}}"
}
}
},
"name": "CASE_EVENT_CREATE :: GS Append Event",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
940,
1090
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f!A:H",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f": "={{$json.event_id + \"-24h\"}}",
"id_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.event_id}}",
"\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f": "lawyer",
"telegram_chat_id": "={{$json.lawyer_chat_id}}",
"\u0442\u0435\u043a\u0441\u0442_\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f": "={{\"\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e \u0434\u0435\u043b\u0443 \" + $json.case_code + \" \u0447\u0435\u0440\u0435\u0437 24 \u0447\u0430\u0441\u0430.\"}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c_\u0432": "={{DateTime.fromISO($json.start_at).minus({hours:24}).toISO()}}",
"\u0441\u0442\u0430\u0442\u0443\u0441": "={{$json.reminder_24h === false ? 'cancelled' : 'pending'}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e_\u0432": ""
}
}
},
"name": "CASE_EVENT_CREATE :: GS Append Reminder 24h",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1180,
1050
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f!A:H",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f": "={{$json.event_id + \"-2h\"}}",
"id_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.event_id}}",
"\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f": "lawyer",
"telegram_chat_id": "={{$json.lawyer_chat_id}}",
"\u0442\u0435\u043a\u0441\u0442_\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f": "={{\"\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e \u0434\u0435\u043b\u0443 \" + $json.case_code + \" \u0447\u0435\u0440\u0435\u0437 2 \u0447\u0430\u0441\u0430.\"}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c_\u0432": "={{DateTime.fromISO($json.start_at).minus({hours:2}).toISO()}}",
"\u0441\u0442\u0430\u0442\u0443\u0441": "={{$json.reminder_2h === false ? 'cancelled' : 'pending'}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e_\u0432": ""
}
}
},
"name": "CASE_EVENT_CREATE :: GS Append Reminder 2h",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1400,
1050
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "json",
"responseCode": 201,
"responseBody": "={\"status\":\"created\",\"event_id\":$json.event_id}"
},
"name": "CASE_EVENT_CREATE :: Respond 201",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1620,
1090
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{Boolean(($json.client_chat_id && $json.payment_due_at) || $json.reminder_30m === true || Number($json.custom_reminder_minutes || 0) > 0)}}",
"value2": true
}
]
}
},
"name": "CASE_EVENT_CREATE :: IF Client Payment Reminder",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1620,
1170
]
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f!A:H",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f": "={{$json.payment_due_at ? ($json.event_id + '-payment') : (Number($json.custom_reminder_minutes || 0) > 0 ? ($json.event_id + '-custom') : ($json.event_id + '-30m'))}}",
"id_\u0441\u043e\u0431\u044b\u0442\u0438\u044f": "={{$json.event_id}}",
"\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f": "={{$json.payment_due_at ? 'client' : 'lawyer'}}",
"telegram_chat_id": "={{$json.payment_due_at ? $json.client_chat_id : $json.lawyer_chat_id}}",
"\u0442\u0435\u043a\u0441\u0442_\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f": "={{$json.payment_due_at ? ('\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u043e\u0431 \u043e\u043f\u043b\u0430\u0442\u0435 \u043f\u043e \u0434\u0435\u043b\u0443 ' + $json.case_code + ($json.payment_amount ? ('. \u0421\u0443\u043c\u043c\u0430: ' + $json.payment_amount) : '')) : ('\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435: \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043f\u043e \u0434\u0435\u043b\u0443 ' + $json.case_code + (Number($json.custom_reminder_minutes || 0) > 0 ? (' \u0447\u0435\u0440\u0435\u0437 ' + Number($json.custom_reminder_minutes || 0) + ' \u043c\u0438\u043d\u0443\u0442.') : ' \u0447\u0435\u0440\u0435\u0437 30 \u043c\u0438\u043d\u0443\u0442.'))}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c_\u0432": "={{$json.payment_due_at ? $json.payment_due_at : DateTime.fromISO($json.start_at).minus({minutes: Number($json.custom_reminder_minutes || 30)}).toISO()}}",
"\u0441\u0442\u0430\u0442\u0443\u0441": "={{$json.payment_due_at ? 'pending' : (($json.reminder_30m === true || Number($json.custom_reminder_minutes || 0) > 0) ? 'pending' : 'cancelled')}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e_\u0432": ""
}
}
},
"name": "CASE_EVENT_CREATE :: GS Append Client Payment Reminder",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1840,
1170
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$env.YC_METADATA_MIRROR === '1' && !!$env.YC_METADATA_API_URL}}",
"value2": true
}
]
}
},
"name": "CASE_EVENT_CREATE :: IF YC Mirror Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2060,
1090
]
},
{
"parameters": {
"url": "={{$env.YC_METADATA_API_URL + '/events/upsert'}}",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { event_id: $json.event_id, case_code: $json.case_code, event_type: $json.event_type, start_at: $json.start_at, end_at: $json.end_at, timezone: $json.timezone, lawyer_chat_id: $json.lawyer_chat_id, client_chat_id: $json.client_chat_id || null, payment_due_at: $json.payment_due_at || null, payment_amount: $json.payment_amount || null, created_at: $json.created_at } }}"
},
"name": "CASE_EVENT_CREATE :: YC Mirror Event Upsert",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
2280,
1070
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
},
"name": "REMINDER_DISPATCH_CRON :: Cron",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
220,
1920
]
},
{
"parameters": {
"operation": "read",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f!A:H"
},
"name": "REMINDER_DISPATCH_CRON :: GS Read Reminders",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
460,
1920
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "read",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0436\u0443\u0440\u043d\u0430\u043b_\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439!A:D"
},
"name": "REMINDER_DISPATCH_CRON :: GS Read Sent Log",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
700,
1920
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const reminders = $items('GS Read Reminders').map(i => i.json);\nconst sentIds = new Set(items.map(i => i.json['id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f']).filter(Boolean));\nconst now = new Date();\nreturn reminders.filter(r => r['\u0441\u0442\u0430\u0442\u0443\u0441'] === 'pending' && new Date(r['\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c_\u0432']) <= now && !sentIds.has(r['id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f'])).map(r => ({ json: r }));"
},
"name": "REMINDER_DISPATCH_CRON :: Filter Due",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
940,
1920
]
},
{
"parameters": {
"batchSize": 1
},
"name": "REMINDER_DISPATCH_CRON :: Split",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
1160,
1920
]
},
{
"parameters": {
"chatId": "={{$json['telegram_chat_id']}}",
"text": "={{$json['\u0442\u0435\u043a\u0441\u0442_\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f'] || ($json['\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f'] === 'client' ? '\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0434\u0435\u043b\u0443.' : '\u041d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0435 \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044e.')}}"
},
"name": "REMINDER_DISPATCH_CRON :: TG Send",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1380,
1920
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0436\u0443\u0440\u043d\u0430\u043b_\u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439!A:D",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f": "={{$json[\"id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f\"]}}",
"\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e_\u0432": "={{$now}}",
"\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f": "={{$json[\"\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f\"]}}",
"\u0441\u0442\u0430\u0442\u0443\u0441": "sent"
}
}
},
"name": "REMINDER_DISPATCH_CRON :: GS Sent Log",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1600,
1920
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$env.YC_METADATA_MIRROR === '1' && !!$env.YC_METADATA_API_URL}}",
"value2": true
}
]
}
},
"name": "REMINDER_DISPATCH_CRON :: IF YC Mirror Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1820,
1920
]
},
{
"parameters": {
"url": "={{$env.YC_METADATA_API_URL + '/reminders/sent'}}",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { reminder_id: $json['id_\u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u044f'], recipient_role: $json['\u0440\u043e\u043b\u044c_\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u044f'], sent_at: String($now), status: 'sent' } }}"
},
"name": "REMINDER_DISPATCH_CRON :: YC Mirror Reminder Sent",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
2040,
1900
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"updates": [
"message",
"callback_query"
]
},
"name": "TELEGRAM_DOCUMENT_INGEST :: Telegram Trigger",
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1,
"position": [
220,
2870
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const m = $json.message || {};\nconst metaText = [m.caption, m.text].filter(Boolean).join(' ');\nconst caseMatch = metaText.match(/[\u0410A]\\d{2}-\\d+\\/\\d{4}|C-\\d{4}-\\d{3}|\\b\\d{4,}\\b/i);\nconst case_code = caseMatch ? caseMatch[0].toUpperCase() : null;\nconst photo = m.photo?.length ? m.photo[m.photo.length - 1] : null;\nconst document = m.document || null;\nconst file_id = document?.file_id || photo?.file_id || null;\nconst extRaw = (document?.file_name || '').split('.').pop()?.toLowerCase();\nconst ext = photo ? 'jpg' : (extRaw || null);\nconst mime = document?.mime_type || (photo ? 'image/jpeg' : null);\nconst allowed = new Set(['jpg','jpeg','png','pdf','doc','docx','txt']);\nif (!file_id) {\n return [{ invalid: true, notFound: true, error_text: '\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0444\u0430\u0439\u043b. \u041e\u0442\u043f\u0440\u0430\u0432\u044c\u0442\u0435 \u0444\u043e\u0442\u043e \u0438\u043b\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 (PDF/DOCX/TXT).', chat_id: m.chat?.id }];\n}\nif (!case_code) {\n return [{ invalid: true, notFound: true, error_text: '\u041d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u043d\u043e\u043c\u0435\u0440 \u0434\u0435\u043b\u0430. \u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u0435\u0433\u043e \u0432 \u043f\u043e\u0434\u043f\u0438\u0441\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: A40-12345/2026.', chat_id: m.chat?.id }];\n}\nif (ext && !allowed.has(ext)) {\n return [{ invalid: true, notFound: true, error_text: `\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0442\u0438\u043f \u0444\u0430\u0439\u043b\u0430: .${ext}. \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e: jpg, jpeg, png, pdf, doc, docx, txt.`, chat_id: m.chat?.id }];\n}\nreturn [{\n invalid: false,\n case_code,\n from_id: m.from?.id || null,\n chat_id: m.chat?.id || null,\n file_id,\n detected_ext: ext,\n mime_hint: mime\n}];"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: Parse",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
2870
]
},
{
"parameters": {
"operation": "read",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u043f\u0430\u043f\u043a\u0438_\u0434\u0435\u043b!A:E"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: GS Read Folders",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
700,
2870
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const input = $items('Parse')[0].json;\nif (input.invalid) return [input];\nconst row = items.map(i => i.json).find(r => String(r['\u043a\u043e\u0434_\u0434\u0435\u043b\u0430']) === String(input.case_code));\nif (!row) {\n return [{ ...input, notFound: true, error_text: `\u0414\u0435\u043b\u043e ${input.case_code} \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043d\u043e\u043c\u0435\u0440.` }];\n}\nreturn [{ ...input, folder_path: row['\u043f\u0443\u0442\u044c_\u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435'], notFound: false }];"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: Match Case",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
940,
2870
]
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$json.notFound}}",
"value2": true
}
]
}
},
"name": "TELEGRAM_DOCUMENT_INGEST :: IF Case Missing",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1160,
2870
]
},
{
"parameters": {
"chatId": "={{$json.chat_id}}",
"text": "={{$json.error_text || '\u041a\u043e\u0434 \u0434\u0435\u043b\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044c: C-2025-001'}}"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: TG Case Not Found",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1380,
2750
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=https://api.telegram.org/bot{{$credentials.telegramApi.accessToken}}/getFile?file_id={{$json.file_id}}",
"method": "GET"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: TG getFile",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1380,
2950
]
},
{
"parameters": {
"url": "=https://api.telegram.org/file/bot{{$credentials.telegramApi.accessToken}}/{{$json.result.file_path}}",
"method": "GET",
"responseFormat": "file",
"binaryPropertyName": "data"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: TG Download",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1600,
2950
]
},
{
"parameters": {
"jsCode": "const ext = ($json.detected_ext || $binary.data.fileExtension || 'bin').toLowerCase();\nconst ts = new Date().toISOString().replace(/[-:]/g,'').slice(0,15);\nconst rnd = Math.random().toString(36).slice(2,8);\nreturn [{...$json, stored_filename:`DOC_${$json.case_code}_${ts}_${rnd}.${ext}`}];"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: Safe Filename",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1820,
2950
]
},
{
"parameters": {
"url": "=http://158.160.191.139/remote.php/dav/files/Vardkes{{$json.folder_path}}/{{$json.stored_filename}}",
"method": "PUT",
"sendBinaryData": true,
"binaryPropertyName": "data"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: DAV Upload",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
2040,
2950
],
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "append",
"sheetId": "={{$env.GSHEET_ID}}",
"range": "\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b!A:H",
"columns": {
"mappingMode": "defineBelow",
"value": {
"id_\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430": "={{$now.toMillis()}}",
"\u043a\u043e\u0434_\u0434\u0435\u043b\u0430": "={{$json.case_code}}",
"telegram_id_\u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044f": "={{$json.from_id}}",
"\u0438\u043c\u044f_\u0444\u0430\u0439\u043b\u0430_\u0432_\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435": "={{$json.stored_filename}}",
"\u043f\u0443\u0442\u044c_\u0432_\u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435": "={{$json.folder_path + \"/\" + $json.stored_filename}}",
"mime_\u0442\u0438\u043f": "={{$binary.data.mimeType}}",
"\u0440\u0430\u0437\u043c\u0435\u0440_\u0431\u0430\u0439\u0442": "={{$binary.data.fileSize}}",
"\u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043e_\u0432": "={{$now}}"
}
}
},
"name": "TELEGRAM_DOCUMENT_INGEST :: GS Append Document",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
2260,
2950
],
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{$json.chat_id}}",
"text": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u0434\u0435\u043b\u0443."
},
"name": "TELEGRAM_DOCUMENT_INGEST :: TG Ack",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
2480,
2950
],
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{$env.YC_METADATA_MIRROR === '1' && !!$env.YC_METADATA_API_URL}}",
"value2": true
}
]
}
},
"name": "TELEGRAM_DOCUMENT_INGEST :: IF YC Mirror Enabled",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2480,
2950
]
},
{
"parameters": {
"url": "={{$env.YC_METADATA_API_URL + '/documents/upsert'}}",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { doc_id: String($now.toMillis()), case_code: $json.case_code, uploaded_by_telegram_id: String($json.from_id || ''), stored_filename: $json.stored_filename, storage_path: $json.folder_path + '/' + $json.stored_filename, mime_type: $binary.data.mimeType, size_bytes: $binary.data.fileSize, uploaded_at: String($now) } }}"
},
"name": "TELEGRAM_DOCUMENT_INGEST :: YC Mirror Document Upsert",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
2700,
2910
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
},
"continueOnFail": true
},
{
"parameters": {
"path": "ai/legal/consult",
"httpMethod": "POST",
"responseMode": "responseNode",
"options": {
"binaryData": true
}
},
"name": "AI_LEGAL :: Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
260
]
},
{
"parameters": {
"jsCode": "const raw = $json || {};\nconst b = (raw && typeof raw.body === 'object' && raw.body !== null) ? raw.body : raw;\nconst binary = $binary || {};\n\nlet extractedFromFile = '';\nif (binary.file?.data) {\n const mime = binary.file.mimeType || '';\n const fileName = binary.file.fileName || 'uploaded_file';\n if (mime.startsWith('text/')) {\n extractedFromFile = Buffer.from(binary.file.data, 'base64').toString('utf8');\n } else {\n extractedFromFile = `[\u0424\u0430\u0439\u043b '${fileName}' (${mime || 'unknown mime'}) \u043f\u043e\u043b\u0443\u0447\u0435\u043d, \u043d\u043e \u0430\u0432\u0442\u043e\u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043e. \u041f\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 text/document_text \u0438\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 OCR/\u043f\u0430\u0440\u0441\u0435\u0440 \u0432 workflow.]`;\n }\n}\n\nconst documentText = String(b.document_text || b.text || b.case_text || extractedFromFile || '').trim();\nif (!documentText) {\n throw new Error('\u041f\u0435\u0440\u0435\u0434\u0430\u0439\u0442\u0435 \u0442\u0435\u043a\u0441\u0442 \u0434\u0435\u043b\u0430 \u0432 body.document_text / body.text / body.case_text \u0438\u043b\u0438 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 binary.file');\n}\n\nreturn [{\n case_code: b.case_code || null,\n jurisdiction: b.jurisdiction || '\u0420\u043e\u0441\u0441\u0438\u044f',\n document_text: documentText\n}];"
},
"name": "AI_LEGAL :: Prepare Input",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
500,
260
]
},
{
"parameters": {
"url": "={{$env.LEGAL_AI_API_URL || 'https://api.openai.com/v1/chat/completions'}}",
"method": "POST",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ { model: $env.LEGAL_AI_MODEL || 'gpt-4o-mini', temperature: 0.2, response_format: { type: 'json_object' }, messages: [ { role: 'system', content: '\u0422\u044b \u2014 \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0439 AI-\u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u044e\u0440\u0438\u0441\u0442\u043e\u0432 \u0438 \u0430\u0434\u0432\u043e\u043a\u0430\u0442\u043e\u0432. \u0420\u043e\u043b\u044c: \u0441\u0442\u0430\u0440\u0448\u0438\u0439 \u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0430\u043d\u0442 \u0441 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u0438\u0437\u043e\u0439 20+ \u043b\u0435\u0442 \u043f\u043e \u043f\u0440\u0430\u0432\u0443 \u0420\u0424 (\u0444\u0435\u0434\u0435\u0440\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u0430\u043a\u043e\u043d\u043e\u0434\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e, \u043f\u043e\u0434\u0437\u0430\u043a\u043e\u043d\u043d\u044b\u0435 \u0430\u043a\u0442\u044b, \u0441\u0443\u0434\u0435\u0431\u043d\u0430\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430). \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0448\u044c \u0441\u0442\u0440\u043e\u0433\u043e \u0432 \u043f\u0440\u0430\u0432\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435 \u0420\u0424, \u043f\u0438\u0448\u0435\u0448\u044c \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e. \u041d\u0435 \u0432\u044b\u0434\u0443\u043c\u044b\u0432\u0430\u0439 \u043d\u043e\u0440\u043c\u044b \u043f\u0440\u0430\u0432\u0430: \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u0432\u0435\u0440\u0435\u043d \u2014 \u0443\u043a\u0430\u0436\u0438, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438. \u041e\u0442\u0432\u0435\u0442 \u0412\u0421\u0415\u0413\u0414\u0410 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c JSON \u0444\u043e\u0440\u043c\u0430\u0442\u0430: {\"summary\":\"...\",\"key_facts\":[\"...\"],\"legal_qualification\":[\"...\"],\"risks\":[\"...\"],\"recommended_next_steps\":[\"...\"],\"evidence_checklist\":[\"...\"],\"questions_for_client\":[\"...\"],\"disclaimer\":\"...\" }' }, { role: 'user', content: `\u042e\u0440\u0438\u0441\u0434\u0438\u043a\u0446\u0438\u044f: ${$json.jurisdiction}\\n\u041a\u043e\u0434 \u0434\u0435\u043b\u0430: ${$json.case_code || '\u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d'}\\n\\n\u0422\u0435\u043a\u0441\u0442 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u0434\u0435\u043b\u0430:\\n${$json.document_text}` } ] } }}"
},
"name": "AI_LEGAL :: LLM Analyze",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
760,
260
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const raw = $json.choices?.[0]?.message?.content || '{}';\nlet parsed;\ntry {\n parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n} catch (e) {\n parsed = {\n summary: String(raw),\n key_facts: [],\n legal_qualification: [],\n risks: ['LLM \u0432\u0435\u0440\u043d\u0443\u043b \u043d\u0435-JSON \u0444\u043e\u0440\u043c\u0430\u0442, \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0443\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430.'],\n recommended_next_steps: [],\n evidence_checklist: [],\n questions_for_client: [],\n disclaimer: '\u041e\u0442\u0432\u0435\u0442 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044e\u0440\u0438\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c.'\n };\n}\n\nreturn [{\n status: 'ok',\n generated_at: new Date().toISOString(),\n ...parsed\n}];"
},
"name": "AI_LEGAL :: Normalize Output",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1020,
260
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "={{$json}}"
},
"name": "AI_LEGAL :: Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
1260,
260
]
}
],
"connections": {
"CASE_CREATE_AND_FOLDERS :: Webhook Case Create": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: GS Read Cases",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: GS Read Cases": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: Check Case Code",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: Check Case Code": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: IF Exists",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: IF Exists": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: Respond 409",
"type": "main",
"index": 0
}
],
[
{
"node": "CASE_CREATE_AND_FOLDERS :: Build Paths",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: Build Paths": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Incoming",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: DAV MKCOL Incoming": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Outgoing",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: DAV MKCOL Outgoing": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: DAV MKCOL Evidence",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: DAV MKCOL Evidence": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: GS Append Case",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: GS Append Case": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: GS Append Folders",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: GS Append Folders": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: IF YC Mirror Enabled",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: IF YC Mirror Enabled": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: YC Mirror Case Upsert",
"type": "main",
"index": 0
}
],
[
{
"node": "CASE_CREATE_AND_FOLDERS :: Respond 201",
"type": "main",
"index": 0
}
]
]
},
"CASE_CREATE_AND_FOLDERS :: YC Mirror Case Upsert": {
"main": [
[
{
"node": "CASE_CREATE_AND_FOLDERS :: Respond 201",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: Webhook Event": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: Prepare",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: Prepare": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: Calendar Create",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: Calendar Create": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: GS Append Event",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: GS Append Event": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: GS Append Reminder 24h",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: GS Append Reminder 24h": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: GS Append Reminder 2h",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: GS Append Reminder 2h": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: IF Client Payment Reminder",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: IF Client Payment Reminder": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: GS Append Client Payment Reminder",
"type": "main",
"index": 0
}
],
[
{
"node": "CASE_EVENT_CREATE :: IF YC Mirror Enabled",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: GS Append Client Payment Reminder": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: IF YC Mirror Enabled",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: IF YC Mirror Enabled": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: YC Mirror Event Upsert",
"type": "main",
"index": 0
}
],
[
{
"node": "CASE_EVENT_CREATE :: Respond 201",
"type": "main",
"index": 0
}
]
]
},
"CASE_EVENT_CREATE :: YC Mirror Event Upsert": {
"main": [
[
{
"node": "CASE_EVENT_CREATE :: Respond 201",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: Cron": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: GS Read Reminders",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: GS Read Reminders": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: GS Read Sent Log",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: GS Read Sent Log": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: Filter Due",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: Filter Due": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: Split",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: Split": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: TG Send",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: TG Send": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: GS Sent Log",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: GS Sent Log": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: IF YC Mirror Enabled",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: IF YC Mirror Enabled": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: YC Mirror Reminder Sent",
"type": "main",
"index": 0
}
],
[
{
"node": "REMINDER_DISPATCH_CRON :: Split",
"type": "main",
"index": 0
}
]
]
},
"REMINDER_DISPATCH_CRON :: YC Mirror Reminder Sent": {
"main": [
[
{
"node": "REMINDER_DISPATCH_CRON :: Split",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: Telegram Trigger": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: Parse",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: Parse": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: GS Read Folders",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: GS Read Folders": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: Match Case",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: Match Case": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: IF Case Missing",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: IF Case Missing": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: TG Case Not Found",
"type": "main",
"index": 0
}
],
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: TG getFile",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: TG getFile": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: TG Download",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: TG Download": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: Safe Filename",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: Safe Filename": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: DAV Upload",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: DAV Upload": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: GS Append Document",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: GS Append Document": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: IF YC Mirror Enabled",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: IF YC Mirror Enabled": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: YC Mirror Document Upsert",
"type": "main",
"index": 0
}
],
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: TG Ack",
"type": "main",
"index": 0
}
]
]
},
"TELEGRAM_DOCUMENT_INGEST :: YC Mirror Document Upsert": {
"main": [
[
{
"node": "TELEGRAM_DOCUMENT_INGEST :: TG Ack",
"type": "main",
"index": 0
}
]
]
},
"AI_LEGAL :: Webhook": {
"main": [
[
{
"node": "AI_LEGAL :: Prepare Input",
"type": "main",
"index": 0
}
]
]
},
"AI_LEGAL :: Prepare Input": {
"main": [
[
{
"node": "AI_LEGAL :: LLM Analyze",
"type": "main",
"index": 0
}
]
]
},
"AI_LEGAL :: LLM Analyze": {
"main": [
[
{
"node": "AI_LEGAL :: Normalize Output",
"type": "main",
"index": 0
}
]
]
},
"AI_LEGAL :: Normalize Output": {
"main": [
[
{
"node": "AI_LEGAL :: Respond",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "2"
}
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.
googleSheetsOAuth2ApihttpBasicAuthhttpHeaderAuthtelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
WF_UNIFIED_LEGAL_AUTOMATION. Uses googleSheets, httpRequest, telegram, telegramTrigger. Webhook trigger; 53 nodes.
Source: https://github.com/alexdmitrievi/Vardkesonva/blob/main/workflows/WF_UNIFIED_LEGAL_AUTOMATION.json — 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.
This workflow captures customer messages from WhatsApp or Telegram, logs the lead in Google Sheets, and replies with a Stripe Payment Link. After Stripe confirms a successful Checkout payment, it look
This workflow provides a complete solution for handling Telegram Stars payments, invoicing and refunds using n8n. It automates the process of sending invoices, managing pre-checkout approvals, recordi
clients kept booking meetings during my prayer times. i'd either miss a prayer or scramble to reschedule. the problem wasn't the clients — it was that my calendar had no blocked windows for salah. i n
Generate 360° product videos from a single photo using Google Veo 3 and Telegram
02b — Article callback. Uses telegramTrigger, googleSheets, telegram, httpRequest. Event-driven trigger; 30 nodes.