API Webhooks ของ Rivya
สร้างจุดเชื่อมต่อเว็บฮุก Rivya API แบบลงลายเซ็น ตรวจลายเซ็นการส่ง ดูความพยายามส่ง และส่งเหตุการณ์ทดสอบอย่างปลอดภัย
ตรวจล่าสุดเมื่อ 2026/05/11
ใช้เว็บฮุก API เมื่อระบบเชื่อมต่อของคุณต้องการให้ Rivya แจ้งเซิร์ฟเวอร์หลังงานสร้างผ่าน Public API เข้าสู่สถานะสิ้นสุด
การตรวจสถานะซ้ำด้วย GET /api/v1/generations/{taskId} ยังคงรองรับอยู่ ส่วนเว็บฮุกเพิ่มการเรียกกลับแบบลงลายเซ็นสำหรับระบบจริงที่ต้องการให้ส่งเหตุการณ์เข้ามาโดยตรง
ขอบเขตสิทธิ์ที่จำเป็น
การจัดการเว็บฮุกต้องใช้คีย์ API ที่มี:
webhooks:manageคีย์ใหม่ที่สร้างในการตั้งค่าจะมีขอบเขตสิทธิ์นี้ตามค่าเริ่มต้น
สร้างจุดเชื่อมต่อ
POST /api/v1/webhookscurl https://rivya.ai/api/v1/webhooks \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Production webhook",
"url": "https://example.com/rivya/webhook",
"event_types": ["generation.succeeded", "generation.failed"]
}'ผลตอบกลับมี signing_secret เพียงครั้งเดียว:
{
"id": "whend_...",
"object": "webhook_endpoint",
"name": "Production webhook",
"url": "https://example.com/rivya/webhook",
"event_types": ["generation.succeeded", "generation.failed"],
"status": "active",
"secret_preview": "whsec_12...abc123",
"signing_secret": "whsec_...",
"last_success_at": null,
"last_failure_at": null,
"failure_count": 0,
"created_at": "2026-05-11T00:00:00.000Z",
"updated_at": "2026-05-11T00:00:00.000Z",
"disabled_at": null,
"revoked_at": null
}เก็บค่าลับแบบเต็มไว้บนเซิร์ฟเวอร์ของคุณ หากทำหาย ให้เรียกจุดเชื่อมต่อสำหรับหมุนเวียนค่าลับ แล้วอัปเดตตัวรับเว็บฮุก
กฎ URL
URL ของจุดเชื่อมต่อต้องใช้ HTTPS โดย Rivya จะปฏิเสธ URL ที่มีข้อมูลรับรอง ส่วนย่อย ชื่อโฮสต์ localhost หรือที่อยู่เครือข่ายภายใน
Rivya ส่งเสมอ:
POSTContent-Type: application/jsonไม่มีส่วนหัวคำขอแบบกำหนดเองที่ผู้ใช้ควบคุม
ไม่ติดตามการเปลี่ยนเส้นทางอัตโนมัติ
กำหนดเวลาหมดอายุของการส่งให้สั้น
เหตุการณ์ที่รองรับ
ประเภทเหตุการณ์ปัจจุบัน:
generation.succeededgeneration.failed
ข้อมูลเหตุการณ์ของเว็บฮุกใช้ตัวแปลงข้อมูลงานสร้างสาธารณะชุดเดียวกับจุดเชื่อมต่อสถานะ
{
"id": "evt_...",
"type": "generation.succeeded",
"api_version": "2026-05-11",
"created_at": "2026-05-11T00:00:00.000Z",
"data": {
"generation": {
"id": "task_public_id",
"status": "succeeded",
"model": "z-image",
"reserved_credits": 1,
"final_credits": 1,
"created_at": "2026-05-11T00:00:00.000Z",
"updated_at": "2026-05-11T00:01:00.000Z",
"result": {
"primary_url": "https://...",
"urls": ["https://..."]
},
"error": null
}
}
}ส่วนหัวสำหรับการส่งเหตุการณ์
การส่งแต่ละครั้งมี:
Rivya-Webhook-Id: evt_...
Rivya-Webhook-Timestamp: 1778467200
Rivya-Webhook-Signature: v1=<hex-hmac-sha256>
Rivya-Webhook-Attempt: 1
Rivya-Webhook-Endpoint-Id: whend_...
Rivya-Request-Id: req_...อินพุตสำหรับสร้างลายเซ็น:
${timestamp}.${rawBody}อัลกอริทึม:
HMAC-SHA256 โดยใช้ข้อมูลลับสำหรับลงลายเซ็นของจุดเชื่อมต่อปฏิเสธคำขอที่มีเวลาประทับเก่าเกินไป โดยค่าคลาดเคลื่อนห้านาทีเป็นค่าเริ่มต้นที่เหมาะกับการใช้งานจริง
การตรวจยืนยันด้วย JavaScript
import crypto from "node:crypto";
function verifyRivyaWebhook({ rawBody, headers, signingSecret }) {
const timestamp = headers["rivya-webhook-timestamp"];
const signature = headers["rivya-webhook-signature"] || "";
const actual = signature.split(",").find((part) => part.startsWith("v1="))?.slice(3);
const expected = crypto
.createHmac("sha256", signingSecret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
if (!actual) return false;
return crypto.timingSafeEqual(Buffer.from(actual, "hex"), Buffer.from(expected, "hex"));
}การตรวจยืนยันด้วย Python
import hmac
import hashlib
def verify_rivya_webhook(raw_body: str, headers: dict, signing_secret: str) -> bool:
timestamp = headers.get("rivya-webhook-timestamp", "")
signature = headers.get("rivya-webhook-signature", "")
actual = next((part[3:] for part in signature.split(",") if part.startswith("v1=")), "")
expected = hmac.new(
signing_secret.encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256,
).hexdigest()
return bool(actual) and hmac.compare_digest(actual, expected)จัดการจุดเชื่อมต่อ
GET /api/v1/webhooks
GET /api/v1/webhooks/{endpointId}
PATCH /api/v1/webhooks/{endpointId}
DELETE /api/v1/webhooks/{endpointId}
POST /api/v1/webhooks/{endpointId}/rotate-secretcurl https://rivya.ai/api/v1/webhooks \
-H "Authorization: Bearer rvya_sk_..."
curl https://rivya.ai/api/v1/webhooks/whend_... \
-H "Authorization: Bearer rvya_sk_..."
curl -X PATCH https://rivya.ai/api/v1/webhooks/whend_... \
-H "Authorization: Bearer rvya_sk_..." \
-H "Content-Type: application/json" \
-d '{"status":"disabled"}'
curl -X POST https://rivya.ai/api/v1/webhooks/whend_.../rotate-secret \
-H "Authorization: Bearer rvya_sk_..."DELETE /api/v1/webhooks/{endpointId} จะปิดใช้จุดเชื่อมต่อ แต่ไม่ลบประวัติการส่ง
บันทึกการส่ง
ดูเหตุการณ์ล่าสุด:
GET /api/v1/webhook-eventscurl https://rivya.ai/api/v1/webhook-events \
-H "Authorization: Bearer rvya_sk_..."ดูประวัติการลองส่งสำหรับจุดเชื่อมต่อ:
GET /api/v1/webhooks/{endpointId}/deliveriescurl https://rivya.ai/api/v1/webhooks/whend_.../deliveries \
-H "Authorization: Bearer rvya_sk_..."บันทึกการส่งประกอบด้วยสถานะ สถานะ HTTP จำนวนครั้งที่ลอง รหัสคำขอ ระยะเวลา ตัวอย่างคำตอบที่ตัดให้สั้น และฟิลด์ข้อผิดพลาดสาธารณะ
เหตุการณ์ทดสอบ
ส่งข้อมูลทดสอบที่ปลอดภัย:
POST /api/v1/webhooks/{endpointId}/testcurl -X POST https://rivya.ai/api/v1/webhooks/whend_.../test \
-H "Authorization: Bearer rvya_sk_..."เหตุการณ์ทดสอบใช้ webhook.test โดยไม่สร้างงาน ไม่ใช้เครดิต และไม่มี URL ผลลัพธ์จริง
นโยบายการลองใหม่
Rivya ถือว่า HTTP 2xx สำเร็จ
ความล้มเหลวครอบคลุมข้อผิดพลาดเครือข่าย การหมดเวลา คำตอบเปลี่ยนเส้นทาง และคำตอบที่ไม่ใช่ 2xx โดย Rivya ลองส่งซ้ำได้สูงสุดห้าครั้ง:
ทันที
หลัง 1 นาที
หลัง 5 นาที
หลัง 30 นาที
หลัง 2 ชั่วโมง
หลังการลองส่งครั้งสุดท้าย เหตุการณ์จะถูกทำเครื่องหมายเป็น failed
ความล้มเหลวในการส่งเว็บฮุกไม่เปลี่ยนสถานะงาน เครดิต การคืนเงิน หรือประวัติงาน
รายการตรวจสอบความปลอดภัย
ตรวจลายเซ็น HMAC ก่อนแปลงข้อมูลและทำงานตามตรรกะธุรกิจ
ปฏิเสธเวลาประทับที่เก่าเกินไป
แยกเหตุการณ์ทดสอบออกจากเหตุการณ์ของงานสร้าง
อย่าบันทึกข้อมูลลับสำหรับลงลายเซ็นแบบเต็มลงในบันทึกระบบ
คืน
2xxหลังระบบรับข้อมูลของคุณยอมรับเหตุการณ์แล้วเท่านั้นใช้การตรวจสถานะซ้ำเป็นทางสำรองสำหรับการกระทบยอด
