串接說明
用 HTTP API 把系統錯誤、日報或 Job 結果送到 Operations Chat。Job Execution 是一等公民,不要只把 Cron 結果當普通文字訊息。
1. 基底網址
http://evt.nexus-ray.com
瀏覽器走 /api/...;OpenAPI:http://evt.nexus-ray.com/docs
2. 驗證
一般訊息:帳號 JWT(operator 或 admin)
curl -sS -X POST http://evt.nexus-ray.com/api/auth/token \
-H "Content-Type: application/json" \
-d '{"email":"operator@example.com","password":"your-password"}'
# 回應含 access_token之後請求加 Authorization: Bearer <access_token>。Token 約 20 分鐘過期,再打一次 /api/auth/token。
若帳號已啟用 Authenticator 雙因素驗證,第一步會回 401 且 detail.mfa_required 為 true,請用 mfa_token 與 6 位驗證碼呼叫 POST /api/auth/token/mfa 取得 token。
Job Runner:內部 Token
環境變數 INTERNAL_TOKEN,放在標頭 X-Internal-Token。不走使用者帳號。
X-Internal-Token: change-me-internal-runner-token
3. 查頻道
curl -sS http://evt.nexus-ray.com/api/channels \ -H "Authorization: Bearer $TOKEN"
記下要發話的 id(UUID)。畫面「新增頻道」建立後也會出現在此列表。
4. 發送訊息
需要 operator 或 admin。權限不足會 403。
curl -sS -X POST http://evt.nexus-ray.com/api/channels/$CHANNEL_ID/messages \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "磁碟使用率 95%",
"kind": "error",
"severity": "critical"
}'| 欄位 | 說明 |
|---|---|
| body | 必填,訊息本文(摘要,不要塞完整 log) |
| kind | text / error / warning / job_event |
| severity | 可選 info / warning / error / critical |
| thread_id | 可選,回覆某則訊息的 ULID |
5. Job 執行結果(建議)
一次執行只投影 一則 頻道訊息;開始後用同一個 id 回報完成,訊息會原地更新。
TOKEN_HDR="X-Internal-Token: change-me-internal-runner-token"
# 開始
curl -sS -X POST http://evt.nexus-ray.com/api/internal/executions \
-H "$TOKEN_HDR" -H "Content-Type: application/json" \
-d '{"job_name":"daily_sftp_sync","trigger":"cron","summary":"開始同步"}'
# 完成(把 EXEC_ID 換成上一步回傳的 id)
curl -sS -X PATCH http://evt.nexus-ray.com/api/internal/executions/$EXEC_ID \
-H "$TOKEN_HDR" -H "Content-Type: application/json" \
-d '{
"status": "failed",
"exit_code": 1,
"summary": "SFTP 連線逾時",
"error_message": "connection timed out",
"log_s3_key": "logs/daily_sftp_sync/2026-08-13/exec-id.log"
}'status 只能是 success、failed、timeout。完整 log 請上傳 S3 後只傳 log_s3_key。
6. Python 範例
import os, httpx
BASE = "http://evt.nexus-ray.com"
token = httpx.post(f"{BASE}/api/auth/token", json={
"email": os.environ["OPS_EMAIL"],
"password": os.environ["OPS_PASSWORD"],
}).json()["access_token"]
httpx.post(
f"{BASE}/api/channels/{os.environ['OPS_CHANNEL_ID']}/messages",
headers={"Authorization": f"Bearer {token}"},
json={"body": "備份完成", "kind": "text", "severity": "info"},
).raise_for_status()注意
- 直接開
/api/auth/me沒帶 Token 會 401,屬正常。 - 過濾規則命中後會依群組選用的通知方式(郵件/LINE Message)送到已設定的多個信箱或 userId,與頻道訊息分開。
- 請用 HTTPS 與專用 operator 帳號,不要把 admin 密碼寫進 Job。