Webhooks
קבלו עדכונים בזמן אמת במקום polling. כל אירוע נשלח כ-POST JSON לכתובת HTTPS שלכם.
הגדרה
bash
curl -X POST https://smsprovider-web.vercel.app/api/v1/webhooks \
-H "Authorization: Bearer $BATLER_API_KEY" -H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/batler", "events": ["message.delivered", "message.failed", "inbound.received"]}'התשובה כוללת secret (whsec_…) — הוא מוצג פעם אחת בלבד. שמרו אותו לאימות החתימות.
אירועים
| אירוע | מתי |
|---|---|
message.sent | ההודעה נמסרה לרשת הסלולרית |
message.delivered | אישור מסירה למכשיר |
message.failed | כישלון, עם reason (למשל blocked, no_coverage, kosher_phone) |
message.expired | לא התקבל אישור מסירה בזמן |
inbound.received | תשובה נכנסת למספר השולח שלכם |
otp.verified / otp.failed | תוצאת אימות קוד |
wallet.low_balance / wallet.credited | יתרה נמוכה / רכישת קרדיטים |
blacklist.added | נמען ביקש הסרה |
link.clicked | לחיצה על קישור מעוקב |
מבנה:
json
{
"id": "4f0c7c1e-1c2b-4a0e-9d7b-2e3f4a5b6c7d",
"type": "message.delivered",
"created_at": "2026-11-02T18:00:05Z",
"data": { "message_id": "0e9b2f0a-6c1d-4f43-8c33-6f3b3f0d9a11", "to": "+972501234567", "ref": "order-123", "status": "delivered", "reason": null, "operator": "Partner", "occurred_at": "2026-11-02T18:00:04Z" }
}אימות חתימה
כל בקשה נושאת X-Batler-Signature: t=<unix seconds>,v1=<hex> כאשר v1 = HMAC-SHA256(secret, "<t>.<raw body>"), ו-X-Batler-Event-Id לזיהוי כפילויות. חשבו את החתימה על הגוף הגולמי ודחו חותמות זמן ישנות מ-5 דקות.
Node.js
ts
import { verifyWebhookSignature } from "@batler/sms";
app.post("/hooks/batler", express.raw({ type: "application/json" }), async (req, res) => {
const raw = req.body.toString("utf8");
if (!(await verifyWebhookSignature(process.env.BATLER_WEBHOOK_SECRET!, req.get("X-Batler-Signature"), raw))) return res.sendStatus(401);
const event = JSON.parse(raw);
// dedupe by req.get("X-Batler-Event-Id"), then handle event.type
res.sendStatus(200);
});PHP
php
$raw = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_BATLER_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $p);
$expected = hash_hmac('sha256', $p['t'] . '.' . $raw, getenv('BATLER_WEBHOOK_SECRET'));
if (!isset($p['v1']) || !hash_equals($expected, $p['v1']) || abs(time() - (int)$p['t']) > 300) {
http_response_code(401); exit;
}
$event = json_decode($raw, true);
http_response_code(200);Python
python
import hmac, hashlib, time
def verify(secret: str, header: str, raw: bytes) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t, v1 = parts.get("t", ""), parts.get("v1", "")
if not t.isdigit() or abs(time.time() - int(t)) > 300:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, v1)Retry
החזירו 2xx תוך 10 שניות. אחרת ננסה שוב אחרי 1 דק', 5 דק', 30 דק', 2 שעות, 6 שעות ו-24 שעות. אחרי 10 כשלונות רצופים הכתובת מושבתת ונשלח מייל. לוג המשלוחים ושליחה חוזרת: GET https://smsprovider-web.vercel.app/api/v1/webhooks/{id}/deliveries ו-…/replay.