Žiniatinklio kabliukai
Užuot vykdę apklausą, perduokite vykdymui webhook_url. Kai užklausa pasiekia galutinę būseną (succeeded, failed arba
canceled), šiuo URL išsiunčiame pasirašytą POST užklausą.
curl -X POST "https://api.doitong.ru/v1/run/{model_id}?webhook_url=https://example.com/hooks/doitong" \
-H "Authorization: Bearer $DOITONG_API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt": "..."}'
Įvykis
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" } ]
}
}
typeyrarequest.succeeded,request.failedarbarequest.canceled.datayra visas užklausos objektas, tiksliai toks, kokį grąžinaGET /requests/{id}.idyra nekintantis užklausai ir jos galutinei būsenai. Naudokite jį, kad ignoruotumėte jau apdorotą pristatymą.
Pristatymai ir pakartotiniai bandymai
Per 10 sekundžių atsakykite bet kuria 2xx būsena. Bet kas kita (arba skirtasis laikas) sukelia pakartotinį bandymą: iš viso iki 6 bandymų,
praėjus 30 sekundžių, 2 minutėms, 10 minučių, 1 valandai ir 6 valandoms. Lėtą darbą atlikite po atsakymo, o ne prieš jį.
Parašo tikrinimas
Kiekvienas raktas turi savo pasirašymo paslaptį. Vieną kartą perskaitykite ją naudodami GET https://api.doitong.ru/v1/account (webhook_signing_secret,
jo pradžia yra whsec_) ir saugokite kartu su raktu.
Antraštė Doitong-Signature yra t=<unix time>,v1=<signature>, kur parašas yra šešioliktainis
HMAC-SHA256 eilutei "<t>.<raw request body>", naudojant jūsų paslaptį kaip raktą. Norėdami patikrinti:
- Paimkite neapdorotus kūno baitus tiksliai taip, kaip jie gauti (prieš atliekant bet kokį JSON analizavimą).
- Apskaičiuokite
t + "." + bodyHMAC-SHA256 su savo paslaptimi, pateikdami rezultatą mažosiomis šešioliktainėmis raidėmis. - Palyginkite jį su
v1pastovaus laiko režimu. - Atmeskite įvykį, kai
tnuo jūsų laikrodžio skiriasi daugiau nei 5 minutėmis (apsauga nuo pakartotinio atkūrimo).
Visas gavėjo pavyzdys naudojant Node.js (Express) ir 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
Patarimai
- Atsakykite greitai ir įtraukite savo apdorojimą į eilę.
- Paslaptis priklauso API raktui, kuriuo pradėtas vykdymas. Skirtingų paslaugų raktai turi skirtingas paslaptis.