خطافات الويب وتنبيهات الأسعار
تلقَّ استدعاءات HTTP موقّعة عندما يتجاوز السعر العتبة التي حددتها، وتحقّق من صحتها باستخدام HMAC-SHA256، مع أمثلة جاهزة بلغتي Node.js وPHP.
كيف تعمل التنبيهات وخطافات الويب
يرسل MetalAPI خطافات الويب عندما ينطلق تنبيه سعري. يراقب التنبيه رمزًا واحدًا بعملة من اختيارك، وينطلق عندما يرتفع السعر فوق عتبة معيّنة أو ينخفض دونها، أو عندما يتحرك صعودًا أو هبوطًا بنسبة مئوية معيّنة منذ الإغلاق السابق.
تنطلق التنبيهات لحظة العبور: تتلقى إشعارًا واحدًا عندما يتحقق الشرط، ثم يُعاد تفعيل التنبيه بعد أن يعود الشرط غير متحقق. وتمنع فترة التهدئة (60 دقيقة افتراضيًا، قابلة للضبط من 5 دقائق إلى 7 أيام) سيلًا من الإشعارات عندما يتأرجح السعر حول العتبة.
تُرسل التنبيهات إشعاراتها بالبريد الإلكتروني في خطة Lite وما فوقها، أو عبر خطاف ويب (طلب HTTPS POST إلى خادمك) في خطة Advanced وما فوقها.
إعداد خطاف ويب
- افتح Alerts في لوحة التحكم وأنشئ تنبيهًا.
- اختر الرمز والعملة والشرط والعتبة.
- اختر التسليم عبر خطاف الويب وأدخل عنوان URL لنقطة النهاية لديك.
- انسخ سر توقيع خطاف الويب (يبدأ بـ
whsec_) من لوحة التحكم إلى إعدادات خادمك.
يجب أن تستخدم عناوين URL لخطافات الويب https:// على مضيف عام. تُرفض العناوين التي تحتوي على بيانات اعتماد أو التي تُحل إلى عناوين IP خاصة أو داخلية، ولا تُتبع عمليات إعادة التوجيه.
الحمولة
كل عملية تسليم هي طلب POST بصيغة JSON مع الترويسات والجسم التاليين:
POST /webhooks/metalapi HTTP/1.1
Content-Type: application/json
User-Agent: MetalAPI-Webhooks/1.0
X-MetalAPI-Timestamp: 1792765800
X-MetalAPI-Signature: t=1792765800,v1=3b9f0c4e…a71d
{
"event": "alert.triggered",
"id": 18342,
"created": 1792765800,
"alert": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"symbol": "XAU",
"base": "USD",
"condition": "above",
"threshold": 4000,
"note": "Gold above 4k"
},
"price": 4001.25,
"unit": "troy_oz"
}تأخذ condition إحدى القيم above أو below أو change_pct_up أو change_pct_down. وprice هو السعر الذي أطلق التنبيه، بوحدة base لكل unit. أما id ففريد لكل حدث، لذا يمكنك استخدامه لتجاهل عمليات التسليم المكررة.
التحقق من التوقيع
تحقّق دائمًا من أن الطلب صادر فعلًا من MetalAPI قبل التصرف بناءً عليه. تأتي ترويسة X-MetalAPI-Signature على الشكل t=<unix timestamp>,v1=<signature>. والتوقيع هو قيمة HMAC-SHA256 للسلسلة <timestamp>.<raw request body> مُرمّزة بالنظام الست عشري، باستخدام سر التوقيع الخاص بك كمفتاح.
- احسب HMAC على الجسم الخام قبل أي تحليل لـ JSON.
- قارن التواقيع في زمن ثابت.
- ارفض الطوابع الزمنية الأقدم من خمس دقائق لمنع إعادة إرسال الطلبات القديمة.
في Node.js مع Express:
import crypto from "node:crypto";
import express from "express";
const app = express();
const SECRET = process.env.METALAPI_WEBHOOK_SECRET;
app.post("/webhooks/metalapi", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-MetalAPI-Signature") ?? "";
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
const body = req.body.toString("utf8");
const expected = crypto.createHmac("sha256", SECRET).update(`${parts.t}.${body}`).digest("hex");
const valid =
typeof parts.v1 === "string" &&
parts.v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
if (!valid || !fresh) return res.status(400).send("invalid signature");
const event = JSON.parse(body);
console.log(event.alert.symbol, event.alert.condition, event.alert.threshold, event.price);
res.sendStatus(200);
});التحقق في PHP
التحقق نفسه بلغة PHP دون أي مكتبات:
<?php
$secret = getenv('METALAPI_WEBHOOK_SECRET');
$payload = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_METALAPI_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $parts);
$timestamp = (int) ($parts['t'] ?? 0);
$expected = hash_hmac('sha256', $timestamp . '.' . $payload, $secret);
if (!hash_equals($expected, $parts['v1'] ?? '') || abs(time() - $timestamp) > 300) {
http_response_code(400);
exit('invalid signature');
}
$event = json_decode($payload, true);
// Handle $event['alert'] and $event['price'] here.
http_response_code(200);الاستجابة وإعادة المحاولة
أرجِع أي حالة 2xx خلال 8 ثوانٍ، ونفّذ الأعمال البطيئة بعد الاستجابة، في طابور مثلًا، لأن انتهاء المهلة والاستجابات بحالة غير 2xx تُعدّ عمليات تسليم فاشلة.
يُعاد إرسال عمليات التسليم الفاشلة بفواصل زمنية متزايدة، حتى ثلاث محاولات إجمالًا خلال الساعة الأولى بعد انطلاق التنبيه. وقد تصل إعادة محاولة بعد تسليم انتهت مهلته من جهتنا لكنه نجح من جهتك، لذا خزّن id الحدث واجعل معالجك آمنًا عند التكرار (idempotent).
أدلة ذات صلة
هل أنت مستعد لبدء التطوير؟
أنشئ حسابًا مجانيًا للحصول على مفتاح API، أو استكشف جميع نقاط النهاية في مرجع API.