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 →
{
"updatedAt": "2025-10-06T04:57:49.000Z",
"createdAt": "2025-07-29T18:48:28.008Z",
"id": "X5baTUVFHhvSO1SC",
"name": "HomeLab",
"active": true,
"isArchived": false,
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-720,
-288
],
"id": "ab1cfe2d-a3d2-4f14-91ea-fc161b070951",
"name": "Schedule Trigger"
},
{
"parameters": {
"authentication": "webhook",
"content": "={{ $json.message }}",
"options": {}
},
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
-48,
-288
],
"id": "146421f7-1e45-486b-98a4-4deb773b9669",
"name": "Discord",
"credentials": {
"discordWebhookApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const output = $('update system').first().json.stdout\nlet message = \"\";\nlet status = \"\u2705\";\nconst logSnippet = output.slice(-1000);\nconst userId = \"664803448629493816\"; // Ganti dengan user Discord yang ingin ditag\nconst mention = `<@${userId}>`;\n\nif (output.toLowerCase().includes(\"error\") || output.toLowerCase().includes(\"failed\")) {\n status = \"\u274c\";\n message = `\\`\\`\\`\\n${logSnippet}\\n\\`\\`\\`\\n\u274c Update failed!\\n${mention}`;\n} else if (output.toLowerCase().includes(\"a reboot is required\")) {\n status = \"\ud83d\udd04\";\n message = `\\`\\`\\`\\n${logSnippet}\\n\\`\\`\\`\\n\ud83d\udd04 Update completed but reboot is required.\\n${mention}`;\n} else {\n status = \"\u2705\";\n message = `\\`\\`\\`\\n${logSnippet}\\n\\`\\`\\`\\n\u2705 System updated successfully!`;\n}\n\nreturn [{\n json: {\n status,\n message\n }\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-272,
-288
],
"id": "d5808171-3559-4005-9116-b68f0adad9c8",
"name": "Code"
},
{
"parameters": {
"authentication": "webhook",
"content": "={{ $json.content }}\n-----------------------------------------",
"options": {}
},
"type": "n8n-nodes-base.discord",
"typeVersion": 2,
"position": [
-48,
-64
],
"id": "ba513429-2751-4051-b2d3-edf67c497de2",
"name": "Discord1",
"credentials": {
"discordWebhookApi": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const rawLog = $input.first().json.stdout; // log input dari node sebelumnya\n\nconst updatedImages = [];\nconst failedImages = [];\n\nconst lines = rawLog.split(\"\\n\");\n\nfor (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n\n // Cek baris \"Pulling image\"\n if (line.startsWith(\"[*] Pulling image:\")) {\n const image = line.replace(\"[*] Pulling image: \", \"\").trim();\n const statusLine = lines[i + 3] || \"\"; // Baris ke-3 setelah ini biasanya status\n const errorLine = lines[i + 1] || \"\"; // Jika error, muncul setelah ini\n\n if (statusLine.includes(\"Image is up to date\")) {\n // Lewatkan (tidak perlu dicatat)\n } else if (errorLine.includes(\"Error response from daemon\")) {\n failedImages.push(`${image} \u274c`);\n } else {\n updatedImages.push(`${image} \u2705`);\n }\n }\n}\n\n// Format pesan\nconst startedAt = rawLog.match(/Started at (.+?) ===/i)?.[1] || \"Unknown\";\nconst completedAt = rawLog.match(/Completed at (.+?) ===/i)?.[1] || \"Unknown\";\n\nlet message = `\ud83d\udee0\ufe0f **Docker Auto Update Summary**\\n\\n`;\nmessage += `\ud83d\udd53 **Started**: ${startedAt}\\n\u2705 **Completed**: ${completedAt}\\n\\n`;\n\nif (updatedImages.length > 0) {\n message += `\ud83d\udd04 **Updated Images:**\\n${updatedImages.map(i => `\u2022 ${i}`).join(\"\\n\")}\\n\\n`;\n}\n\nif (failedImages.length > 0) {\n message += `\u2757 **Failed Pulls:**\\n${failedImages.map(i => `\u2022 ${i}`).join(\"\\n\")}\\n\\n`;\n}\n\nif (updatedImages.length === 0 && failedImages.length === 0) {\n message += `\ud83d\udce6 All containers already up to date.\\n`;\n}\n\nreturn [\n {\n json: {\n content: message // Output ke Discord node\n }\n }\n];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
-272,
-64
],
"id": "2566227c-7ce0-498a-b457-bff46bf30732",
"name": "Code1"
},
{
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 3
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
-720,
-64
],
"id": "ddf8f63b-c2d1-4ac1-ac51-86d0760cfc1a",
"name": "Schedule Trigger1"
},
{
"parameters": {
"command": "sudo nala update && sudo nala upgrade -y"
},
"type": "n8n-nodes-base.ssh",
"typeVersion": 1,
"position": [
-496,
-288
],
"id": "683f5583-acd1-4443-9c9c-091509c29b68",
"name": "update system",
"credentials": {
"sshPassword": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"command": "sudo ./autoupdate.sh",
"cwd": "/home/n8nbot/dockerUpdate"
},
"type": "n8n-nodes-base.ssh",
"typeVersion": 1,
"position": [
-496,
-64
],
"id": "38bb81de-883a-486d-8c34-8dc590a392bd",
"name": "update docker",
"credentials": {
"sshPassword": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "update system",
"type": "main",
"index": 0
}
]
]
},
"Code": {
"main": [
[
{
"node": "Discord",
"type": "main",
"index": 0
}
]
]
},
"Code1": {
"main": [
[
{
"node": "Discord1",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger1": {
"main": [
[
{
"node": "update docker",
"type": "main",
"index": 0
}
]
]
},
"update system": {
"main": [
[
{
"node": "Code",
"type": "main",
"index": 0
}
]
]
},
"update docker": {
"main": [
[
{
"node": "Code1",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "workflowsFromSameOwner",
"errorWorkflow": "AvhjGJdACMdnvIEn"
},
"staticData": {
"node:Schedule Trigger": {
"recurrenceRules": []
},
"node:Schedule Trigger1": {
"recurrenceRules": []
},
"node:Metopen": {
"recurrenceRules": []
},
"node:AI": {
"recurrenceRules": []
},
"node:Informasi": {
"recurrenceRules": []
},
"node:Jaringan": {
"recurrenceRules": []
},
"node:Distribusi": {
"recurrenceRules": []
},
"node:Embedded": {
"recurrenceRules": []
},
"node:Sinyal": {
"recurrenceRules": []
},
"node:Tatul": {
"recurrenceRules": []
},
"node:prak distribusi": {
"recurrenceRules": []
},
"node:PrakEmbedded": {
"recurrenceRules": []
}
},
"meta": {
"templateCredsSetupCompleted": true
},
"versionId": "d1dced24-4b25-45dc-9e2e-3a376d75255f",
"triggerCount": 2,
"shared": [
{
"updatedAt": "2025-07-29T18:48:28.014Z",
"createdAt": "2025-07-29T18:48:28.014Z",
"role": "workflow:owner",
"workflowId": "X5baTUVFHhvSO1SC",
"projectId": "DiQC0tGxFhuiK9UM"
}
],
"tags": []
}
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.
discordWebhookApisshPassword
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
HomeLab. Uses scheduleTrigger, discord, ssh. Scheduled trigger; 8 nodes.
Source: https://github.com/SamVivan1/n8n-Workflows-Backup/blob/main/homelab-X5baTUVFHhvSO1SC.json — 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.
Absen Otomatis. Uses discord, ssh, scheduleTrigger, executeWorkflowTrigger. Scheduled trigger; 16 nodes.
Absen Nami. Uses ssh, discord, scheduleTrigger. Scheduled trigger; 13 nodes.
Wait Schedule. Uses spotify, supabase, compareDatasets, noOp. Scheduled trigger; 54 nodes.
This n8n template demonstrates how to automatically monitor and track username and nickname changes across your Discord server members. Perfect for community moderation, security monitoring, and maint