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 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.
Automates LinkedIn job searches across multiple countries and categories, filters results with AI, stores data in Google Sheets, and sends weekly Telegram notifications. Perfect for professionals seek