{ "name": "Send a Website Screenshot to Telegram", "nodes": [ { "name": "On clicking 'execute'", "type": "n8n-nodes-base.manualTrigger", "position": [ 250, 300 ], "parameters": {}, "typeVersion": 1, "id": "send-website-screenshot-to-telegram-start" }, { "id": "send-website-screenshot-to-telegram-capture", "name": "Capture the full page", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "parameters": { "method": "GET", "url": "https://api.screenshotbase.com/v1/take", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "sendQuery": true, "queryParameters": { "parameters": [ { "name": "url", "value": "https://n8n.io" }, { "name": "format", "value": "png" }, { "name": "full_page", "value": "1" }, { "name": "viewport_width", "value": "1024" }, { "name": "device_scale_factor", "value": "1" }, { "name": "upload", "value": "1" } ] }, "options": { "timeout": 95000, "response": { "response": { "responseFormat": "json" } } } } }, { "id": "send-website-screenshot-to-telegram-url-check", "name": "Check the Screenshotbase URL", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": " function validUrl(value) {\n if (typeof value !== 'string' || /[\\s\\x00-\\x1f\\x7f\\\\]/.test(value) || /%(?![0-9a-f]{2})/i.test(value)) return false;\n const match = /^https?:\\/\\/([^/?#]+)(?:[/?#].*)?$/i.exec(value);\n if (!match || match[1].includes('@')) return false;\n const authority = match[1];\n let host, port;\n if (authority.startsWith('[')) {\n const parts = /^\\[([0-9a-f:]+)\\](?::(\\d+))?$/i.exec(authority);\n if (!parts) return false;\n host = parts[1]; port = parts[2];\n const halves = host.split('::');\n if (halves.length > 2) return false;\n const groups = halves.flatMap(part => part ? part.split(':') : []);\n if (groups.some(group => !/^[0-9a-f]{1,4}$/i.test(group))) return false;\n if (halves.length === 1 ? groups.length !== 8 : groups.length >= 8) return false;\n } else {\n const parts = /^([^:]+)(?::(\\d+))?$/.exec(authority);\n if (!parts) return false;\n host = parts[1]; port = parts[2];\n if (host.length > 253) return false;\n const labels = host.replace(/\\.$/, '').split('.');\n if (!labels.every(label => label.length > 0 && label.length <= 63 && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label))) return false;\n if (labels.every(label => /^\\d+$/.test(label)) && (labels.length !== 4 || labels.some(label => Number(label) > 255))) return false;\n }\n return port === undefined || (port.length <= 5 && Number(port) <= 65535);\n }\n\nconst url=$input.first().json.url;if(!validUrl(url)||!/^https:\\/\\/(?:cache|cdn)\\.screenshotbase\\.com(?:[/?#]|$)/i.test(url))throw Error('Invalid Screenshotbase CDN URL');return [{json:{url}}];" } }, { "id": "send-website-screenshot-to-telegram-inspect", "name": "Read screenshot header", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "parameters": { "method": "GET", "url": "={{ $json.url }}", "sendHeaders": true, "headerParameters": { "parameters": [ { "name": "Range", "value": "bytes=0-23" } ] }, "options": { "response": { "response": { "responseFormat": "file", "outputPropertyName": "data" } } } } }, { "id": "send-website-screenshot-to-telegram-check", "name": "Validate the screenshot URL", "type": "n8n-nodes-base.code", "typeVersion": 2, "parameters": { "mode": "runOnceForAllItems", "jsCode": " function validUrl(value) {\n if (typeof value !== 'string' || /[\\s\\x00-\\x1f\\x7f\\\\]/.test(value) || /%(?![0-9a-f]{2})/i.test(value)) return false;\n const match = /^https?:\\/\\/([^/?#]+)(?:[/?#].*)?$/i.exec(value);\n if (!match || match[1].includes('@')) return false;\n const authority = match[1];\n let host, port;\n if (authority.startsWith('[')) {\n const parts = /^\\[([0-9a-f:]+)\\](?::(\\d+))?$/i.exec(authority);\n if (!parts) return false;\n host = parts[1]; port = parts[2];\n const halves = host.split('::');\n if (halves.length > 2) return false;\n const groups = halves.flatMap(part => part ? part.split(':') : []);\n if (groups.some(group => !/^[0-9a-f]{1,4}$/i.test(group))) return false;\n if (halves.length === 1 ? groups.length !== 8 : groups.length >= 8) return false;\n } else {\n const parts = /^([^:]+)(?::(\\d+))?$/.exec(authority);\n if (!parts) return false;\n host = parts[1]; port = parts[2];\n if (host.length > 253) return false;\n const labels = host.replace(/\\.$/, '').split('.');\n if (!labels.every(label => label.length > 0 && label.length <= 63 && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label))) return false;\n if (labels.every(label => /^\\d+$/.test(label)) && (labels.length !== 4 || labels.some(label => Number(label) > 255))) return false;\n }\n return port === undefined || (port.length <= 5 && Number(port) <= 65535);\n }\n\nfunction checkPng(bytes){if(!bytes||bytes.length<24)throw Error('Screenshot PNG header is incomplete');const sig=[137,80,78,71,13,10,26,10];if(sig.some((x,i)=>bytes[i]!==x)||bytes[8]!==0||bytes[9]!==0||bytes[10]!==0||bytes[11]!==13||String.fromCharCode(...bytes.slice(12,16))!=='IHDR')throw Error('Screenshot is not a PNG with an IHDR header');const u=i=>bytes[i]*16777216+bytes[i+1]*65536+bytes[i+2]*256+bytes[i+3],width=u(16),height=u(20);if(width!==1024||height<1||height>=20000)throw Error('Screenshot dimensions may indicate truncation or scaling');return true;}\n\nconst url=$('Check the Screenshotbase URL').first().json.url;if(!validUrl(url)||!/^https:\\/\\/(?:cache|cdn)\\.screenshotbase\\.com(?:[/?#]|$)/i.test(url))throw Error('Invalid Screenshotbase CDN URL');const bytes=await this.helpers.getBinaryDataBuffer(0,'data');checkPng(bytes);return [{json:{photo:url}}];" } }, { "name": "Telegram", "type": "n8n-nodes-base.telegram", "position": [ 650, 300 ], "parameters": { "resource": "message", "operation": "sendPhoto", "chatId": "YOUR_TELEGRAM_CHAT_ID", "binaryData": false, "file": "={{ $json.photo }}", "replyMarkup": "none", "additionalFields": {} }, "typeVersion": 1, "id": "send-website-screenshot-to-telegram-send" } ], "active": false, "settings": {}, "connections": { "On clicking 'execute'": { "main": [ [ { "node": "Capture the full page", "type": "main", "index": 0 } ] ] }, "Capture the full page": { "main": [ [ { "node": "Check the Screenshotbase URL", "type": "main", "index": 0 } ] ] }, "Check the Screenshotbase URL": { "main": [ [ { "node": "Read screenshot header", "type": "main", "index": 0 } ] ] }, "Read screenshot header": { "main": [ [ { "node": "Validate the screenshot URL", "type": "main", "index": 0 } ] ] }, "Validate the screenshot URL": { "main": [ [ { "node": "Telegram", "type": "main", "index": 0 } ] ] } }, "pinData": {} }