Slack, Teams & Webhooks
الأدلة
تنبيهات Slack وTeams والويب هوك
أرسل تنبيهات Scanverra إلى قناة في Slack أو قناة في Microsoft Teams أو نقطة نهاية HTTPS خاصة بك، ليعرف فريقك بانخفاض النتيجة أو بأي تغيير خطِر في المكان الذي يعمل فيه أصلًا.
كيف يعمل
- 1افتح الفريق ثم التكاملات، وأضف Slack أو Microsoft Teams أو ويب هوك.
- 2اختر التنبيهات التي يجب أن يستقبلها، ثم انقر على إرسال اختبار للتأكد من وصول الرسالة.
- 3عندما يجد فحص مجدول أو مراقبة شيئًا ما، يرسل Scanverra التنبيه فور انتهاء التشغيل.
الفحوصات التي يشغّلها أحد يدويًا لا ترسل تنبيهات. جدوِل المواقع والمستودعات التي تريد مراقبتها من صفحة الفحوصات المجدولة.
التنبيهات المتاحة
يستقبل كل تكامل التنبيهات التي تحددها فقط. في الويب هوك، يصل اسم الحدث في الترويسة X-Scanverra-Event وفي الحقل event.
| الحدث | يُرسل عندما |
|---|---|
scan.score_dropped | تقل نتيجة فحص مجدول بأكثر من 10 نقاط عن تشغيله السابق. يسرد التنبيه ما هو جديد. |
scan.completed | ينتهي أي فحص مجدول بنتيجة. |
scan.policy_failedEnterprise | لا يستوفي فحص مجدول سياسة فريقك (حد أدنى للنتيجة، أو عدم وجود مشكلات حرجة). يسرد التنبيه الأسباب. |
payment_page.scripts_changedEnterprise | تحمّل صفحة دفع مراقبة سكربتًا جديدًا أو معدّلًا، أو تتغير سياسة Content-Security-Policy الخاصة بها. |
attack_surface.changedEnterprise | يظهر مضيف جديد في نطاق مراقب، أو يصبح أحد المضيفين معرضًا لخطر الاستيلاء. |
test | ينقر أحد على إرسال اختبار. |
ربط Slack
- 1في Slack، افتح Apps، وابحث عن Incoming Webhooks، وأضفه إلى القناة التي يجب أن تستقبل التنبيهات.
- 2انسخ عنوان URL الخاص بالويب هوك. يبدأ بـ https://hooks.slack.com/.
- 3في Scanverra، أضف تكاملًا، واختر Slack، والصق العنوان، ثم اختر تنبيهاتك.
يعرض كل تنبيه العنوان، وحتى خمس مشكلات جديدة، وزر "Open report".
ربط Microsoft Teams
- 1في قناة Teams، افتح سير العمل واختر النشر في قناة عند تلقي طلب ويب هوك.
- 2أكمل سير العمل وانسخ عنوان URL الذي يعطيك إياه.
- 3في Scanverra، أضف تكاملًا، واختر Microsoft Teams، والصق العنوان، ثم اختر تنبيهاتك.
يصل كل تنبيه على شكل بطاقة فيها العنوان والمشكلات الجديدة وزر "Open report".
الويب هوك
استخدم الويب هوك لإرسال التنبيهات إلى أي مكان آخر: فتح تذكرة، أو تنبيه المناوب، أو حفظها. يرسل Scanverra طلب POST واحدًا عبر HTTPS بمحتوى JSON لكل تنبيه.
ترويسات الطلب
Content-Type | دائمًا application/json. |
User-Agent | يعرّف Scanverra بوصفه المرسل.Scanverra-Alerts/1.0 |
X-Scanverra-Event | اسم الحدث، وهو نفسه الحقل event في المحتوى.scan.score_dropped |
X-Scanverra-Timestamp | وقت توقيع الطلب، بثواني Unix.1762594212 |
X-Scanverra-Signature | sha256= متبوعًا بقيمة HMAC-SHA256 للطابع الزمني ثم نقطة ثم المحتوى الخام، باستخدام سر التوقيع الخاص بك مفتاحًا.sha256=9f2c… |
محتوى الطلب
مثال على انخفاض النتيجة:
{
"event": "scan.score_dropped",
"sentAt": "2026-11-08T09:30:12.418Z",
"summary": "Security Scan score dropped from 81 to 62 for shop.example.com",
"data": {
"target": "https://shop.example.com",
"scanType": "security",
"score": 62,
"prevScore": 81,
"reportUrl": "https://www.scanverra.com/security-scan/cm9x2k1",
"newIssues": [
"Missing Content-Security-Policy header",
"jQuery 3.4.1 has known vulnerabilities"
]
}
}الحقول
event | اسم الحدث. |
sentAt | وقت إرسال التنبيه (ISO 8601). |
summary | وصف من سطر واحد، جاهز للعرض كما هو. |
data.target | عنوان URL الذي تم فحصه، أو النطاق، أو owner/repo للمستودع. |
data.scanType | audit أو seo أو security أو browser أو repo أو crawl (زحف SEO لعدة صفحات). |
data.score | النتيجة الجديدة من 0 إلى 100، أو null عندما لا تكون للتنبيه نتيجة (المراقبة والاختبارات). |
data.prevScore | نتيجة التشغيل السابق، أو null. |
data.reportUrl | رابط إلى التقرير أو صفحة المراقبة. |
data.newIssues | أسطر قصيرة تصف ما تغيّر. قد تكون فارغة أو غير موجودة. |
التحقق من التوقيع
عند إضافة ويب هوك، يعرض Scanverra سر التوقيع (whsec_...) مرة واحدة فقط. احفظه على خادمك، ثم تحقق من كل طلب قبل أن تثق به:
- 1اقرأ محتوى الطلب الخام كما وصل تمامًا، قبل أي تحليل لـ JSON.
- 2احسب HMAC-SHA256 لترويسة الطابع الزمني ثم نقطة ثم المحتوى الخام، باستخدام السر مفتاحًا.
- 3قارنه بترويسة التوقيع بزمن ثابت، وارفض الطلبات التي يزيد عمر طابعها الزمني على 5 دقائق.
import crypto from "node:crypto";
import express from "express";
const SECRET = process.env.SCANVERRA_WEBHOOK_SECRET; // whsec_...
const app = express();
// express.raw keeps the exact bytes Scanverra signed.
app.post("/scanverra", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.get("X-Scanverra-Timestamp") ?? "";
const signature = req.get("X-Scanverra-Signature") ?? "";
const expected = "sha256=" + crypto
.createHmac("sha256", SECRET)
.update(`${timestamp}.${req.body}`)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
const valid = signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!fresh || !valid) return res.sendStatus(401);
const alert = JSON.parse(req.body);
console.log(alert.event, alert.summary);
res.sendStatus(204); // answer fast, do slow work afterwards
});
app.listen(3000);لأن الطابع الزمني يُوقَّع مع المحتوى، لا يمكن إعادة إرسال طلب ملتقط لاحقًا.
قواعد التسليم
- أجب بأي حالة 2xx خلال 5 ثوانٍ. نفّذ الأعمال البطيئة بعد الرد.
- يُرسل كل تنبيه مرة واحدة ولا تُعاد محاولة إرساله. توضح لوحة التكاملات ما إذا نجح آخر تسليم.
- لا تُتبع عمليات إعادة التوجيه، لذا استخدم العنوان النهائي.
- تُقبل عناوين HTTPS العامة فقط. يجب أن تكون عناوين Slack على hooks.slack.com، وعناوين Teams على webhook.office.com أو Power Automate.
- تتوقف التنبيهات للفريق كله إذا انتهت خطة Team أو Enterprise الخاصة به.
هل أنت مستعد للربط؟
يمكن لمالكي الفريق والمسؤولين إضافة تكامل خلال دقيقة. أرسل اختبارًا قبل أول تنبيه حقيقي.