انتقل إلى المحتوى الرئيسي

إخطارات آلية

Ithbat يرسل HTTP POST Requests إلى الـ Endpoints لديك عند وقوع أحداث في المستفيد. استخدم إخطارات آلية لمزامنة أنظمتك -- مثلًا Sync المستخدمين مع CRM عند التسجيل، تنبيه فريق الأمان عند قفل حساب، أو تحديث قاعدة بيانات التدقيق بشكل فوري.


آلية العمل

عند تشغيل حدث مشترك فيه، Ithbat:

  1. يحوّل الـ Event Payload لصيغة JSON.
  2. يوقّع الـ Payload بـ HMAC-SHA256 باستخدام الـ مفتاح توقيع الإخطار.
  3. يرسل HTTP POST للـ Endpoint بـ timeout مدته 30 ثانية.
  4. يسجّل محاولة التسليم (Status Code و Response Body) في الـ Delivery Log.

التسليم غير متزامن -- الإجراء الذي أطلق الحدث يكتمل بشكل مستقل عن الـ إخطار آلي delivery. الـ Endpoint يجب يرجع 2xx Status Code لكي يُعتبر التسليم ناجح.


إنشاء إخطار آلي

عبر لوحة تحكم المسؤول

  1. انتقل إلى الإعدادات > إخطارات آلية > إضافة إخطار آلي.
  2. أدخل الاسم وEndpoint URL (يجب https:// في Production).
  3. اختر الأحداث الذي تريد تشترك فيها.
  4. انقر حفظ. Ithbat ينشئ Signing Secret (whsec_...) -- انسخه الحين.

عبر API

POST /api/v1/webhooks
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"name": "Production إخطار آلي",
"url": "https://your-app.example.com/webhooks/ithbat",
"events": [
"user.created",
"user.deleted",
"auth.login",
"auth.failed",
"security.lockout",
"role.assigned"
]
}

Response:

{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"tenantId": "c2e3f4a5-...",
"name": "Production إخطار آلي",
"url": "https://your-app.example.com/webhooks/ithbat",
"secret": "whsec_1a2b3c4d5e6f...",
"events": ["user.created", "user.deleted", "auth.login", "auth.failed", "security.lockout", "role.assigned"],
"isActive": true,
"createdAt": "2026-02-24T10:00:00Z",
"updatedAt": "2026-02-24T10:00:00Z"
}
تحذير

حقل secret يُرجع فقط عند الإنشاء. خزّنه في secrets manager. للحصول على Secret جديد، استخدم الـ Regenerate Endpoint.


Event Catalog

اشترك في أي تركيبة من الأحداث التالية.

أحداث المستخدمين

الحدثيُطلَق عند
user.createdإنشاء مستخدم جديد (مباشر، SCIM، JIT، أو دعوة)
user.updatedتحديث الملف الشخصي لمستخدم
user.deletedحذف حساب مستخدم نهائيًا
user.suspendedإيقاف حساب مستخدم
user.reactivatedإعادة تفعيل حساب موقوف

أحداث المصادقة

الحدثيُطلَق عند
auth.loginمصادقة ناجحة
auth.logoutتسجيل خروج
auth.failedفشل محاولة مصادقة
auth.mfa_verifiedاجتياز MFA بنجاح

أحداث الأمان

الحدثيُطلَق عند
security.password_changedتغيير كلمة المرور
security.mfa_enabledتفعيل MFA
security.lockoutقفل حساب بعد محاولات فاشلة

أحداث الأدوار

الحدثيُطلَق عند
role.assignedتعيين دور لمستخدم
role.revokedإزالة دور من مستخدم
role.createdإنشاء دور جديد
role.deletedحذف دور

أحداث المجموعات

الحدثيُطلَق عند
group.member_addedإضافة مستخدم لمجموعة
group.member_removedإزالة مستخدم من مجموعة

أحداث SCIM

الحدثيُطلَق عند
scim.user_syncedإنشاء أو تحديث مستخدم عبر SCIM
scim.group_syncedإنشاء أو تحديث مجموعة عبر SCIM

أحداث الدعوات

الحدثيُطلَق عند
invitation.sentإرسال دعوة بالبريد الإلكتروني
invitation.acceptedقبول الدعوة وإكمال إعداد الحساب

Payload Format

جميع الـ إخطار آلي deliveries تشترك في نفس البنية. حقل event يخبرك بما حدث وكائن payload يتضمن البيانات.

{
"id": "e7f8a9b0-1234-4abc-def0-1234567890ab",
"event": "user.created",
"tenantId": "c2e3f4a5-6b7c-8d9e-0f1a-2b3c4d5e6f70",
"timestamp": "2026-02-24T10:00:00Z",
"test": false,
"payload": {
"userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"status": "active",
"createdAt": "2026-02-24T10:00:00Z"
}
}

في الـ Test deliveries (عبر زر إرسال اختبار أو API)، "test": true والـ Payload كائن مبسّط.


Signature Verification

كل delivery يتضمن Header X-إخطار آلي-Signature فيه HMAC-SHA256 hex digest للـ raw Request Body، موقّع بالـ مفتاح توقيع الإخطار.

صيغة الـ Signature: HMAC-SHA256 hex-encoded (بدون prefix -- سلسلة 64 حرف lowercase hex).

صيغة الـ Secret: whsec_ + 64 حرف hex (الـ whsec_ prefix جزء من الـ HMAC key).

آلية التوقيع

signature = HMAC-SHA256(secret, raw_request_body)
header value = hex.encode(signature)

الـ raw Request Body هو البايتات الفعلية المُستلمة، قبل أي JSON parsing.

أمثلة التحقق

Node.js

const crypto = require('crypto');

function verifyإخطار آلي(rawBody, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}

// Express example
app.post('/webhooks/ithbat', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const secret = process.env.ITHBAT_WEBHOOK_SECRET;

if (!verifyإخطار آلي(req.body, signature, secret)) {
return res.status(401).send('Invalid signature');
}

const event = JSON.parse(req.body);
console.log('Received event:', event.event);
res.status(200).send('OK');
});

Python

import hmac
import hashlib

def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode('utf-8'),
raw_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)

# Flask example
from flask import Flask, request, abort
import os

app = Flask(__name__)

@app.route('/webhooks/ithbat', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-إخطار آلي-Signature', '')
secret = os.environ['ITHBAT_WEBHOOK_SECRET']

if not verify_webhook(request.get_data(), signature, secret):
abort(401)

event = request.get_json()
print(f"Received event: {event['event']}")
return '', 200

Go

package webhook

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
)

func VerifySignature(body []byte, signature, secret string) bool {
h := hmac.New(sha256.New, []byte(secret))
h.Write(body)
expected := hex.EncodeToString(h.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}

func Handleإخطار آلي(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "failed to read body", http.StatusBadRequest)
return
}

signature := r.Header.Get("X-إخطار آلي-Signature")
secret := os.Getenv("ITHBAT_WEBHOOK_SECRET")

if !VerifySignature(body, signature, secret) {
http.Error(w, "invalid signature", http.StatusUnauthorized)
return
}

// Process event...
w.WriteHeader(http.StatusOK)
}

PHP

function verifyإخطار آلي(string $rawBody, string $signature, string $secret): bool {
$expected = hash_hmac('sha256', $rawBody, $secret);
return hash_equals($expected, $signature);
}

$rawBody = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$secret = getenv('ITHBAT_WEBHOOK_SECRET');

if (!verifyإخطار آلي($rawBody, $signature, $secret)) {
http_response_code(401);
exit('Invalid signature');
}

$event = json_decode($rawBody, true);
error_log('Received event: ' . $event['event']);
http_response_code(200);
نصيحة

استخدم دائمًا timing-safe comparison (crypto.timingSafeEqual، hmac.compare_digest، hmac.Equal، hash_equals) لمنع timing attacks. لا تستخدم == أو === لمقارنة الـ Signatures.


Delivery Policy و Retry

  • Ithbat يجري أول محاولة تسليم فورًا بعد الحدث.
  • التسليم ناجح إذا الـ Endpoint رجع أي 2xx Status Code.
  • إذا فشل (non-2xx response أو timeout أو connection error)، Ithbat يسجّل الفشل في الـ Delivery Log.
  • الـ HTTP client timeout هو 30 ثانية لكل محاولة.
  • يمكنك تعمل Retry يدوي لأي delivery فاشل من لوحة المسؤول أو API.
ملاحظة

الـ Automatic retry مع Exponential Backoff مُخطط للمستقبل. حاليًا، Retry يدوي فقط عبر لوحة المسؤول أو POST /api/v1/webhooks/logs/{logId}/retry.

الـ Endpoint يجب يرجع Response بسرعة (ثوانٍ قليلة) ويعالج الحدث بشكل غير متزامن. إذا المعالجة أخذت أكثر من 30 ثانية، التسليم يُسجَّل كفاشل حتى إذا المعالجة نجحت فعليًا.


Delivery Logs

Ithbat يسجّل كل محاولة تسليم مع الـ Request Payload والـ Response Status Code والـ Response Body.

عرض Delivery Logs في اللوحة

انتقل إلى الإعدادات > إخطارات آلية > {اسم الـ إخطار آلي} > Delivery Logs.

عبر API

GET /api/v1/webhooks/logs
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}

تصفية بـ إخطار آلي محدد:

GET /api/v1/webhooks/logs?webhookId={id}

Retry تسليم فاشل

POST /api/v1/webhooks/logs/{logId}/retry
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}

إرسال Test إخطار آلي

قبل التشغيل الفعلي، أرسل test delivery للتحقق من الـ Endpoint والـ Signature verification.

عبر لوحة تحكم المسؤول

انتقل إلى الإعدادات > إخطارات آلية > {إخطار آلي} > إرسال اختبار.

عبر API

POST /api/v1/webhooks/{id}/test
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}
Content-Type: application/json

{
"event": "user.created"
}

Response:

{
"success": true,
"statusCode": 200,
"response": "OK"
}

إدارة إخطارات آلية عبر API

سرد إخطارات آلية

GET /api/v1/webhooks
Authorization: Bearer {token}
X-Tenant-ID: {tenant_id}

جلب إخطار آلي

GET /api/v1/webhooks/{id}
Authorization: Bearer {token}

تحديث إخطار آلي

PUT /api/v1/webhooks/{id}
Authorization: Bearer {token}
Content-Type: application/json

{
"name": "Production إخطار آلي",
"url": "https://your-app.example.com/webhooks/ithbat",
"events": ["user.created", "user.deleted"],
"isActive": true
}

حذف إخطار آلي

DELETE /api/v1/webhooks/{id}
Authorization: Bearer {token}

Regenerate Signing Secret

استخدم هذا إذا الـ Secret تعرّض للاختراق. الـ Secret الجديد يُرجع في الـ Response ويسري فورًا. جميع الـ deliveries اللاحقة تُوقَّع بالـ Secret الجديد.

POST /api/v1/webhooks/{id}/regenerate-secret
Authorization: Bearer {token}

Response:

{
"secret": "whsec_newvalue..."
}

أفضل الممارسات الأمنية

تحقق من كل Request: لا تعالج أي إخطار آلي event دون التحقق من Header X-إخطار آلي-Signature. Endpoint غير محمي قد يُستغل لحقن Payloads خبيثة.

استخدم HTTPS: الـ HTTP Endpoints مقبولة للتطوير لكن غير مُوصى بها. في Production، قدّم الـ Endpoint عبر HTTPS بشهادة صالحة.

استجب بسرعة: أعد 200 بمجرد التحقق من الـ Signature. انقل المعالجة الثقيلة لـ background queue لكي تتجنب الـ timeout.

Idempotency: قد يصل نفس الحدث أكثر من مرة (وإن كان نادرًا) بسبب Retries. صمّم المعالج لديك ليكون idempotent -- استخدم الـ delivery id كـ deduplication key.

خزّن الـ Raw Body: حلّل JSON فقط بعد التحقق من الـ Signature. إذا أجريت parsing ثم re-serialization قد يتغيّر الـ byte order ويُبطل الـ Signature check.

دوّر الـ Secrets: استخدم الـ Regenerate Secret Endpoint كل بضعة أشهر كجزء من secret rotation.


الخطوات التالية