{ "nodes": [ { "name": "Webhook", "type": "n8n-nodes-base.webhook", "position": [ 350, 70 ], "webhookId": "727b4887-e7f9-405f-bf94-7889c82a8f0b", "parameters": { "path": "sh", "options": {}, "responseMode": "lastNode" }, "typeVersion": 1, "id": "node-18717d2e" }, { "name": "Extract URL", "type": "n8n-nodes-base.set", "position": [ 650, -80 ], "parameters": { "values": { "string": [ { "name": "url", "value": "={{$node[\"Webhook\"].json[\"query\"][\"url\"]}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-10d1922e" }, { "name": "Check URL", "type": "n8n-nodes-base.if", "position": [ 500, 70 ], "parameters": { "conditions": { "boolean": [ { "value1": "={{Object($node[\"Webhook\"].json[\"query\"]).hasOwnProperty(\"url\")}}", "value2": true } ] } }, "typeVersion": 1, "id": "node-f5cf8f6e" }, { "name": "Crypto", "type": "n8n-nodes-base.crypto", "position": [ 800, -80 ], "parameters": { "type": "SHA256", "value": "={{$node[\"Extract URL\"].json[\"url\"]}}" }, "typeVersion": 1, "id": "node-ce570b2e" }, { "name": "Airtable", "type": "n8n-nodes-base.airtable", "position": [ 1550, -30 ], "parameters": { "table": "YOUR TABLE NAME", "options": {}, "operation": "append", "application": "YOUR BASE ID" }, "credentials": { "airtableApi": "Personal Airtable API creds" }, "typeVersion": 1, "id": "node-1882d7e6" }, { "name": "Set ID,shortUrl,longUrl", "type": "n8n-nodes-base.set", "position": [ 950, -80 ], "parameters": { "values": { "string": [ { "name": "id", "value": "={{$node[\"Crypto\"].json[\"data\"].substr(0,6)}}" }, { "name": "longUrl", "value": "={{$node[\"Extract URL\"].json[\"url\"]}}" }, { "name": "shortUrl", "value": "=http://n8n.ly/w/go?id={{$node[\"Crypto\"].json[\"data\"].substr(0,6)}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-1f3b0ea3" }, { "name": "Find by ID", "type": "n8n-nodes-base.airtable", "position": [ 1100, -80 ], "parameters": { "limit": 1, "table": "YOUR TABLE NAME", "operation": "list", "returnAll": false, "application": "YOUR BASE ID", "additionalOptions": { "filterByFormula": "=id=\"{{$node[\"Set ID,shortUrl,longUrl\"].json[\"id\"]}}\"" } }, "credentials": { "airtableApi": "Personal Airtable API creds" }, "typeVersion": 1, "alwaysOutputData": true, "id": "node-19c0d5ab" }, { "name": "Already exists ?", "type": "n8n-nodes-base.if", "position": [ 1250, -80 ], "parameters": { "conditions": { "boolean": [ { "value1": "={{$node[\"Find by ID\"].json[\"id\"] != \"\" && $node[\"Find by ID\"].json[\"id\"] != null && $node[\"Find by ID\"].json[\"id\"] != undefined}}", "value2": true } ] } }, "typeVersion": 1, "id": "node-1f5d56fe" }, { "name": "Set Output", "type": "n8n-nodes-base.set", "position": [ 1400, -180 ], "parameters": { "values": { "string": [ { "name": "shortUrl", "value": "={{$node[\"Set ID,shortUrl,longUrl\"].json[\"shortUrl\"]}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-4afab0cb" }, { "name": "Set Error output", "type": "n8n-nodes-base.set", "position": [ 650, 170 ], "parameters": { "values": { "string": [ { "name": "error", "value": "url parameter missing" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-abe3481b" }, { "name": "Set Output1", "type": "n8n-nodes-base.set", "position": [ 1700, -30 ], "parameters": { "values": { "string": [ { "name": "shortUrl", "value": "={{$node[\"Set ID,shortUrl,longUrl\"].json[\"shortUrl\"]}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-302c0702" }, { "name": "Set input", "type": "n8n-nodes-base.set", "position": [ 1400, -30 ], "parameters": { "values": { "number": [ { "name": "clicks" } ], "string": [ { "name": "id", "value": "={{$node[\"Crypto\"].json[\"data\"].substr(0,6)}}" }, { "name": "longUrl", "value": "={{$node[\"Extract URL\"].json[\"url\"]}}" }, { "name": "shortUrl", "value": "=http://n8n.ly/w/go?id={{$node[\"Crypto\"].json[\"data\"].substr(0,6)}}" }, { "name": "host", "value": "={{(new URL($node[\"Extract URL\"].json[\"url\"])).host}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-97cacfd7" }, { "name": "Webhook1", "type": "n8n-nodes-base.webhook", "position": [ 350, 430 ], "webhookId": "727b4887-e7f9-405f-bf94-7889c82a8f0b", "parameters": { "path": "/go", "options": { "responseHeaders": { "entries": [ { "name": "Content-Type", "value": "text/html" } ] }, "responsePropertyName": "result" }, "responseMode": "lastNode" }, "typeVersion": 1, "id": "node-5d88b942" }, { "name": "Set Error output1", "type": "n8n-nodes-base.set", "position": [ 640, 530 ], "parameters": { "values": { "string": [ { "name": "result", "value": "id parameter missing." } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-d62879e2" }, { "name": "Check Id", "type": "n8n-nodes-base.if", "position": [ 500, 430 ], "parameters": { "conditions": { "boolean": [ { "value1": "={{Object($node[\"Webhook1\"].json[\"query\"]).hasOwnProperty(\"id\")}}", "value2": true } ] } }, "typeVersion": 1, "id": "node-179c31cc" }, { "name": "Find by ID1", "type": "n8n-nodes-base.airtable", "position": [ 800, 330 ], "parameters": { "limit": 1, "table": "YOUR TABLE NAME", "operation": "list", "returnAll": false, "application": "YOUR BASE ID", "additionalOptions": { "filterByFormula": "=id=\"{{$node[\"Extract Id\"].json[\"id\"]}}\"" } }, "credentials": { "airtableApi": "Personal Airtable API creds" }, "typeVersion": 1, "alwaysOutputData": true, "id": "node-8db2dbd0" }, { "name": "Already exists ?1", "type": "n8n-nodes-base.if", "position": [ 950, 330 ], "parameters": { "conditions": { "boolean": [ { "value1": "={{$node[\"Find by ID1\"].json[\"id\"] != \"\" && $node[\"Find by ID1\"].json[\"id\"] != null && $node[\"Find by ID1\"].json[\"id\"] != undefined}}", "value2": true } ] } }, "typeVersion": 1, "id": "node-a0f12b6b" }, { "name": "Set Output2", "type": "n8n-nodes-base.set", "position": [ 1400, 230 ], "parameters": { "values": { "string": [ { "name": "result", "value": "=\n\n\n \n \n \n Redirection\n\n\n \n\n\n" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-fdc4cd18" }, { "name": "Extract Id", "type": "n8n-nodes-base.set", "position": [ 650, 330 ], "parameters": { "values": { "string": [ { "name": "id", "value": "={{$node[\"Webhook1\"].json[\"query\"][\"id\"]}}" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-1db6081a" }, { "name": "404 Error", "type": "n8n-nodes-base.set", "position": [ 1100, 430 ], "parameters": { "values": { "string": [ { "name": "result", "value": "=Short URL not found" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-8b63c5df" }, { "name": "Update clicks", "type": "n8n-nodes-base.airtable", "position": [ 1250, 230 ], "parameters": { "id": "={{$node[\"Find by ID1\"].json[\"id\"]}}", "table": "YOUR TABLE NAME", "fields": [ "clicks" ], "options": {}, "operation": "update", "application": "YOUR BASE ID", "updateAllFields": false }, "credentials": { "airtableApi": "Personal Airtable API creds" }, "typeVersion": 1, "alwaysOutputData": true, "id": "node-d86db8d2" }, { "name": "Prepare clicks count", "type": "n8n-nodes-base.set", "position": [ 1100, 230 ], "parameters": { "values": { "string": [ { "name": "clicks", "value": "={{$node[\"Find by ID1\"].json[\"fields\"][\"clicks\"]+1}}" } ] }, "options": {} }, "typeVersion": 1, "id": "node-40abc2d4" }, { "name": "Webhook2", "type": "n8n-nodes-base.webhook", "position": [ 350, 680 ], "webhookId": "8ac18eb4-bcc5-4817-b76d-d93094755ed2", "parameters": { "path": "/dashboard", "options": { "responseHeaders": { "entries": [ { "name": "Content-Type", "value": "text/html" } ] }, "responsePropertyName": "dashboard" }, "responseMode": "lastNode" }, "typeVersion": 1, "id": "node-b2cfb131" }, { "name": "Find by ID2", "type": "n8n-nodes-base.airtable", "position": [ 550, 680 ], "parameters": { "table": "YOUR TABLE NAME", "operation": "list", "application": "YOUR BASE ID", "additionalOptions": {} }, "credentials": { "airtableApi": "Personal Airtable API creds" }, "typeVersion": 1, "alwaysOutputData": true, "id": "node-46a6f3ea" }, { "name": "Extract stats", "type": "n8n-nodes-base.function", "position": [ 750, 680 ], "parameters": { "functionCode": "\nitems = items.filter(item=> Object.keys(item.json).length !==0).map(item => item.json.fields);\nif(items.length === 0){\nreturn [{\n json:{\n totalLinks:0,\n totalClick:0,\n totalHosts:0\n }\n}];\n}\nconst totalLinks = items.length;\nconst totalClick = items.map(item => item.clicks).reduce((acc,val) => acc+=val);\nconst hostsMap = new Map();\nconst hosts = items.map(item => item.host);\nhosts.forEach(host => { \n hostsMap.set(host,hostsMap.get(host)!==undefined?hostsMap.get(host)+1:1)\n});\n\nconst totalHosts = [...hostsMap.keys()].length;\n\nreturn [{\n json:{\n totalLinks,\n totalClick,\n totalHosts\n }\n}];" }, "typeVersion": 1, "id": "node-d20eb6dd" }, { "name": "Set dashboard", "type": "n8n-nodes-base.set", "position": [ 950, 680 ], "parameters": { "values": { "string": [ { "name": "dashboard", "value": "=\n\n\n \n \n \n Dashboard\n\n\n\n\n \n
\n
\n \n n8 \n \n

Dashboard

\n
\n
\n
\n
Total Clicks
\n{{$node[\"Extract stats\"].json[\"totalClick\"]}}\n
\n
\n
Total Links
\n{{$node[\"Extract stats\"].json[\"totalLinks\"]}}\n
\n
\n
Total Hosts
\n{{$node[\"Extract stats\"].json[\"totalHosts\"]}}\n
\n
\n
\n\n" } ] }, "options": {}, "keepOnlySet": true }, "typeVersion": 1, "id": "node-b9d262d9" }, { "id": "error-8b7c13c3", "name": "Error Handler", "type": "n8n-nodes-base.stopAndError", "typeVersion": 1, "position": [ 1000, 400 ], "parameters": { "message": "Workflow execution error", "options": {} } } ], "connections": {}, "name": "Production Workflow", "settings": { "executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3 }, "meta": { "instanceId": "workflow-80fcc502", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:44.064716", "updatedAt": "2025-09-29T07:07:44.064760", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "description": "Production-ready workflow: Production Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }