Webhook
Badala ya kuuliza hali mara kwa mara, mpe uendeshaji webhook_url. Ombi linapofikia hali ya mwisho (succeeded, failed au canceled), tunatuma POST iliyotiwa sahihi kwenye URL hiyo.
curl -X POST "https://api.doitong.com/v1/run/{model_id}?webhook_url=https://example.com/hooks/doitong" \
-H "Authorization: Bearer $DOITONG_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "..."}'
Tukio
POST /hooks/doitong HTTP/1.1
Content-Type: application/json
User-Agent: Doitong-Webhooks/1
Doitong-Request-Id: req_8k2m4q7x1z9c3v5b6n0p2r4t
Doitong-Signature: t=1760961609,v1=5f1c0d6e2b…
{
"id": "evt_8k2m4q7x1z9c3v5b6n0p2r4t_succeeded",
"object": "event",
"type": "request.succeeded",
"created_at": "2026-10-20T12:00:09Z",
"data": {
"id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
"object": "request",
"status": "succeeded",
"outputs": [ { "type": "video", "url": "https://content.doitong.com/dev-api/…/0-output.mp4" } ]
}
}
typenirequest.succeeded,request.failedaurequest.canceled.datani kitu kamili cha ombi, sawasawa na kileGET /requests/{id}hurudisha.idni thabiti kwa ombi na hali yake ya mwisho. Itumie kupuuza uwasilishaji ambao tayari umechakata.
Uwasilishaji na majaribio tena
Jibu kwa hali yoyote ya 2xx ndani ya sekunde 10. Kitu kingine chochote (au kuisha kwa muda) hujaribiwa tena: hadi majaribio 6 kwa jumla, baada ya sekunde 30, dakika 2, dakika 10, saa 1 na saa 6. Fanya kazi nzito baada ya kujibu, si kabla.
Thibitisha sahihi
Kila ufunguo una siri yake ya kutia sahihi. Isome mara moja kutoka GET https://api.doitong.com/v1/account (webhook_signing_secret, huanza na whsec_) na ihifadhi karibu na ufunguo.
Kichwa cha Doitong-Signature ni t=<unix time>,v1=<signature>, ambapo sahihi ni HMAC-SHA256 ya hex ya "<t>.<raw request body>" kwa siri yako kama ufunguo. Ili kuthibitisha:
- Chukua baiti mbichi za mwili sawasawa zilivyopokelewa (kabla ya uchanganuzi wowote wa JSON).
- Kokotoa HMAC-SHA256 ya
t + "." + bodykwa siri yako, kama hex ya herufi ndogo. - Linganisha na
v1kwa muda usiobadilika. - Kataa tukio wakati
tiko zaidi ya dakika 5 kutoka saa yako (ulinzi dhidi ya replay).
Kipokezi kamili katika Node.js (Express) na Python (Flask):
import crypto from "node:crypto";
import express from "express";
const SECRET = process.env.DOITONG_WEBHOOK_SECRET; // whsec_...
const app = express();
app.post("/hooks/doitong", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("Doitong-Signature") || "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
const t = Number(parts.t);
const expected = crypto.createHmac("sha256", SECRET).update(t + "." + req.body).digest("hex");
const given = Buffer.from(parts.v1 || "", "utf8");
const valid =
given.length === expected.length &&
crypto.timingSafeEqual(given, Buffer.from(expected, "utf8")) &&
Math.abs(Date.now() / 1000 - t) < 300;
if (!valid) return res.status(400).send("bad signature");
const event = JSON.parse(req.body);
if (event.type === "request.succeeded") {
console.log(event.data.id, event.data.outputs.map((o) => o.url));
}
res.sendStatus(204);
});
import hashlib
import hmac
import json
import os
import time
from flask import Flask, abort, request
SECRET = os.environ["DOITONG_WEBHOOK_SECRET"].encode() # whsec_...
app = Flask(__name__)
@app.post("/hooks/doitong")
def doitong_hook():
body = request.get_data() # raw bytes
parts = dict(p.split("=", 1) for p in request.headers.get("Doitong-Signature", "").split(",") if "=" in p)
t = parts.get("t", "0")
expected = hmac.new(SECRET, t.encode() + b"." + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, parts.get("v1", "")) or abs(time.time() - int(t)) > 300:
abort(400)
event = json.loads(body)
if event["type"] == "request.succeeded":
print(event["data"]["id"], [o["url"] for o in event["data"]["outputs"]])
return "", 204
Vidokezo
- Jibu haraka na panga uchakataji wako mwenyewe kwenye foleni.
- Siri ni ya ufunguo wa API ulioanzisha uendeshaji. Vifunguo katika huduma tofauti vina siri tofauti.