{ "id": "Gd4MsAZGnSGfBwaw", "meta": { "instanceId": "workflow-cfc36d28", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:54.059612", "updatedAt": "2025-09-29T07:07:54.059620", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "name": "Telegram channel to Readeck & Hoarder", "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "nodes": [ { "id": "6e50d52e-8b9e-4c92-82a1-af366c7a2ccf", "name": "Schedule Trigger", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -440, -700 ], "parameters": { "rule": { "interval": [ { "field": "hours" } ] } }, "typeVersion": 1.2, "notes": "This scheduleTrigger node performs automated tasks as part of the workflow." }, { "id": "bb7430a2-a7b7-47f2-9ba3-a3e43c8da004", "name": "Split Out", "type": "n8n-nodes-base.splitOut", "position": [ -100, -120 ], "parameters": { "options": {}, "fieldToSplitOut": "bookmarks" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "922aeb0b-29b1-46c6-9b18-76c02eca5a9e", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ -460, -480 ], "parameters": { "width": 1120, "height": 220, "content": "## Readeck" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "64d4ca0b-2c16-441e-9461-5707be877132", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ -220, -740 ], "parameters": { "width": 480, "height": 200, "content": "## Telegram" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "13ae24ec-ac11-470a-bad4-76403861f632", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ -460, -180 ], "parameters": { "width": 1120, "height": 220, "content": "## Hoarder" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "c606f434-d37b-4406-997a-1e7f17319281", "name": "not_saved_links_hd", "type": "n8n-nodes-base.code", "position": [ 260, -120 ], "parameters": { "jsCode": "const linksCanalItems = $('channel_links_tg').all();\nconst saved_links_items = $('saved_links_hd').all();\n\n// Extract links\nconst saved_links = new Set(\n saved_links_items.map(item => String(item.json.content.url))\n);\n\n// Filter\nconst filteredLinks = linksCanalItems.filter(item => {\n return !saved_links.has(String(item.json.url));\n});\n\nreturn filteredLinks;\n\n\n\n\n\n\n\n\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "d0f61836-798c-4835-ae8f-8f184b6720ed", "name": "not_saved_links_rd", "type": "n8n-nodes-base.code", "position": [ 260, -420 ], "parameters": { "jsCode": "const linksCanalItems = $('channel_links_tg').all();\nconst saved_links_items = $('saved_links_rd').all();\n\n// Extract urls\nconst saved_urls = new Set(\n saved_links_items.map(item => String(item.json.url))\n);\n\n// Filter\nconst filteredLinks = linksCanalItems.filter(item => {\n return !saved_urls.has(String(item.json.url));\n});\n\nreturn filteredLinks;\n\n\n\n\n\n\n\n\n" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "f33349a7-361a-4b0f-844b-1ca5ded2aeab", "name": "saved_links_rd", "type": "n8n-nodes-base.set", "position": [ 80, -420 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "8c6f3806-0fb8-4c76-a0bc-19b588717430", "name": "id", "type": "string", "value": "={{ $json.id }}" }, { "id": "ef41cba3-2844-479c-9467-6b94ae24c98b", "name": "url", "type": "string", "value": "={{ $json.url }}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "63d45b19-e878-418e-8eb5-c16b50af9669", "name": "save_link_rd", "type": "n8n-nodes-base.httpRequest", "position": [ 460, -420 ], "parameters": { "url": "{{ $env.BASE_URL }}", "method": "POST", "options": {}, "sendBody": true, "sendHeaders": true, "bodyParameters": { "parameters": [ { "name": "url", "value": "={{ $json.url }}" } ] }, "headerParameters": { "parameters": [ { "name": "accept", "value": "application/json" }, { "name": "authorization", "value": "=Bearer {{$env.READECK_API_KEY}}" } ] } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "9416a858-1a25-4c3e-a49e-153118c268a7", "name": "save_link_hd", "type": "n8n-nodes-base.httpRequest", "position": [ 460, -120 ], "parameters": { "url": "{{ $env.BASE_URL }}", "method": "POST", "options": {}, "sendBody": true, "sendHeaders": true, "bodyParameters": { "parameters": [ { "name": "type", "value": "link" }, { "name": "url", "value": "={{ $json.url }}" } ] }, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "=Bearer {{$env.HOARDER_API_KEY}}" } ] } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "13693467-cd75-4774-9072-832419606ab2", "name": "get_links_rd", "type": "n8n-nodes-base.httpRequest", "position": [ -280, -420 ], "parameters": { "url": "{{ $env.BASE_URL }}", "options": {}, "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "accept", "value": "application/json" }, { "name": "authorization", "value": "=Bearer {{$env.READECK_API_KEY}}" } ] } }, "typeVersion": 4.2, "alwaysOutputData": true, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "e4ed315d-d065-425a-b30d-eca1509670cc", "name": "get_links_hd", "type": "n8n-nodes-base.httpRequest", "position": [ -280, -120 ], "parameters": { "url": "{{ $env.BASE_URL }}", "options": {}, "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Authorization", "value": "=Bearer {{$env.HOARDER_API_KEY}}" } ] } }, "typeVersion": 4.2, "alwaysOutputData": true, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "f54d9a4d-f00b-41bf-988a-8920d0046424", "name": "saved_links_hd", "type": "n8n-nodes-base.set", "position": [ 80, -120 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "b07ce8e5-0b67-4c9c-831a-7a52f92f5744", "name": "content.url", "type": "string", "value": "={{ $json.content.url }}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "d4e83b9d-5988-46f4-b853-86daec274dba", "name": "channel_links_tg", "type": "n8n-nodes-base.code", "position": [ 120, -700 ], "parameters": { "jsCode": "// Define the chatId from the environment variable\nconst chatId = parseInt($env.TG_SHERLINK_ID, 10);\n// Access the \"result\" field from the previous node's output\nconst updates = $node[\"channel_items_tg\"].json[\"result\"];\n// Check if \"result\" is an array\nif (!Array.isArray(updates)) {\n return []; // Return empty if there are no messages\n}\n// Filter and process the messages\nconst filteredUpdates = updates\n .map(update => {\n // Ensure message from the specified channel\n if (update.channel_post && update.channel_post.chat && update.channel_post.chat.id === chatId) {\n return {\n id: update.channel_post.message_id,\n url: update.channel_post.text\n };\n }\n return null;\n })\n \n .filter(item => item !== null) // Filter nulls\n .filter(item => {\n // Filter only with hyperlink in text\n const text = item.url || \"\"; // Defined text\n return /https?:\\/\\/[^\\s]+/.test(text); // hyperlink\n });\n// Convert each array element into an individual item\nreturn filteredUpdates.map(update => ({ json: update }));\n" }, "typeVersion": 2, "alwaysOutputData": false, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "ca306aed-e682-4c35-a257-3b65bcfde895", "name": "channel_items_tg", "type": "n8n-nodes-base.httpRequest", "position": [ -80, -700 ], "parameters": { "url": "{{ $env.BASE_URL }}", "options": {}, "sendQuery": true, "queryParameters": { "parameters": [ {} ] } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." } ], "active": true, "pinData": {}, "settings": { "callerPolicy": "workflowsFromSameOwner", "executionOrder": "v1", "saveManualExecutions": true, "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000 }, "versionId": "85dd3731-0772-4b8b-b828-ae6a034d5419", "connections": { "63d45b19-e878-418e-8eb5-c16b50af9669": { "main": [ [ { "node": "error-handler-63d45b19-e878-418e-8eb5-c16b50af9669", "type": "main", "index": 0 } ], [ { "node": "error-handler-63d45b19-e878-418e-8eb5-c16b50af9669-0691e201", "type": "main", "index": 0 } ], [ { "node": "error-handler-63d45b19-e878-418e-8eb5-c16b50af9669-65c2c97f", "type": "main", "index": 0 } ], [ { "node": "error-handler-63d45b19-e878-418e-8eb5-c16b50af9669-f18aeecc", "type": "main", "index": 0 } ], [ { "node": "error-handler-63d45b19-e878-418e-8eb5-c16b50af9669-e3e73071", "type": "main", "index": 0 } ] ] }, "9416a858-1a25-4c3e-a49e-153118c268a7": { "main": [ [ { "node": "error-handler-9416a858-1a25-4c3e-a49e-153118c268a7", "type": "main", "index": 0 } ], [ { "node": "error-handler-9416a858-1a25-4c3e-a49e-153118c268a7-0cce38ef", "type": "main", "index": 0 } ], [ { "node": "error-handler-9416a858-1a25-4c3e-a49e-153118c268a7-f5474bdc", "type": "main", "index": 0 } ], [ { "node": "error-handler-9416a858-1a25-4c3e-a49e-153118c268a7-e7eebe2f", "type": "main", "index": 0 } ], [ { "node": "error-handler-9416a858-1a25-4c3e-a49e-153118c268a7-8baeab24", "type": "main", "index": 0 } ] ] }, "13693467-cd75-4774-9072-832419606ab2": { "main": [ [ { "node": "error-handler-13693467-cd75-4774-9072-832419606ab2", "type": "main", "index": 0 } ], [ { "node": "error-handler-13693467-cd75-4774-9072-832419606ab2-ac4023f9", "type": "main", "index": 0 } ], [ { "node": "error-handler-13693467-cd75-4774-9072-832419606ab2-50574df2", "type": "main", "index": 0 } ], [ { "node": "error-handler-13693467-cd75-4774-9072-832419606ab2-4763b7f5", "type": "main", "index": 0 } ], [ { "node": "error-handler-13693467-cd75-4774-9072-832419606ab2-16b60249", "type": "main", "index": 0 } ] ] }, "e4ed315d-d065-425a-b30d-eca1509670cc": { "main": [ [ { "node": "error-handler-e4ed315d-d065-425a-b30d-eca1509670cc", "type": "main", "index": 0 } ], [ { "node": "error-handler-e4ed315d-d065-425a-b30d-eca1509670cc-4e492879", "type": "main", "index": 0 } ], [ { "node": "error-handler-e4ed315d-d065-425a-b30d-eca1509670cc-f476277a", "type": "main", "index": 0 } ], [ { "node": "error-handler-e4ed315d-d065-425a-b30d-eca1509670cc-0a335c77", "type": "main", "index": 0 } ], [ { "node": "error-handler-e4ed315d-d065-425a-b30d-eca1509670cc-21aa2c00", "type": "main", "index": 0 } ] ] }, "ca306aed-e682-4c35-a257-3b65bcfde895": { "main": [ [ { "node": "error-handler-ca306aed-e682-4c35-a257-3b65bcfde895", "type": "main", "index": 0 } ], [ { "node": "error-handler-ca306aed-e682-4c35-a257-3b65bcfde895-3abc7893", "type": "main", "index": 0 } ], [ { "node": "error-handler-ca306aed-e682-4c35-a257-3b65bcfde895-ca1f7896", "type": "main", "index": 0 } ], [ { "node": "error-handler-ca306aed-e682-4c35-a257-3b65bcfde895-1054356a", "type": "main", "index": 0 } ], [ { "node": "error-handler-ca306aed-e682-4c35-a257-3b65bcfde895-70cfa463", "type": "main", "index": 0 } ] ] } }, "description": "Automated workflow: Telegram channel to Readeck & Hoarder. This workflow integrates 7 different services: stickyNote, httpRequest, code, scheduleTrigger, splitOut. It contains 25 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: Telegram channel to Readeck & Hoarder. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }