الويب هوك
مئة حدث عبر تسعة وعشرين نطاقاً. سجّل عنواناً، وقُرب يرسل إليه عند وقوع الحدث بدل أن تستعلم أنت في حلقة.
100 حدث · 29 نطاقاً
التوقيع — معيار Standard Webhooks
كل تسليم يحمل ثلاث ترويسات، والتوقيع HMAC-SHA256 على «المعرّف.الطابع الزمني.الجسم». تحقّق منه دائماً: عنوان غير محقَّق يقبل أي طلب من أي جهة تعرف رابطه.
| الترويسات | |
|---|---|
webhook-id | ULID — dedupe on this |
webhook-timestamp | Unix seconds |
webhook-signature | v1,<base64 HMAC-SHA256> |
التحقق
استخدم مكتبة المعيار بدل كتابة المقارنة بيدك — المقارنة الساذجة عرضة لهجوم توقيت، والمكتبة تستخدم مقارنة ثابتة الزمن.
import { Webhook } from 'standardwebhooks'
import express from 'express'
const app = express()
app.post(
'/gurb/webhook',
// RAW body, not express.json(). See the note below.
express.raw({ type: 'application/json' }),
(req, res) => {
const wh = new Webhook(process.env.GURB_WEBHOOK_SECRET!)
let event
try {
event = wh.verify(req.body, {
'webhook-id': req.header('webhook-id')!,
'webhook-timestamp': req.header('webhook-timestamp')!,
'webhook-signature': req.header('webhook-signature')!,
})
} catch {
return res.status(400).send('bad signature')
}
// Answer FIRST, work after. A slow handler is a failed delivery, and a
// failed delivery is retried — so slow work becomes duplicate work.
res.sendStatus(200)
void handle(event)
},
)use StandardWebhooks\Webhook;
$raw = file_get_contents('php://input'); // RAW, before any json_decode
$wh = new Webhook(getenv('GURB_WEBHOOK_SECRET'));
try {
$event = $wh->verify($raw, [
'webhook-id' => $_SERVER['HTTP_WEBHOOK_ID'],
'webhook-timestamp' => $_SERVER['HTTP_WEBHOOK_TIMESTAMP'],
'webhook-signature' => $_SERVER['HTTP_WEBHOOK_SIGNATURE'],
]);
} catch (\Throwable $e) {
http_response_code(400);
exit;
}تحقّق من الجسم الخام لا من المُفكّك
نافذة إعادة التشغيل ٣٠٠ ثانية
تسليم أقدم من خمس دقائق يُرفض. فساعة خادمك لازم تكون مضبوطة؛ الانحراف يظهر كفشل توقيع متقطّع لا كخطأ وقت.
إعادة المحاولة والتكرار
التسليم الفاشل يُعاد. فقد يصلك الحدث نفسه مرتين — استخدم webhook-id لإزالة التكرار، وتعامل مع معالجك كأنه قد يُنادى أكثر من مرة على نفس الحدث.
الأحداث تُطلق بعد إتمام الكتابة
لا تُطلق داخل معاملة قابلة للتراجع، لأن الويب هوك لا يمكن سحبه بعد إرساله. فوصول الحدث يعني أن التغيير ثابت فعلاً.
الكتالوج
كل اسم هنا يظهر في واجهة الاشتراك عند عميلك، وكلها موصولة بمواضع إطلاق حقيقية — اسم معلن بلا إطلاق وعد مكسور، ويوجد فحص آلي يمنع ذلك.
advertisement
- advertisement.created
- advertisement.deleted
- advertisement.updated
album
- album.created
- album.deleted
- album.photo_added
- album.photo_deleted
- album.updated
api_key
- api_key.created
- api_key.revoked
app
- app.installed
- app.reinstated
- app.suspended
- app.uninstalled
award
- award.created
- award.deleted
- award.granted
- award.revoked
blog
- blog.deleted
- blog.published
- blog.unpublished
- blog.updated
comment
- comment.created
- comment.deleted
community
- community.settings_changed
- community.updated
- community.visibility_changed
consultant
- consultant.created
- consultant.status_changed
- consultant.updated
custom_domain
- custom_domain.activated
- custom_domain.added
- custom_domain.removed
- custom_domain.verified
event
- event.attendee_joined
- event.attendee_left
- event.cancelled
- event.created
- event.deleted
- event.updated
family_member
- family_member.added
- family_member.deleted
- family_member.updated
family_tree_request
- family_tree_request.approved
- family_tree_request.created
- family_tree_request.rejected
group
- group.created
- group.deleted
- group.member_added
- group.member_removed
- group.updated
group_join_request
- group_join_request.approved
- group_join_request.created
- group_join_request.rejected
invitation
- invitation.accepted
- invitation.revoked
- invitation.sent
invite_link
- invite_link.created
- invite_link.revoked
join_request
- join_request.approved
- join_request.created
- join_request.rejected
leave_request
- leave_request.approved
- leave_request.cancelled
- leave_request.created
- leave_request.rejected
member
- member.banned
- member.joined
- member.left
- member.permissions_changed
- member.removed
- member.restricted
- member.restriction_lifted
- member.role_changed
- member.unbanned
poll
- poll.voted
post
- post.created
- post.deleted
- post.pinned
- post.updated
project
- project.created
- project.status_changed
- project.updated
project_request
- project_request.created
report
- report.created
- report.dismissed
- report.resolved
subscription
- subscription.activated
- subscription.cancelled
- subscription.plan_changed
subscription_request
- subscription_request.approved
- subscription_request.created
- subscription_request.rejected
support_conversation
- support_conversation.opened
task
- task.assigned
- task.completed
- task.created
- task.deleted
- task.reopened
- task.updated
