Webhook — ирсэн эвент
Толгойнууд, HMAC-SHA256 гарын үсэг (Node · Python · Go), давтан илгээлт, эвентийн төрөл.
Таны URL руу POST, Content-Type: application/json, User-Agent: BuildryChat/1.0. 2xx буцаахад л амжилттай; бусдад 0.5с · 1с · 2с-ийн дараа дахин (нийт 4 оролдлого, тус бүр 10с timeout). 20 дараалсан алдаанд webhook paused болно — dashboard-д URL-аа дахин хадгалахад сэргэнэ (нууц шинээр гарна). Хүргэлтийн лог 14 хоног dashboard/GET /v1/webhook/deliveries-д.
Толгойнууд: X-Buildry-Event · X-Buildry-Delivery (uuid, давхардлыг үүгээр таслана) · X-Buildry-Timestamp (unix сек) · X-Buildry-Signature: sha256=<hex>.
Гарын үсэг шалгах
Гарын үсэг: HMAC-SHA256(secret, timestamp + "." + raw_body). Body-г түүхий байтаар (parse хийхээс өмнө) авна.
// Node (Express: app.use(express.raw({ type: "*/*" })))
const crypto = require("crypto");
function verify(req, secret) {
const ts = req.header("X-Buildry-Timestamp");
const sig = (req.header("X-Buildry-Signature") || "").replace("sha256=", "");
const mac = crypto.createHmac("sha256", secret).update(ts + "." + req.body).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300; // 5 мин replay цонх
return fresh && sig.length === mac.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(mac));
}import hmac, hashlib, time
def verify(headers, raw_body: bytes, secret: str) -> bool:
ts = headers["X-Buildry-Timestamp"]
sig = headers.get("X-Buildry-Signature", "").removeprefix("sha256=")
mac = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
return abs(time.time() - int(ts)) < 300 and hmac.compare_digest(sig, mac)import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"math"
"net/http"
"strconv"
"strings"
"time"
)
// rawBody = io.ReadAll(r.Body) — JSON задлахаас өмнө.
func verify(h http.Header, rawBody []byte, secret string) bool {
ts := h.Get("X-Buildry-Timestamp")
sec, err := strconv.ParseInt(ts, 10, 64)
if err != nil || math.Abs(float64(time.Now().Unix()-sec)) >= 300 { // 5 мин replay цонх
return false
}
sig, err := hex.DecodeString(strings.TrimPrefix(h.Get("X-Buildry-Signature"), "sha256="))
if err != nil {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(rawBody)
return hmac.Equal(sig, mac.Sum(nil))
}Дугтуй ба эвентүүд
Дугтуй:
{ "id": "<delivery uuid>", "event": "message.received", "created_at": "2026-09-08T08:00:00Z", "data": { … } }| event | data |
|---|---|
message.received | workspace_id, conversation_id, platform (messenger·instagram·telegram·webchat), channel{kind, external_id}, contact{id, sender_id, name, profile_pic}, message{id, text, type, external_id, created_at, attachment?{url,type}} |
postback.received | дээрхтэй ижил + postback{payload, received_at} — таны илгээсэн товчны payload |
comment.received | workspace_id, platform, channel, comment{id, post_id, text, from{id,name}, received_at} |
test | workspace_id, sent_at — «Тест илгээх» товч / POST /v1/webhook/test |
Зөвхөн ҮЙЛЧЛҮҮЛЭГЧИЙН ирсэн зүйл дамжина — таны өөрийн хариу, OpenBot-ийн inbox-оос бичсэн хариу, page-ийн өөрийн коммент ХЭЗЭЭ Ч ирэхгүй (давталт үүсгэхгүй).
Webhook-оо API-аар удирдах
Dashboard-гүйгээр:
GET /v1/webhook·PUT /v1/webhook {url}→{webhook, secret}(secret нэг удаа) ·DELETE /v1/webhook·POST /v1/webhook/test→{delivery}·GET /v1/webhook/deliveries?limit=