188 lines
6.5 KiB
JSON
188 lines
6.5 KiB
JSON
{
|
|
"name": "GCP 自動修復機制",
|
|
"nodes": [
|
|
{
|
|
"parameters": {
|
|
"rule": {
|
|
"interval": [
|
|
{
|
|
"field": "minutes",
|
|
"minutesInterval": 5
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"id": "schedule",
|
|
"name": "每 5 分鐘檢查",
|
|
"type": "n8n-nodes-base.scheduleTrigger",
|
|
"typeVersion": 1.2,
|
|
"position": [240, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "https://momo.wooo.work/health",
|
|
"options": {
|
|
"timeout": 15000
|
|
}
|
|
},
|
|
"id": "health-check",
|
|
"name": "GCP 健康檢查",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [460, 300],
|
|
"continueOnFail": true
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const response = $input.first().json;\nconst now = new Date().toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });\n\n// 檢查健康狀態\nlet isHealthy = false;\nlet needsRepair = false;\nlet repairType = '';\nlet errorDetail = '';\n\nif (response && response.status === 'healthy') {\n isHealthy = true;\n} else if (response && response.error) {\n needsRepair = true;\n repairType = 'app_error';\n errorDetail = response.error;\n} else {\n needsRepair = true;\n repairType = 'app_down';\n errorDetail = '應用無回應或返回異常';\n}\n\nreturn [{\n json: {\n isHealthy,\n needsRepair,\n repairType,\n errorDetail,\n environment: 'GCP',\n envIcon: '🟥',\n url: 'https://momo.wooo.work',\n timestamp: now,\n response: JSON.stringify(response).slice(0, 500)\n }\n}];"
|
|
},
|
|
"id": "analyze",
|
|
"name": "分析健康狀態",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [680, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"conditions": {
|
|
"options": {
|
|
"caseSensitive": true,
|
|
"leftValue": "",
|
|
"typeValidation": "strict"
|
|
},
|
|
"conditions": [
|
|
{
|
|
"id": "needs-repair",
|
|
"leftValue": "={{ $json.needsRepair }}",
|
|
"rightValue": true,
|
|
"operator": {
|
|
"type": "boolean",
|
|
"operation": "equals"
|
|
}
|
|
}
|
|
],
|
|
"combinator": "and"
|
|
},
|
|
"options": {}
|
|
},
|
|
"id": "check-repair",
|
|
"name": "需要修復?",
|
|
"type": "n8n-nodes-base.if",
|
|
"typeVersion": 2,
|
|
"position": [900, 300]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"command": "gcloud compute ssh momo-pro-gcp --zone=asia-east1-b --project=astral-gateway-484913-d7 --command=\"sudo kubectl rollout restart deployment/momo-app -n momo && sudo kubectl rollout status deployment/momo-app -n momo --timeout=120s\" 2>&1",
|
|
"cwd": "/home/wooo"
|
|
},
|
|
"id": "repair-app",
|
|
"name": "重啟 GCP momo-app",
|
|
"type": "n8n-nodes-base.executeCommand",
|
|
"typeVersion": 1,
|
|
"position": [1120, 200],
|
|
"continueOnFail": true
|
|
},
|
|
{
|
|
"parameters": {
|
|
"amount": 30,
|
|
"unit": "seconds"
|
|
},
|
|
"id": "wait",
|
|
"name": "等待 30 秒",
|
|
"type": "n8n-nodes-base.wait",
|
|
"typeVersion": 1.1,
|
|
"position": [1340, 200]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "https://momo.wooo.work/health",
|
|
"options": {
|
|
"timeout": 30000
|
|
}
|
|
},
|
|
"id": "verify-repair",
|
|
"name": "驗證修復結果",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [1560, 200],
|
|
"continueOnFail": true
|
|
},
|
|
{
|
|
"parameters": {
|
|
"jsCode": "const repairResult = $('repair-app').first().json;\nconst verifyResult = $input.first().json;\nconst originalData = $('analyze').first().json;\nconst now = new Date().toLocaleString('zh-TW', { timeZone: 'Asia/Taipei' });\n\nlet repairSuccess = verifyResult && verifyResult.status === 'healthy';\nlet message = '';\n\nif (repairSuccess) {\n message = `✅ <b>${originalData.envIcon} GCP 正式環境自動修復成功</b>\\n\\n`;\n message += `🔧 問題: ${originalData.errorDetail}\\n`;\n message += `✨ 動作: 重啟 momo-app Pod\\n`;\n message += `📊 結果: 服務已恢復正常\\n`;\n message += `⏰ 時間: ${now}`;\n} else {\n message = `🔴 <b>${originalData.envIcon} GCP 正式環境自動修復失敗</b>\\n\\n`;\n message += `🔧 問題: ${originalData.errorDetail}\\n`;\n message += `❌ 修復嘗試未成功\\n`;\n message += `📋 需要人工介入\\n`;\n message += `🔗 SSH: gcloud compute ssh momo-pro-gcp --zone=asia-east1-b\\n`;\n message += `⏰ 時間: ${now}`;\n}\n\nreturn [{\n json: {\n repairSuccess,\n message,\n timestamp: now\n }\n}];"
|
|
},
|
|
"id": "build-notification",
|
|
"name": "建立通知訊息",
|
|
"type": "n8n-nodes-base.code",
|
|
"typeVersion": 2,
|
|
"position": [1780, 200]
|
|
},
|
|
{
|
|
"parameters": {
|
|
"url": "https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/sendMessage",
|
|
"sendBody": true,
|
|
"specifyBody": "json",
|
|
"jsonBody": "={\n \"chat_id\": \"5619078117\",\n \"parse_mode\": \"HTML\",\n \"text\": \"{{ $json.message }}\"\n}",
|
|
"options": {}
|
|
},
|
|
"id": "telegram-notify",
|
|
"name": "Telegram 通知",
|
|
"type": "n8n-nodes-base.httpRequest",
|
|
"typeVersion": 4.2,
|
|
"position": [2000, 200]
|
|
}
|
|
],
|
|
"connections": {
|
|
"每 5 分鐘檢查": {
|
|
"main": [
|
|
[{ "node": "GCP 健康檢查", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"GCP 健康檢查": {
|
|
"main": [
|
|
[{ "node": "分析健康狀態", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"分析健康狀態": {
|
|
"main": [
|
|
[{ "node": "需要修復?", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"需要修復?": {
|
|
"main": [
|
|
[{ "node": "重啟 GCP momo-app", "type": "main", "index": 0 }],
|
|
[]
|
|
]
|
|
},
|
|
"重啟 GCP momo-app": {
|
|
"main": [
|
|
[{ "node": "等待 30 秒", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"等待 30 秒": {
|
|
"main": [
|
|
[{ "node": "驗證修復結果", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"驗證修復結果": {
|
|
"main": [
|
|
[{ "node": "建立通知訊息", "type": "main", "index": 0 }]
|
|
]
|
|
},
|
|
"建立通知訊息": {
|
|
"main": [
|
|
[{ "node": "Telegram 通知", "type": "main", "index": 0 }]
|
|
]
|
|
}
|
|
},
|
|
"settings": {
|
|
"executionOrder": "v1"
|
|
},
|
|
"staticData": null,
|
|
"tags": [],
|
|
"triggerCount": 0,
|
|
"updatedAt": "2026-02-07T16:00:00.000Z",
|
|
"versionId": "1"
|
|
}
|