نمایک، نیاز اول کسب و کارها
پرش به محتوای اصلی

وب‌هوک‌های پشتیبان‌گیری

رویدادهای پشتیبان‌گیری موفق، ناموفق و جامانده، بازگردانی و عامل؛ با همان پاکت و امضای HMAC وب‌هوک‌های نمایک.

در این صفحه

رویدادها

نشانی وب‌هوک را در پنل یا با API وب‌هوک بسازید و رویدادهای پشتیبان‌گیری را انتخاب کنید. کلیدهای data فقط همین‌هایند؛ بایت‌ها رشته‌اند.

رویدادهای پشتیبان‌گیری و کلیدهای data
نوعنوع / مقدارتوضیح
backup.succeededپشتیبان‌گیری موفقsourceId، sourceName، snapshotId، jobId، engine، trigger، startedAt، completedAt، durationMs، fileBytes، rawBytes، verifyState
backup.failedپشتیبان‌گیری ناموفقsourceId، sourceName، jobId، engine، trigger، attempt، willRetry، consecutiveFailures، errorCode، errorMessage، failedAt
backup.missedپشتیبان‌گیری جاماندهsourceId، sourceName، jobId، scheduledFor، reason (agent_offline | not_started)، consecutiveMissed
backup.verification_failedرد شدن بررسی یکپارچگیsourceId، snapshotId، level، errorCode، detectedAt
restore.completedپایان بازگردانیrestoreId، sourceId، snapshotId، mode، target، durationMs، completedAt
restore.failedخطای بازگردانیrestoreId، sourceId، snapshotId، mode، target، errorCode، errorMessage، failedAt
agent.offlineقطع شدن عاملagentId، agentName، lastSeenAt، offlineSince، sourcesCount
agent.onlineوصل شدن دوباره عاملagentId، agentName، onlineAt، sourcesCount

نمونه پیام

errorMessage متن فارسی نگاشت‌شده است، هرگز خروجی خام ابزار. هر رویداد شناسه یکتا دارد؛ تکراری‌ها را با آن کنار بگذارید.

backup.failed
{  "id": "evt_0000000000000000000001",  "type": "backup.failed",  "created": "2026-10-23T10:00:00.000Z",  "data": {    "sourceId": "00000000-0000-4000-8000-000000000001",    "sourceName": "shop-main",    "jobId": "00000000-0000-4000-8000-000000000002",    "engine": "postgres",    "trigger": "schedule",    "attempt": 1,    "willRetry": true,    "consecutiveFailures": 1,    "errorCode": "CONNECTION_FAILED",    "errorMessage": "اتصال به پایگاه داده برقرار نشد",    "failedAt": "2026-10-23T10:00:00.000Z"  }}

بررسی امضا

امضا همان امضای همه وب‌هوک‌های نمایک است؛ پیش از هر پردازش، امضا و پنجره زمانی ۳۰۰ ثانیه را بسنجید:

کد
v1 = hex( HMAC-SHA256( key = utf8(secret شامل "whsec_"), message = utf8(t + "." + rawBody) ) )
import crypto from "node:crypto"; const TOLERANCE_SECONDS = 300; /** rawBody همان بایت‌های دریافتی است، پیش از JSON.parse */export function verifyNamayekSignature(rawBody, header, secret, now = Date.now()) {  const parts = String(header || "").split(",").map((p) => p.trim().split("="));  const t = Number(parts.find(([k]) => k === "t")?.[1]);  const signatures = parts.filter(([k, v]) => k === "v1" && /^[0-9a-f]{64}$/.test(v || "")).map(([, v]) => v);  if (!Number.isInteger(t) || signatures.length === 0) return false;  if (Math.abs(Math.floor(now / 1000) - t) > TOLERANCE_SECONDS) return false; // replay  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`, "utf8").digest();  return signatures.some((sig) => crypto.timingSafeEqual(expected, Buffer.from(sig, "hex")));} // Express: بدنه خام را نگه دارید// app.post("/hooks/namayek", express.raw({ type: "application/json" }), (req, res) => {//   if (!verifyNamayekSignature(req.body.toString("utf8"), req.get("Namayek-Signature"), process.env.NAMAYEK_WEBHOOK_SECRET)) {//     return res.sendStatus(400);//   }//   const event = JSON.parse(req.body.toString("utf8"));//   res.sendStatus(200); // سریع پاسخ دهید؛ پردازش در صف// });

آخرین به‌روزرسانی: