This workflow follows the Agent → 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": "\u0424\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0439 \u0411\u043e\u0442 Telegram - \u041f\u043e\u043b\u043d\u044b\u0439 \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b",
"nodes": [
{
"parameters": {
"content": "\ud83d\udce5 \u0411\u041b\u041e\u041a 1: \u041f\u0420\u0418\u0401\u041c \u0412\u0425\u041e\u0414\u042f\u0429\u0418\u0425 \u0414\u0410\u041d\u041d\u042b\u0425\n\n\u042d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:\n- \u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b (/payment, /limit, /stats)\n- \u0413\u043e\u043b\u043e\u0441\u043e\u0432\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f (STT)\n- \u0424\u043e\u0442\u043e \u0447\u0435\u043a\u043e\u0432 (OCR)\n- \u0424\u0430\u0439\u043b\u044b \u0432\u044b\u043f\u0438\u0441\u043e\u043a (CSV/XLS)",
"height": 400,
"width": 400,
"color": 1
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-1",
"name": "\u0411\u043b\u043e\u043a 1: \u041f\u0440\u0438\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445"
},
{
"parameters": {
"updates": [
"message"
],
"additionalFields": {}
},
"type": "n8n-nodes-base.telegramTrigger",
"typeVersion": 1.2,
"position": [
240,
400
],
"id": "node-trigger",
"name": "Telegram Webhook - \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-payment",
"leftValue": "={{ $json.message.text || '' }}",
"rightValue": "/payment",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "payment"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-stats",
"leftValue": "={{ $json.message.text || '' }}",
"rightValue": "/stats",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "stats"
},
{
"conditions": {
"options": {
"caseSensitive": false,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-limit",
"leftValue": "={{ $json.message.text || '' }}",
"rightValue": "/limit",
"operator": {
"type": "string",
"operation": "startsWith"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "limit"
}
]
},
"options": {
"fallbackOutput": "fallback"
}
},
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
460,
400
],
"id": "node-switch-commands",
"name": "\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-voice",
"leftValue": "={{ $json.message.voice ? 'voice' : 'no' }}",
"rightValue": "voice",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
520
],
"id": "node-check-voice",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-photo",
"leftValue": "={{ $json.message.photo ? 'photo' : 'no' }}",
"rightValue": "photo",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
640
],
"id": "node-check-photo",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0444\u043e\u0442\u043e"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-document",
"leftValue": "={{ $json.message.document ? 'document' : 'no' }}",
"rightValue": "document",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
460,
760
],
"id": "node-check-document",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430"
},
{
"parameters": {
"content": "\ud83e\udd16 \u0411\u041b\u041e\u041a 2: AI AGENT - \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 \u041a\u041e\u041c\u0410\u041d\u0414\n\nAI Agent \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442:\n- \u0421\u0443\u043c\u043c\u0443 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\n- \u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044e\n- \u0420\u0435\u0436\u0438\u043c (\u0424\u0438\u0437/\u042e\u0440)\n- \u0414\u0430\u0442\u0443\n- \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439\n- \u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a",
"height": 400,
"width": 400,
"color": 2
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-2",
"name": "\u0411\u043b\u043e\u043a 2: AI Agent"
},
{
"parameters": {
"promptType": "define",
"text": "=\u0422\u044b \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0439 \u0430\u0441\u0441\u0438\u0441\u0442\u0435\u043d\u0442. \u0422\u0432\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 - \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.\n\n\u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:\n\u041a\u043e\u043c\u0430\u043d\u0434\u0430: \"{{ $json.message.text }}\"\nChat ID: {{ $json.message.chat.id }}\nUsername: {{ $json.message.from.username || 'unknown' }}\n\n\u0424\u043e\u0440\u043c\u0430\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u044b /payment:\n/payment [\u0421\u0423\u041c\u041c\u0410] [\u041a\u0410\u0422\u0415\u0413\u041e\u0420\u0418\u042f] [\u0420\u0415\u0416\u0418\u041c] [\u0414\u0410\u0422\u0410] [\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439: \"\u0442\u0435\u043a\u0441\u0442\"]\n\n\u041f\u0440\u0438\u043c\u0435\u0440\u044b:\n/payment 4500 \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0424\u0438\u0437\n/payment 18000 \u0420\u0435\u043a\u043b\u0430\u043c\u0430 \u042e\u0440 2025-01-03\n/payment 2000 \u0422\u0430\u043a\u0441\u0438 \u0424\u0438\u0437 \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439: \"\u041f\u043e\u0435\u0437\u0434\u043a\u0430 \u0432 \u0430\u044d\u0440\u043e\u043f\u043e\u0440\u0442\"\n\n\u0412\u0435\u0440\u043d\u0438 \u0422\u041e\u041b\u042c\u041a\u041e JSON \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:\n{\n \"amount\": \u0447\u0438\u0441\u043b\u043e (\u0441\u0443\u043c\u043c\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438),\n \"category\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f),\n \"mode\": \"\u0424\u0438\u0437\" \u0438\u043b\u0438 \"\u042e\u0440\" (\u0440\u0435\u0436\u0438\u043c, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \"\u0424\u0438\u0437\"),\n \"date\": \"YYYY-MM-DD\" \u0438\u043b\u0438 null (\u0434\u0430\u0442\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438),\n \"note\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u0442\u043a\u0430),\n \"source\": \"telegram\",\n \"chat_id\": \u0447\u0438\u0441\u043b\u043e,\n \"username\": \"\u0441\u0442\u0440\u043e\u043a\u0430\"\n}\n\n\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430:\n- \u0421\u0443\u043c\u043c\u0430: \u043f\u0435\u0440\u0432\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435\n- \u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: \u0441\u043b\u043e\u0432\u043e \u043f\u043e\u0441\u043b\u0435 \u0441\u0443\u043c\u043c\u044b\n- \u0420\u0435\u0436\u0438\u043c: \"\u0424\u0438\u0437\" \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u043b\u043e\u0432\u043e \"\u0424\u0438\u0437\", \"\u042e\u0440\" \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \"\u042e\u0440\", \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \"\u0424\u0438\u0437\"\n- \u0414\u0430\u0442\u0430: \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u0430\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 YYYY-MM-DD, \u0438\u043d\u0430\u0447\u0435 null\n- \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439: \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0441\u043b\u0435 \"\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439:\" \u0438\u043b\u0438 \u0432\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\n\n\u0412\u0435\u0440\u043d\u0438 \u0442\u043e\u043b\u044c\u043a\u043e JSON, \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430.",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
680,
400
],
"id": "node-ai-agent",
"name": "AI Agent - \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u043e\u043c\u0430\u043d\u0434\u044b /payment"
},
{
"parameters": {
"content": "\ud83c\udfa4 \u0411\u041b\u041e\u041a 3: \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 \u0413\u041e\u041b\u041e\u0421\u041e\u0412\u042b\u0425 \u0421\u041e\u041e\u0411\u0429\u0415\u041d\u0418\u0419 (STT)\n\n\u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044f \u0433\u043e\u043b\u043e\u0441\u0430 \u0432 \u0442\u0435\u043a\u0441\u0442,\n\u0437\u0430\u0442\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 AI Agent",
"height": 300,
"width": 400,
"color": 3
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-3",
"name": "\u0411\u043b\u043e\u043a 3: STT"
},
{
"parameters": {
"fileId": "={{ $json.message.voice.file_id }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
680,
520
],
"id": "node-get-voice",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=https://api.telegram.org/bot{{ $credentials.telegramApi.accessToken }}/getFile?file_id={{ $json.message.voice.file_id }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
900,
520
],
"id": "node-get-file-path",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u043a \u0444\u0430\u0439\u043b\u0443"
},
{
"parameters": {
"url": "=https://api.openai.com/v1/audio/transcriptions",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"whisper-1\",\n \"file\": \"{{ $json.result.file_path }}\"\n}",
"options": {
"bodyContentType": "multipart-form-data"
}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
520
],
"id": "node-stt-openai",
"name": "STT - OpenAI Whisper",
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "assign-voice-text",
"name": "message.text",
"value": "={{ $json.text }}",
"type": "string"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1340,
520
],
"id": "node-set-voice-text",
"name": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0437 \u0433\u043e\u043b\u043e\u0441\u0430"
},
{
"parameters": {
"content": "\ud83d\udcf7 \u0411\u041b\u041e\u041a 4: \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 \u0424\u041e\u0422\u041e \u0427\u0415\u041a\u041e\u0412 (OCR)\n\n\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435:\n- \u0421\u0443\u043c\u043c\u044b\n- \u0414\u0430\u0442\u044b\n- \u0418\u041d\u041d\n- \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430\n- \u0410\u0432\u0442\u043e\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438",
"height": 300,
"width": 400,
"color": 4
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-4",
"name": "\u0411\u043b\u043e\u043a 4: OCR"
},
{
"parameters": {
"fileId": "={{ $json.message.photo[$json.message.photo.length - 1].file_id }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
680,
640
],
"id": "node-get-photo",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0444\u043e\u0442\u043e",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"url": "=https://api.telegram.org/bot{{ $credentials.telegramApi.accessToken }}/getFile?file_id={{ $json.message.photo[$json.message.photo.length - 1].file_id }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
900,
640
],
"id": "node-get-photo-path",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u0443\u0442\u0438 \u043a \u0444\u043e\u0442\u043e"
},
{
"parameters": {
"url": "=https://api.telegram.org/file/bot{{ $credentials.telegramApi.accessToken }}/{{ $json.result.file_path }}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1120,
640
],
"id": "node-download-photo",
"name": "\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 \u0444\u043e\u0442\u043e"
},
{
"parameters": {
"url": "=https://api.ocr.space/parse/image",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"apikey\": \"YOUR_OCR_API_KEY\",\n \"base64Image\": \"{{ $binary.data }}\",\n \"language\": \"rus\"\n}",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1340,
640
],
"id": "node-ocr-api",
"name": "OCR API - \u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430"
},
{
"parameters": {
"promptType": "define",
"text": "=\u0418\u0437\u0432\u043b\u0435\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u0447\u0435\u043a\u0430:\n\n\u0422\u0435\u043a\u0441\u0442 \u0447\u0435\u043a\u0430:\n{{ $json.ParsedResults && $json.ParsedResults.length > 0 ? $json.ParsedResults[0].ParsedText : ($json.ParsedText || $json.text || '') }}\n\n\u0412\u0435\u0440\u043d\u0438 JSON:\n{\n \"amount\": \u0447\u0438\u0441\u043b\u043e (\u0441\u0443\u043c\u043c\u0430),\n \"category\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u0430\u0432\u0442\u043e\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438),\n \"date\": \"YYYY-MM-DD\" \u0438\u043b\u0438 null,\n \"counterparty\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430),\n \"inn\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u0418\u041d\u041d \u0435\u0441\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u043d),\n \"note\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f)\n}\n\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b, \u0420\u0435\u043a\u043b\u0430\u043c\u0430, \u0422\u0430\u043a\u0441\u0438, \u041a\u0430\u0444\u0435, \u0422\u0440\u0430\u043d\u0441\u043f\u043e\u0440\u0442, \u041a\u043e\u043c\u043c\u0443\u043d\u0430\u043b\u044c\u043d\u044b\u0435, \u041f\u0440\u043e\u0447\u0435\u0435",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
1560,
640
],
"id": "node-ai-ocr",
"name": "AI Agent - \u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 OCR"
},
{
"parameters": {
"content": "\ud83d\udcc4 \u0411\u041b\u041e\u041a 5: \u0418\u041c\u041f\u041e\u0420\u0422 \u0411\u0410\u041d\u041a\u041e\u0412\u0421\u041a\u0418\u0425 \u0412\u042b\u041f\u0418\u0421\u041e\u041a\n\n\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 CSV/XLS \u0444\u0430\u0439\u043b\u043e\u0432:\n- \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u044b\u043f\u0438\u0441\u043a\u0438\n- \u041f\u043e\u0438\u0441\u043a \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432\n- \u0417\u0430\u043f\u0438\u0441\u044c \u0432 \u0411\u0414\n- \u041e\u0442\u0447\u0451\u0442 \u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445",
"height": 300,
"width": 400,
"color": 5
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-5",
"name": "\u0411\u043b\u043e\u043a 5: \u0418\u043c\u043f\u043e\u0440\u0442 \u0432\u044b\u043f\u0438\u0441\u043e\u043a"
},
{
"parameters": {
"fileId": "={{ $json.message.document.file_id }}",
"additionalFields": {}
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
680,
760
],
"id": "node-get-document",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "read",
"binaryPropertyName": "data",
"options": {}
},
"type": "n8n-nodes-base.spreadsheetFile",
"typeVersion": 1,
"position": [
900,
760
],
"id": "node-parse-csv",
"name": "\u041f\u0430\u0440\u0441\u0438\u043d\u0433 CSV/XLS \u0444\u0430\u0439\u043b\u0430"
},
{
"parameters": {
"jsCode": "// \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0440\u043e\u043a\u0438 CSV/XLS \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\nconst inputItem = $input.first();\nif (!inputItem || !inputItem.json) {\n return [{ json: { error: '\u041d\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445' } }];\n}\n\nconst row = inputItem.json;\nconst fileName = row.fileName || row.file_name || '';\n\n// \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u0435\u0436\u0438\u043c \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430 \u0438\u043b\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u043c\u0443\nconst isJuridical = fileName.toLowerCase().includes('\u044e\u0440') || \n fileName.toLowerCase().includes('jur') ||\n (row.counterparty && /\u041e\u041e\u041e|LLC|LTD|\u0418\u041f/i.test(row.counterparty));\n\n// \u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438\nconst transaction = {\n bank_id: row.bank_id || row.id || row.transaction_id || null,\n amount: parseFloat(row.amount || row.sum || row.\u0441\u0443\u043c\u043c\u0430 || 0),\n category: row.category || row.\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f || '\u0418\u043c\u043f\u043e\u0440\u0442',\n transaction_id: row.transaction_id || row.id || null,\n note: row.note || row.\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 || row.description || '\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0438\u0437 \u0444\u0430\u0439\u043b\u0430',\n source: 'csv_import',\n counterparty: row.counterparty || row.\u043a\u043e\u043d\u0442\u0440\u0430\u0433\u0435\u043d\u0442 || row.merchant || null,\n created_at: row.date || row.\u0434\u0430\u0442\u0430 || row.created_at || new Date().toISOString().split('T')[0],\n mode: isJuridical ? '\u042e\u0440' : '\u0424\u0438\u0437',\n table: isJuridical ? 'transactions_jur' : 'transactions_phys'\n};\n\nreturn [{ json: transaction }];"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1120,
760
],
"id": "node-map-csv-row",
"name": "\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 CSV"
},
{
"parameters": {
"content": "\ud83d\udcbe \u0411\u041b\u041e\u041a 6: \u0420\u0410\u0411\u041e\u0422\u0410 \u0421 \u0411\u0410\u0417\u041e\u0419 \u0414\u0410\u041d\u041d\u042b\u0425 MariaDB\n\n\u0417\u0430\u043f\u0438\u0441\u044c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0432:\n- transactions_phys (\u0444\u0438\u0437\u043b\u0438\u0446\u043e)\n- transactions_jur (\u044e\u0440\u043b\u0438\u0446\u043e)\n\n\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432,\n\u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445",
"height": 300,
"width": 400,
"color": 6
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-6",
"name": "\u0411\u043b\u043e\u043a 6: \u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445"
},
{
"parameters": {
"jsCode": "// \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\nconst inputItem = $input.first();\nif (!inputItem || !inputItem.json) {\n return { json: { error: '\u041d\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445', valid: false, errors: ['\u041d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438'] } };\n}\n\nconst data = inputItem.json;\n\nconst errors = [];\n\n// \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0443\u043c\u043c\u044b\nif (!data.amount || isNaN(data.amount) || data.amount <= 0) {\n errors.push('\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0430\u044f \u0441\u0443\u043c\u043c\u0430');\n}\n\n// \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438\nif (!data.category || data.category.trim() === '') {\n errors.push('\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430');\n}\n\n// \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0435\u0436\u0438\u043c\u0430\nif (data.mode !== '\u0424\u0438\u0437' && data.mode !== '\u042e\u0440') {\n data.mode = '\u0424\u0438\u0437'; // \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e\n}\n\n// \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b\nif (!data.table) {\n data.table = data.mode === '\u042e\u0440' ? 'transactions_jur' : 'transactions_phys';\n}\n\n// \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f transaction_id \u0435\u0441\u043b\u0438 \u043d\u0435\u0442\nif (!data.transaction_id) {\n data.transaction_id = `txn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n\n// \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0430\u0442\u044b\nif (data.date) {\n data.created_at = data.date;\n} else if (!data.created_at) {\n data.created_at = new Date().toISOString().split('T')[0];\n}\n\nreturn {\n json: {\n ...data,\n valid: errors.length === 0,\n errors: errors\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
400
],
"id": "node-validate-data",
"name": "\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438"
},
{
"parameters": {
"operation": "executeQuery",
"query": "=SELECT COUNT(*) as count FROM {{ $json.table }} WHERE bank_id = '{{ $json.bank_id }}' AND bank_id IS NOT NULL",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
1560,
400
],
"id": "node-check-duplicate",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432 \u043f\u043e bank_id",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432\nconst inputItem = $input.first();\nif (!inputItem || !inputItem.json) {\n return { json: { error: '\u041d\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445', skip: true } };\n}\n\nconst inputData = inputItem.json;\nconst duplicateCheck = Array.isArray(inputData) ? (inputData.length > 0 ? inputData[0] : null) : inputData;\n\n// \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u043d\u043e\u0434\u044b\nconst transaction = duplicateCheck && duplicateCheck.category ? duplicateCheck : (Array.isArray(inputData) && inputData.length > 0 ? inputData[0] : inputData);\n\nif (duplicateCheck && duplicateCheck.count > 0 && transaction && transaction.bank_id) {\n return {\n json: {\n ...transaction,\n isDuplicate: true,\n skip: true\n }\n };\n}\n\nreturn {\n json: {\n ...transaction,\n isDuplicate: false,\n skip: false\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1780,
400
],
"id": "node-process-duplicate",
"name": "\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-skip",
"leftValue": "={{ $json.skip }}",
"rightValue": "true",
"operator": {
"type": "boolean",
"operation": "true"
}
}
],
"combinator": "and"
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
2000,
400
],
"id": "node-if-skip",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 - \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442?"
},
{
"parameters": {
"operation": "insert",
"table": "={{ $json.table }}",
"columns": {
"columns": [
{
"name": "bank_id",
"value": "={{ $json.bank_id }}"
},
{
"name": "amount",
"value": "={{ $json.amount }}"
},
{
"name": "category",
"value": "={{ $json.category }}"
},
{
"name": "transaction_id",
"value": "={{ $json.transaction_id }}"
},
{
"name": "note",
"value": "={{ $json.note }}"
},
{
"name": "source",
"value": "={{ $json.source || 'telegram' }}"
},
{
"name": "counterparty",
"value": "={{ $json.counterparty }}"
},
{
"name": "created_at",
"value": "={{ $json.created_at }}"
}
]
}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
2220,
300
],
"id": "node-insert-phys",
"name": "\u0417\u0430\u043f\u0438\u0441\u044c \u0432 transactions_phys",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "insert",
"table": "transactions_jur",
"columns": {
"columns": [
{
"name": "bank_id",
"value": "={{ $json.bank_id }}"
},
{
"name": "amount",
"value": "={{ $json.amount }}"
},
{
"name": "category",
"value": "={{ $json.category }}"
},
{
"name": "transaction_id",
"value": "={{ $json.transaction_id }}"
},
{
"name": "note",
"value": "={{ $json.note }}"
},
{
"name": "source",
"value": "={{ $json.source || 'telegram' }}"
},
{
"name": "counterparty",
"value": "={{ $json.counterparty }}"
},
{
"name": "created_at",
"value": "={{ $json.created_at }}"
}
]
}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
2220,
500
],
"id": "node-insert-jur",
"name": "\u0417\u0430\u043f\u0438\u0441\u044c \u0432 transactions_jur",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "\u26a0\ufe0f \u0411\u041b\u041e\u041a 7: \u0421\u0418\u0421\u0422\u0415\u041c\u0410 \u041b\u0418\u041c\u0418\u0422\u041e\u0412 \u0418 \u0423\u0412\u0415\u0414\u041e\u041c\u041b\u0415\u041d\u0418\u0419\n\n\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u0432 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c:\n- \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 80%\n- \u0423\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0438\n- \u0421\u043f\u0438\u0441\u043e\u043a \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439",
"height": 300,
"width": 400,
"color": 7
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-7",
"name": "\u0411\u043b\u043e\u043a 7: \u041b\u0438\u043c\u0438\u0442\u044b"
},
{
"parameters": {
"operation": "executeQuery",
"query": "=SELECT limit_amount FROM category_limits WHERE category = '{{ $json.category }}' AND mode = '{{ $json.mode }}' LIMIT 1",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
2440,
400
],
"id": "node-get-limit",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043b\u0438\u043c\u0438\u0442\u0430 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"operation": "executeQuery",
"query": "=SELECT SUM(amount) as spent FROM {{ $json.table }} WHERE category = '{{ $json.category }}' AND MONTH(created_at) = MONTH(NOW()) AND YEAR(created_at) = YEAR(NOW())",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
2660,
400
],
"id": "node-get-spent",
"name": "\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b \u0437\u0430 \u043c\u0435\u0441\u044f\u0446",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// \u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u043c\u0438\u0442\u0430 \u0438 \u043f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u043c\u043c\u044b\nconst allInputs = $input.all();\n\nlet transaction = {};\nlet limit = null;\nlet spent = 0;\n\n// \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\nallInputs.forEach(item => {\n const data = item.json;\n \n // \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 (\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u0430)\n if (Array.isArray(data) && data.length > 0) {\n const firstRow = data[0];\n if (firstRow.limit_amount !== undefined) {\n limit = parseFloat(firstRow.limit_amount || 0);\n }\n if (firstRow.spent !== undefined) {\n spent = parseFloat(firstRow.spent || 0);\n }\n } else if (data) {\n // \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0438\n if (data.category) {\n transaction = data;\n }\n if (data.limit_amount !== undefined) {\n limit = parseFloat(data.limit_amount || 0);\n }\n if (data.spent !== undefined) {\n spent = parseFloat(data.spent || 0);\n }\n }\n});\n\nreturn {\n json: {\n ...transaction,\n limit: limit,\n spent: spent\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2880,
400
],
"id": "node-merge-limit-data",
"name": "\u041e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u0438\u043c\u0438\u0442\u0430"
},
{
"parameters": {
"jsCode": "// \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u0432 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439\nconst inputItem = $input.first();\nif (!inputItem || !inputItem.json) {\n return { json: { error: '\u041d\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445' } };\n}\n\nconst inputData = inputItem.json;\nconst transaction = inputData || {};\nconst limit = transaction.limit || null;\nconst spent = transaction.spent || 0;\n\nlet alert = null;\nlet alertType = null;\n\nif (limit && transaction.category) {\n const percentage = (spent / limit) * 100;\n \n if (spent > limit) {\n alertType = 'exceeded';\n alert = `\u26a0\ufe0f \u041f\u0420\u0415\u0412\u042b\u0428\u0415\u041d \u041b\u0418\u041c\u0418\u0422!\\n\\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: ${transaction.category}\\n\u041b\u0438\u043c\u0438\u0442: ${limit.toLocaleString('ru-RU')} \u20bd\\n\u041f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e: ${spent.toLocaleString('ru-RU')} \u20bd\\n\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u0438\u0435: ${(spent - limit).toLocaleString('ru-RU')} \u20bd`;\n } else if (percentage >= 80) {\n alertType = 'warning';\n alert = `\u26a0\ufe0f \u041f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 \u043a \u043b\u0438\u043c\u0438\u0442\u0443!\\n\\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: ${transaction.category}\\n\u041b\u0438\u043c\u0438\u0442: ${limit.toLocaleString('ru-RU')} \u20bd\\n\u041f\u043e\u0442\u0440\u0430\u0447\u0435\u043d\u043e: ${spent.toLocaleString('ru-RU')} \u20bd (${percentage.toFixed(1)}%)\\n\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c: ${(limit - spent).toLocaleString('ru-RU')} \u20bd`;\n }\n}\n\nreturn {\n json: {\n ...transaction,\n alert: alert,\n alertType: alertType\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
3100,
400
],
"id": "node-check-limits",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u0432 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "loose"
},
"conditions": [
{
"id": "cond-alert",
"leftValue": "={{ $json.alert }}",
"rightValue": "",
"operator": {
"type": "string",
"operation": "notEmpty"
}
}
],
"combinator": "and"
}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
3100,
400
],
"id": "node-if-alert",
"name": "\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 - \u0435\u0441\u0442\u044c \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435?"
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "={{ $json.alert }}"
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
3320,
300
],
"id": "node-send-alert",
"name": "\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u043b\u0438\u043c\u0438\u0442\u0435",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "\u2705 \u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430!\n\n\u0421\u0443\u043c\u043c\u0430: {{ $json.amount.toLocaleString('ru-RU') }} \u20bd\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: {{ $json.category }}\n\u0420\u0435\u0436\u0438\u043c: {{ $json.mode }}\n\u0414\u0430\u0442\u0430: {{ $json.created_at }}"
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
3320,
500
],
"id": "node-send-confirm",
"name": "\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "\ud83d\udcca \u0411\u041b\u041e\u041a 8: \u0410\u041d\u0410\u041b\u0418\u0422\u0418\u041a\u0410 \u0418 \u041e\u0422\u0427\u0401\u0422\u042b (/stats)\n\n\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u0447\u0451\u0442\u043e\u0432:\n- \u0415\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u044b\u0435/\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u044b\u0435/\u043c\u0435\u0441\u044f\u0447\u043d\u044b\u0435\n- \u041f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f\u043c\n- \u0413\u0440\u0430\u0444\u0438\u043a\u0438\n- \u042d\u043a\u0441\u043f\u043e\u0440\u0442 \u0432 CSV",
"height": 300,
"width": 400,
"color": 8
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-8",
"name": "\u0411\u043b\u043e\u043a 8: \u0410\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430"
},
{
"parameters": {
"promptType": "define",
"text": "=\u041f\u0430\u0440\u0441\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 /stats \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:\n\n\u041a\u043e\u043c\u0430\u043d\u0434\u0430: \"{{ $json.message.text }}\"\n\n\u0424\u043e\u0440\u043c\u0430\u0442: /stats [\u043f\u0435\u0440\u0438\u043e\u0434] [\u0440\u0435\u0436\u0438\u043c] [\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f]\n\n\u041f\u0440\u0438\u043c\u0435\u0440\u044b:\n/stats \u0434\u0435\u043d\u044c\n/stats \u043d\u0435\u0434\u0435\u043b\u044f \u0424\u0438\u0437\n/stats \u043c\u0435\u0441\u044f\u0446 \u042e\u0440 \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b\n\n\u0412\u0435\u0440\u043d\u0438 JSON:\n{\n \"period\": \"\u0434\u0435\u043d\u044c\" | \"\u043d\u0435\u0434\u0435\u043b\u044f\" | \"\u043c\u0435\u0441\u044f\u0446\" | \"\u0433\u043e\u0434\",\n \"mode\": \"\u0424\u0438\u0437\" | \"\u042e\u0440\" | \"\u0412\u0441\u0435\",\n \"category\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" | null\n}\n\n\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e: \u043f\u0435\u0440\u0438\u043e\u0434 = \"\u043c\u0435\u0441\u044f\u0446\", mode = \"\u0412\u0441\u0435\", category = null",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
680,
880
],
"id": "node-ai-stats",
"name": "AI Agent - \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u043e\u043c\u0430\u043d\u0434\u044b /stats"
},
{
"parameters": {
"jsCode": "// \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438\nconst inputItem = $input.first();\nif (!inputItem || !inputItem.json) {\n return { json: { query: '', table: 'transactions_phys', period: '\u043c\u0435\u0441\u044f\u0446', mode: '\u0412\u0441\u0435', category: null } };\n}\n\nconst params = inputItem.json;\nconst period = params.period || '\u043c\u0435\u0441\u044f\u0446';\nconst mode = params.mode || '\u0412\u0441\u0435';\nconst category = params.category || null;\n\nlet table = 'transactions_phys';\nif (mode === '\u042e\u0440') {\n table = 'transactions_jur';\n} else if (mode === '\u0412\u0441\u0435') {\n // \u0414\u043b\u044f \"\u0412\u0441\u0435\" \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c UNION\n table = 'transactions_phys'; // \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e\n}\n\nlet dateFilter = '';\nswitch(period) {\n case '\u0434\u0435\u043d\u044c':\n dateFilter = \"DATE(created_at) = CURDATE()\";\n break;\n case '\u043d\u0435\u0434\u0435\u043b\u044f':\n dateFilter = \"created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)\";\n break;\n case '\u043c\u0435\u0441\u044f\u0446':\n dateFilter = \"MONTH(created_at) = MONTH(NOW()) AND YEAR(created_at) = YEAR(NOW())\";\n break;\n case '\u0433\u043e\u0434':\n dateFilter = \"YEAR(created_at) = YEAR(NOW())\";\n break;\n default:\n dateFilter = \"MONTH(created_at) = MONTH(NOW()) AND YEAR(created_at) = YEAR(NOW())\";\n}\n\nlet categoryFilter = '';\nif (category) {\n categoryFilter = `AND category = '${category}'`;\n}\n\nconst query = `\n SELECT \n category,\n SUM(amount) as total,\n COUNT(*) as count,\n AVG(amount) as avg_amount,\n MIN(amount) as min_amount,\n MAX(amount) as max_amount\n FROM ${table}\n WHERE ${dateFilter} ${categoryFilter}\n GROUP BY category\n ORDER BY total DESC\n`;\n\nreturn {\n json: {\n query: query,\n table: table,\n period: period,\n mode: mode,\n category: category\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
880
],
"id": "node-build-stats-query",
"name": "\u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 SQL \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438"
},
{
"parameters": {
"operation": "executeQuery",
"query": "={{ $json.query }}",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
1120,
880
],
"id": "node-execute-stats",
"name": "\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// \u0424\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0447\u0451\u0442\u0430 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432\nconst stats = $input.all();\nif (!stats || stats.length === 0) {\n return { json: { report: '\u041d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0442\u0447\u0451\u0442\u0430', csv: '', totalSum: 0, totalCount: 0 } };\n}\n\nconst params = (stats[0] && stats[0].json) ? stats[0].json : {};\n\nlet report = `\ud83d\udcca \u041e\u0422\u0427\u0401\u0422 \u041f\u041e \u0422\u0420\u0410\u041d\u0417\u0410\u041a\u0426\u0418\u042f\u041c\\n\\n`;\nreport += `\u041f\u0435\u0440\u0438\u043e\u0434: ${params.period || '\u043c\u0435\u0441\u044f\u0446'}\\n`;\nreport += `\u0420\u0435\u0436\u0438\u043c: ${params.mode || '\u0412\u0441\u0435'}\\n`;\nif (params.category) {\n report += `\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: ${params.category}\\n`;\n}\nreport += `\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nlet totalSum = 0;\nlet totalCount = 0;\nconst statsData = [];\n\nstats.forEach((item, index) => {\n if (!item || !item.json) return;\n \n let data = null;\n if (Array.isArray(item.json) && item.json.length > 0) {\n data = item.json[0];\n } else if (item.json && item.json.category) {\n data = item.json;\n }\n \n if (data && data.category) {\n statsData.push(data);\n totalSum += parseFloat(data.total || 0);\n totalCount += parseInt(data.count || 0);\n }\n});\n\nstatsData.forEach((data, index) => {\n report += `${index + 1}. ${data.category}\\n`;\n report += ` \u0421\u0443\u043c\u043c\u0430: ${parseFloat(data.total || 0).toLocaleString('ru-RU')} \u20bd\\n`;\n report += ` \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e: ${data.count || 0}\\n`;\n report += ` \u0421\u0440\u0435\u0434\u043d\u044f\u044f: ${parseFloat(data.avg_amount || 0).toLocaleString('ru-RU')} \u20bd\\n`;\n report += `\\n`;\n});\n\nreport += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\nreport += `\u0418\u0422\u041e\u0413\u041e:\\n`;\nreport += `\u0421\u0443\u043c\u043c\u0430: ${totalSum.toLocaleString('ru-RU')} \u20bd\\n`;\nreport += `\u0422\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439: ${totalCount}\\n`;\n\n// CSV \u0434\u0430\u043d\u043d\u044b\u0435\nlet csv = '\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f,\u0421\u0443\u043c\u043c\u0430,\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e,\u0421\u0440\u0435\u0434\u043d\u044f\u044f,\u041c\u0438\u043d,\u041c\u0430\u043a\u0441\\n';\nstatsData.forEach(data => {\n csv += `${data.category},${data.total || 0},${data.count || 0},${data.avg_amount || 0},${data.min_amount || 0},${data.max_amount || 0}\\n`;\n});\n\nreturn {\n json: {\n report: report,\n csv: csv,\n totalSum: totalSum,\n totalCount: totalCount\n }\n};"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1340,
880
],
"id": "node-format-stats",
"name": "\u0424\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0447\u0451\u0442\u0430"
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "={{ $json.report }}"
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1560,
880
],
"id": "node-send-stats",
"name": "\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043e\u0442\u0447\u0451\u0442\u0430",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"fileName": "stats.csv",
"fileContent": "={{ $json.csv }}",
"options": {}
},
"type": "n8n-nodes-base.writeBinaryFile",
"typeVersion": 1,
"position": [
1780,
880
],
"id": "node-create-csv",
"name": "\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 CSV \u0444\u0430\u0439\u043b\u0430"
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"caption": "\ud83d\udcca \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439",
"binaryPropertyName": "data"
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
2000,
880
],
"id": "node-send-csv",
"name": "\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 CSV \u0444\u0430\u0439\u043b\u0430",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "\u2699\ufe0f \u0411\u041b\u041e\u041a 9: \u0423\u041f\u0420\u0410\u0412\u041b\u0415\u041d\u0418\u0415 \u041b\u0418\u041c\u0418\u0422\u0410\u041c\u0418 (/limit)\n\n\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u043e\u0432:\n/limit [\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f] [\u0441\u0443\u043c\u043c\u0430] [\u0440\u0435\u0436\u0438\u043c]\n\n\u041f\u0440\u0438\u043c\u0435\u0440:\n/limit \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b 40000\n/limit \u0420\u0435\u043a\u043b\u0430\u043c\u0430 150000 \u042e\u0440",
"height": 300,
"width": 400,
"color": 9
},
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"id": "sticky-9",
"name": "\u0411\u043b\u043e\u043a 9: \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u0438\u043c\u0438\u0442\u0430\u043c\u0438"
},
{
"parameters": {
"promptType": "define",
"text": "=\u041f\u0430\u0440\u0441\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 /limit \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:\n\n\u041a\u043e\u043c\u0430\u043d\u0434\u0430: \"{{ $json.message.text }}\"\n\n\u0424\u043e\u0440\u043c\u0430\u0442: /limit [\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f] [\u0441\u0443\u043c\u043c\u0430] [\u0440\u0435\u0436\u0438\u043c]\n\n\u041f\u0440\u0438\u043c\u0435\u0440\u044b:\n/limit \u041f\u0440\u043e\u0434\u0443\u043a\u0442\u044b 40000\n/limit \u0420\u0435\u043a\u043b\u0430\u043c\u0430 150000 \u042e\u0440\n\n\u0412\u0435\u0440\u043d\u0438 JSON:\n{\n \"category\": \"\u0441\u0442\u0440\u043e\u043a\u0430\" (\u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f),\n \"limit_amount\": \u0447\u0438\u0441\u043b\u043e (\u0441\u0443\u043c\u043c\u0430 \u043b\u0438\u043c\u0438\u0442\u0430),\n \"mode\": \"\u0424\u0438\u0437\" | \"\u042e\u0440\" (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \"\u0424\u0438\u0437\")\n}\n\n\u0415\u0441\u043b\u0438 \u0440\u0435\u0436\u0438\u043c \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \"\u0424\u0438\u0437\"",
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 3,
"position": [
680,
1000
],
"id": "node-ai-limit",
"name": "AI Agent - \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u043a\u043e\u043c\u0430\u043d\u0434\u044b /limit"
},
{
"parameters": {
"operation": "executeQuery",
"query": "=INSERT INTO category_limits (category, limit_amount, mode, created_at, updated_at) \nVALUES ('{{ $json.category }}', {{ $json.limit_amount }}, '{{ $json.mode || '\u0424\u0438\u0437' }}', NOW(), NOW())\nON DUPLICATE KEY UPDATE \n limit_amount = {{ $json.limit_amount }},\n updated_at = NOW()",
"options": {}
},
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [
900,
1000
],
"id": "node-set-limit",
"name": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043b\u0438\u043c\u0438\u0442\u0430 \u0432 \u0411\u0414",
"credentials": {
"mySql": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"chatId": "={{ $json.message.chat.id }}",
"text": "\u2705 \u041b\u0438\u043c\u0438\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d!\n\n\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f: {{ $json.category }}\n\u041b\u0438\u043c\u0438\u0442: {{ $json.limit_amount.toLocaleString('ru-RU') }} \u20bd\n\u0420\u0435\u0436\u0438\u043c: {{ $json.mode || '\u0424\u0438\u0437' }}"
},
"type": "n8n-nodes-base.telegram",
"typeVersion": 1,
"position": [
1120,
1000
],
"id": "node-confirm-limit",
"name": "\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043b\u0438\u043c\u0438\u0442\u0430",
"credentials": {
"telegramApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"content": "\ud83d\udd04 \u0411\u041b\u041e\u041a 10: \u041e\u0411\u0420\u0410\u0411\u041e\u0422\u041a\u0410 \u0418\u041c\u041f\u041e\u0420\u0422\u0410 CSV\n\n\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439:\n- \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a\n- \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0432\n- \u041c\u0430\u0441\u0441\u043e\u0432\u0430\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0430\n- \u041e\u0442\u0447\u0451\u0442 \u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u0445",
"height": 300,
"width": 400,
"color": 10
},
"
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.
mySqlopenAiApitelegramApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Финансовый Бот Telegram - Полный Функционал. Uses telegramTrigger, agent, telegram, httpRequest. Event-driven trigger; 53 nodes.
Source: https://gist.github.com/enrikkko/bc3ee0bac84cfdf7315ca77bdc1ebab6 — 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.
AI Money Tracker Chatbot. Uses telegramTrigger, postgres, googleSheets, telegram. Event-driven trigger; 24 nodes.
This workflow is perfect for productivity-focused teams, remote workers, virtual assistants, and digital knowledge managers who receive documents, images, or notes through Telegram and want to automat
This n8n workflow automates the transformation of spreadsheet data into professional charts and graphs using AI-driven analysis. Triggered via Slack, it processes uploaded files (Excel, CSV, Google Sh
Splitout Filter. Uses toolWorkflow, lmChatOpenAi, outputParserStructured, manualTrigger. Event-driven trigger; 38 nodes.
This template demonstrates how to build a low-code, AI-powered data analysis workflow in n8n. It enables you to connect to various data sources (such as MySQL, Google Sheets, or local files), process