feat: v1.3 Unraid Update Status Sync

Unraid GraphQL API foundation — connectivity, authentication, and
container ID format verified for native Unraid API integration.

Phase 14: Unraid API Access (2 plans, 4 tasks)
- Established Unraid GraphQL API connectivity via myunraid.net cloud relay
- Dual credential storage (.env.unraid-api + n8n env vars)
- Container ID format: {server_hash}:{container_hash} (128-char SHA256 pair)
- Complete API contract documented in ARCHITECTURE.md
- "unraid" test command added to Telegram bot

Phases 15-16 dropped (superseded by v1.4 Unraid API Native).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lucas Berger
2026-02-09 07:47:31 -05:00
parent ff0773b84b
commit 903e73d616
14 changed files with 1018 additions and 205 deletions
+121 -2
View File
@@ -363,6 +363,29 @@
},
"renameOutput": true,
"outputKey": "status"
},
{
"id": "keyword-unraid-test",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "loose"
},
"conditions": [
{
"id": "contains-unraid",
"leftValue": "={{ $json.message.text }}",
"rightValue": "unraid",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "unraid"
}
]
},
@@ -4778,6 +4801,80 @@
}
},
"onError": "continueRegularOutput"
},
{
"id": "7d42919e-f0a9-4ac6-8c0f-ea647eb5e841",
"name": "Unraid API Test",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1200,
5200
],
"parameters": {
"url": "={{ $env.UNRAID_HOST }}/graphql",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
},
"authentication": "genericCredentialType",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "{\"query\": \"query { docker { containers { id names state } } }\"}",
"options": {},
"genericAuthType": "httpHeaderAuth"
},
"continueOnFail": true,
"credentials": {
"httpHeaderAuth": {
"id": "6DB4RZZoeF5Raf7V",
"name": "Unraid API Key"
}
}
},
{
"id": "117c6fb1-5d62-4a63-8290-186b8c4ab784",
"name": "Validate Unraid Response",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1500,
5200
],
"parameters": {
"jsCode": "const response = $input.item.json;\n\n// Check for HTTP errors (from continueOnError)\nif (response.error) {\n return {\n json: {\n action: 'send_message',\n text: `\u274c <b>Unraid API Error</b>\\n\\n` +\n `<b>Error:</b> ${response.error.message || JSON.stringify(response.error)}\\n\\n` +\n `<b>Check:</b>\\n` +\n `\u2022 Is UNRAID_HOST correct?\\n` +\n `\u2022 Is the API key valid?\\n` +\n `\u2022 Can n8n reach the Unraid host? (--add-host flag)\\n` +\n `\u2022 Is Unraid GraphQL API enabled? (v7.2+ or Connect plugin)`,\n chatId: $('Telegram Trigger').item.json.message.chat.id\n }\n };\n}\n\n// Check for GraphQL errors\nif (response.errors) {\n const errorMsg = response.errors.map(e => e.message).join(', ');\n return {\n json: {\n action: 'send_message',\n text: `\u274c <b>Unraid GraphQL Error</b>\\n\\n${errorMsg}`,\n chatId: $('Telegram Trigger').item.json.message.chat.id\n }\n };\n}\n\n// Validate response structure\nif (!response.data?.docker?.containers) {\n return {\n json: {\n action: 'send_message',\n text: '\u274c <b>Unexpected response</b>\\n\\nNo container data in GraphQL response.',\n chatId: $('Telegram Trigger').item.json.message.chat.id\n }\n };\n}\n\nconst containers = response.data.docker.containers;\nconst sampleId = containers[0]?.id || 'N/A';\n// isUpdateAvailable field TBD \u2014 discover via sandbox\n\nreturn {\n json: {\n action: 'send_message',\n text: `\u2705 <b>Unraid API Connected</b>\\n\\n` +\n `<b>Containers:</b> ${containers.length}\\n` +\n `<b>ID format:</b> <code>${sampleId}</code>\\n\\n` +\n `Sample:\\n` +\n containers.slice(0, 5).map(c =>\n `\u2022 ${c.names?.[0] || c.id} (${c.state})`\n ).join('\\n'),\n chatId: $('Telegram Trigger').item.json.message.chat.id\n }\n};"
}
},
{
"id": "-",
"name": "Send Unraid Test Result",
"type": "n8n-nodes-base.telegram",
"typeVersion": 1.2,
"position": [
1800,
5200
],
"parameters": {
"resource": "message",
"operation": "sendMessage",
"chatId": "={{ $json.chatId }}",
"text": "={{ $json.text }}",
"additionalFields": {
"parse_mode": "HTML"
}
},
"credentials": {
"telegramApi": {
"id": "I0xTTiASl7C1NZhJ",
"name": "Telegram account"
}
}
}
],
"connections": {
@@ -5198,7 +5295,7 @@
],
[
{
"node": "Show Menu",
"node": "Unraid API Test",
"type": "main",
"index": 0
}
@@ -6659,6 +6756,28 @@
}
]
]
},
"Unraid API Test": {
"main": [
[
{
"node": "Validate Unraid Response",
"type": "main",
"index": 0
}
]
]
},
"Validate Unraid Response": {
"main": [
[
{
"node": "Send Unraid Test Result",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
@@ -6669,4 +6788,4 @@
"tags": [],
"triggerCount": 1,
"active": false
}
}