{ "name": "JSON Feed Telegram Alert", "nodes": [ { "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "*/5 * * * *" } ] } }, "id": "trigger-5min", "name": "Ogni 5 minuti", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [ 0, 0 ] }, { "parameters": { "method": "GET", "url": "https://YOUR_FEED_HOST/lista.json", "options": { "timeout": 10000, "response": { "response": { "responseFormat": "json" } } } }, "id": "fetch-feed", "name": "Leggi il feed JSON", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [ 220, 0 ] }, { "parameters": { "mode": "runOnceForAllItems", "jsCode": "function selectEvents({body,arrayField,filterField,filterValues,timestampField,lastTs}) {\n if(!body||typeof body!=='object'||Array.isArray(body))throw new Error('The feed must return a JSON object.');\n if([arrayField,filterField,timestampField].some(value=>typeof value!=='string'||!value))throw new Error('Configure the feed field names.');\n if(!Array.isArray(filterValues)||filterValues.some(value=>typeof value!=='string'))throw new Error('filterValues must be an array of strings.');\n if(typeof lastTs!=='string')throw new Error('The saved timestamp must be a string.');\n const raw=body[arrayField]??[];\n if(!Array.isArray(raw))throw new Error('The configured feed array must be an array.');\n const eligible=[];\n for(const entry of raw){\n if(!entry||typeof entry!=='object'||Array.isArray(entry))throw new Error('Feed entries must be objects.');\n if(filterValues.length&&!filterValues.includes(entry[filterField]))continue;\n const value=entry[timestampField];\n if(value!=null&&typeof value!=='string'&&!(typeof value==='number'&&Number.isFinite(value)))throw new Error('Feed timestamps must be comparable strings or finite numbers.');\n const timestamp=value==null?'':String(value);\n if(timestamp>lastTs)eligible.push({entry,timestamp});\n }\n eligible.sort((a,b)=>a.timestampb.timestamp?1:0);\n const escape=text=>text.replaceAll('&','&').replaceAll('<','<').replaceAll('>','>');\n const notifications=eligible.map(({entry,timestamp})=>{\n const rawText='🔔 '+(entry[filterField]||'evento')+'\\n'+JSON.stringify(entry).slice(0,300);\n const text=escape(rawText);\n if(!text||text.length>4096)throw new Error('A Telegram alert exceeds 4096 characters.');\n return {text,timestamp};\n });\n return {notifications,count:notifications.length,nextTimestamp:eligible.at(-1)?.timestamp??lastTs};\n}\n\n\nconst state=$getWorkflowStaticData('global');\nconst selected=selectEvents({body:$input.first().json,...{\"arrayField\":\"items\",\"filterField\":\"tipo\",\"filterValues\":[],\"timestampField\":\"ts\"},lastTs:state.lastTs||''});\nif(selected.count)state.lastTs=selected.nextTimestamp;\nreturn selected.notifications.map(item=>({json:{text:item.text}}));\n" }, "id": "filter-new", "name": "Solo voci nuove e filtrate", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 440, 0 ] }, { "parameters": { "resource": "message", "operation": "sendMessage", "chatId": "@YOUR_TELEGRAM_CHANNEL", "text": "={{ $json.text }}", "additionalFields": { "parse_mode": "HTML", "appendAttribution": false } }, "id": "send-telegram", "name": "Manda su Telegram", "type": "n8n-nodes-base.telegram", "typeVersion": 1.2, "position": [ 660, 0 ] } ], "connections": { "Ogni 5 minuti": { "main": [ [ { "node": "Leggi il feed JSON", "type": "main", "index": 0 } ] ] }, "Leggi il feed JSON": { "main": [ [ { "node": "Solo voci nuove e filtrate", "type": "main", "index": 0 } ] ] }, "Solo voci nuove e filtrate": { "main": [ [ { "node": "Manda su Telegram", "type": "main", "index": 0 } ] ] } }, "settings": { "executionOrder": "v1", "timezone": "UTC" }, "active": false, "pinData": {} }