通知
當有事情需要處理時,Zenavo 會發郵件通知你的團隊,這樣你就不用一直開著控制台;同樣的告警也可以傳送到 Slack、Discord、Telegram 或你自己的 Webhook。
事件
| 事件 | 何時傳送 |
|---|---|
| 部署失敗 | 部署或回滾沒有完成。郵件會說明是在建置服務時失敗,還是在發布時失敗。 |
| 伺服器設定失敗 | 伺服器的初始化或重灌沒有完成。郵件會給出原因,以及為重試保留 SSH 憑據的截止時間。 |
| 服務已暫停 | 服務重啟次數超過了它的崩潰限制,已被停止。 |
| 伺服器離線 | 伺服器連續 3 次狀態檢查沒有回應(約 3 分鐘)。恢復回應時會再發一封郵件。 |
| 磁碟或記憶體即將用盡 | 伺服器磁碟使用率超過 90%,或者記憶體連續 3 次檢查都超過 90%。使用率降到 85% 以下後才會再次告警。 |
| 新的 SSH 登入來源 | 有 IP 位址第一次透過 SSH 登入了團隊的某台伺服器。如果你剛從新的網路連線過,這是正常的;否則是一個警告訊號。 |
| 用量上限 | 團隊的映像檔傳輸達到了本帳單週期允許額度的 80% 或 100%。達到 100% 時,伺服器將停止拉取新映像檔。 |
對於同一個專案、服務或伺服器,每種告警每小時最多傳送一次。偶爾一兩次檢查沒有回應不會傳送任何通知。
關於你自己帳號的安全郵件(新裝置登入、批准的 CLI 登入、新的 API 金鑰)見安全。它們只發給你本人,對所有角色預設開啟,顯示在通知頁面的 安全 下。
誰會收到
郵件發給擁有該專案或伺服器的團隊的成員:
- 擁有者和管理員 預設接收所有事件,除非自己關閉。
- 成員 預設不接收,需要自己開啟。
- 觀察者 永遠不會收到通知。
在 帳號設定 → 通知 中選擇你要接收的事件。這個選擇按帳號生效,適用於你所在的所有團隊。
郵件內容
專案、服務或伺服器的名稱、時間(UTC),以及控制台中對應頁面的連結。郵件中從不包含變數值、機密、指令或日誌文字。要檢視日誌,請開啟控制台。
通知管道
團隊管理員還可以把團隊的通知傳送到聊天工具和 Webhook:帳號設定 → 通知 → 團隊通知管道,作用於側邊欄中選中的團隊。每個管道可以選擇自己的事件;除了上面的事件,管道還可以接收 部署成功(從不發郵件)。管道收到的告警與郵件相同,同樣每小時最多一次,並且不受任何人的郵件設定影響。
| 管道 | 需要什麼 |
|---|---|
| Slack | 頻道的 Incoming Webhook 位址(https://hooks.slack.com/services/…)。 |
| Discord | 頻道 Webhook:頻道設定 → 整合 → Webhook(https://discord.com/api/webhooks/…)。 |
| Telegram | 從 @BotFather 取得的機器人權杖,以及聊天 ID(例如 -1001234567890 這樣的數字,或公開頻道的 @username)。請先把機器人加入聊天。 |
| Webhook | 任意 https:// 位址。Zenavo 會向它 POST 簽名後的 JSON(見下文)。 |
測試 會立即傳送一條訊息,並顯示是否送達。每個管道都會顯示最近一次傳送的結果或失敗原因;傳送失敗會在大約 13 分鐘內重試三次。每個團隊最多 20 個管道。
Webhook 位址和機器人權杖都屬於機密:它們加密儲存,控制台只顯示主機或聊天。Zenavo 只向所有位址都是公開網路位址的主機傳送,並且不跟隨重定向。
Webhook 請求內容
{
"type": "deploy_failed",
"team_id": "team_…",
"subject": "Deployment failed: shop",
"text": "The deployment of project \"shop\" failed at 2026-10-19 08:12 UTC.\nIt failed while building service \"web\".\n",
"url": "https://zenavo.app/projects/proj_…/deployments/job_…",
"time": "2026-10-19T08:12:03Z"
}type 是 deploy_failed、deploy_succeeded、service_suspended、server_offline(伺服器恢復時也會傳送)、server_resources、usage_limit 或 test 之一。任何 2xx 回應都視為已送達。
每個請求都帶有 X-Zenavo-Event、X-Zenavo-Timestamp(Unix 秒)和 X-Zenavo-Signature: v1=<hex>,後者是用管道的簽名金鑰對 <timestamp>.<原始請求體> 計算的 HMAC-SHA256。金鑰(whsec_…)在新增 Webhook 時只顯示一次;編輯 不會再次顯示它,但可以透過 API 更換。請基於原始位元組驗證簽名,並拒絕過舊的時間戳:
import crypto from 'node:crypto'
function verify(rawBody, headers, secret) {
const ts = headers['x-zenavo-timestamp']
const expected = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex')
const given = headers['x-zenavo-signature'] ?? ''
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300
const a = Buffer.from(given), b = Buffer.from(expected)
return fresh && a.length === b.length && crypto.timingSafeEqual(a, b)
}