ওয়েবহুক
একটি এনভায়রনমেন্টে যা ঘটে, Usher তা ঘটার সাথে সাথে আপনার সার্ভারকে জানাতে পারে: কেউ যোগ দিলেন, সাইন ইন করলেন, তাঁর তথ্য বদলালেন বা চলে গেলেন। প্রতিটি ইভেন্ট আপনার বেছে নেওয়া ঠিকানায় একটি সাইন করা POST, আপনার সার্ভার উত্তর না দিলে আবার চেষ্টা করা হয়।
একটি এন্ডপয়েন্ট যোগ করুন
Usher Console-এ এনভায়রনমেন্টটি খুলুন, তারপর ওয়েবহুক → নতুন এন্ডপয়েন্ট। আপনার একটি https:// ঠিকানা দিন এবং বেছে নিন এটি কোন ইভেন্টগুলির খবর পাবে। Console এন্ডপয়েন্টের সাইনিং সিক্রেট (whsec_…) একবার দেখায়: এটি আপনার সার্ভারের অন্যান্য সিক্রেটের সাথে রাখুন।
| ইভেন্ট | কখন |
|---|---|
user.created | কেউ একটি অ্যাকাউন্ট তৈরি করেছেন |
user.updated | একটি অ্যাকাউন্ট বদলেছে: ইমেল, নাম, যাচাই বা নিষেধাজ্ঞা (আপনার প্রতিষ্ঠানের ডিরেক্টরি থেকে SCIM-এর মাধ্যমে দেওয়া নিষেধাজ্ঞাসহ) |
user.deleted | একটি অ্যাকাউন্ট মুছে ফেলা হয়েছে |
session.created | কেউ সাইন ইন করেছেন |
session.ended | একটি সেশন শেষ হয়েছে: সাইন আউট, বাতিল, বা মেয়াদের আগেই শেষ |
পরীক্ষা পাঠান কেবল সেই এন্ডপয়েন্টে একটি webhook.test ইভেন্ট পাঠায়, এটি যে ইভেন্টগুলিতেই সাবস্ক্রাইব করা থাকুক না কেন।
যা আসে
POST /usher/webhooks HTTP/1.1
content-type: application/json
user-agent: Usher-Webhooks/1
webhook-id: msg_2fk7x…
webhook-timestamp: 1793643116
webhook-signature: v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE={
"type": "user.created",
"timestamp": "2026-11-02T18:11:56.412Z",
"data": {
"user": {
"id": "Qz3m…",
"email": "lena@acme.com",
"emailVerified": false,
"name": "Lena Live",
"image": null,
"banned": false,
"createdAt": "2026-11-02T18:11:56.380Z",
"updatedAt": "2026-11-02T18:11:56.380Z"
}
}
}ইভেন্টগুলি মানুষ ও সেশনের বর্ণনা দেয়, কখনও সিক্রেটের নয়: কোনো টোকেন নয়, কোনো পাসওয়ার্ড হ্যাশ নয়, কোনো ভূমিকা নয়, এবং কেন কাউকে নিষিদ্ধ করা হয়েছে তাও নয়।
প্রতিটি ডেলিভারি যাচাই করুন
Usher Standard Webhooks স্পেসিফিকেশন অনুযায়ী সাইন করে, তাই এর যেকোনো লাইব্রেরি আপনার হয়ে সিগনেচার যাচাই করে। যা যাচাই হয় না তা প্রত্যাখ্যান করুন। লাইব্রেরিগুলি পাঁচ মিনিটের বেশি দূরের টাইমস্ট্যাম্পও প্রত্যাখ্যান করে, তাই পুরনো ডেলিভারি আবার চালানো যায় না।
// a route that receives Usher's webhooks (Node, the standardwebhooks package)
import { Webhook } from 'standardwebhooks'
const wh = new Webhook(process.env.USHER_WEBHOOK_SECRET!) // whsec_…, from Usher Console
export async function POST(request: Request) {
const body = await request.text() // the raw body: the signature covers it byte for byte
let event: { type: string; timestamp: string; data: Record<string, unknown> }
try {
event = wh.verify(body, Object.fromEntries(request.headers)) as typeof event
} catch {
return new Response('bad signature', { status: 400 })
}
// webhook-id is the same on every attempt: skip one you have handled already
if (await alreadyHandled(request.headers.get('webhook-id')!)) return new Response(null, { status: 204 })
await queue(event) // answer quickly; do the work afterwards
return new Response(null, { status: 204 })
}- 15 সেকেন্ডের মধ্যে উত্তর দিন যেকোনো
2xxদিয়ে। অন্য যেকোনো কিছু, রিডাইরেক্টসহ, ব্যর্থতা হিসেবে গণ্য হয়। - পুনরাবৃত্তি আশা করুন। প্রতিটি চেষ্টায় একটি মেসেজের
webhook-idএকই থাকে; যেটি আপনি সামলে ফেলেছেন সেটি এড়িয়ে যান। - ক্রমের উপর নির্ভর করবেন না। আবার পাঠানো মেসেজ নতুন ইভেন্টের পরে আসতে পারে।
আপনার সার্ভার উত্তর না দিলে
Usher 5 সেকেন্ড, 5 মিনিট, 30 মিনিট, 2 ঘণ্টা, 5 ঘণ্টা, 10 ঘণ্টা ও 10 ঘণ্টা পরে আবার চেষ্টা করে (সব মিলিয়ে প্রায় দেড় দিন), তারপর থেমে যায়। Console-এর ডেলিভারি লগ প্রতিটি মেসেজের চেষ্টাগুলি এবং আপনার সার্ভারের শেষ উত্তর দেখায়, আর আবার পাঠান একটি ডেলিভারি নতুন করে শুরু করে।
নতুন সিক্রেট
Console-এ নতুন সিক্রেট আরেকটি সিক্রেট তৈরি করে এবং সেটি একবার দেখায়। পরের 24 ঘণ্টা প্রতিটি ডেলিভারিতে দুটি সিগনেচার থাকে, প্রতিটি সিক্রেটের জন্য একটি, যাতে কিছু না হারিয়েই আপনি নতুন সিক্রেট ডিপ্লয় করতে পারেন। তারপর কেবল নতুনটি সাইন করে।
ডেলিভারি কোথা থেকে আসে
ওয়েবহুক Usher থেকে বের হয় তার ইগ্রেস প্রক্সি দিয়ে, যা প্রাইভেট বা অভ্যন্তরীণ ঠিকানায় সংযোগ করে না। একটি এন্ডপয়েন্ট অবশ্যই একটি পাবলিক নামের https:// ঠিকানা হতে হবে: কোনো IP ঠিকানা, প্রাইভেট নাম, বা Usher-এর নিজের ডোমেইনের ঠিকানা নয়।