صدى
English لوحة التحكم
حزم SDK / Node.js

Node.js

حزمة Node.js ‏@sada/node قادمة. حتى تصدر، الـ REST API صغير بما يكفي لاستدعائه بـ fetch — هذه الصفحة تعرض المسارات نفسها بـ HTTP مباشر.

حُدّث في 21 أكتوبر 2026 عدّل هذه الصفحة

01حالة الحزمة

npm install @sada/node لا يعمل بعد؛ مقطع sada.calls.create() في البدء السريع معاينة لواجهتها. كل ما يلي يعمل اليوم على Node 18+ بلا اعتماديات، والانتقال إلى الحزمة لاحقاً بضعة أسطر.

02عميل صغير

دالة مساعدة واحدة تضيف ترويسة bearer وترسل JSON وترمي عند الأخطاء بـ message وstatus وerrors من الـ API.

sada.js
1 // Until @sada/node ships, the REST API is a few lines of fetch (Node 18+).
2 const BASE = 'https://sada.g4t.io/api/v1';
3
4 export async function sada(path, { method = 'GET', body } = {}) {
5 const res = await fetch(BASE + path, {
6 method,
7 headers: {
8 Authorization: `Bearer ${process.env.SADA_SECRET_KEY}`,
9 'Content-Type': 'application/json',
10 Accept: 'application/json',
11 },
12 body: body ? JSON.stringify(body) : undefined,
13 });
14
15 const json = await res.json();
16 if (!res.ok) throw Object.assign(new Error(json.message), { status: res.status, errors: json.errors });
17
18 return json;
19 }

03إنشاء مكالمة وإصدار رمز

أنشئ المكالمة ثم أصدر رمزاً لكل مشارك. أعد الرمز إلى تطبيقك؛ لا المفتاح السري أبداً.

server.js
1 import { sada } from './sada.js';
2
3 app.post('/calls', async (req, res) => {
4 const { call } = await sada('/calls', { method: 'POST', body: { type: 'one_to_one', ring: true } });
5
6 const { token } = await sada(`/calls/${call.call_id}/tokens`, {
7 method: 'POST',
8 body: { user_ref: String(req.user.id), display_name: req.user.name, ttl: 300 },
9 });
10
11 res.json({ callId: call.call_id, token });
12 });

04القائمة والجلب والإنهاء

بقية المسارات تقابل واحداً لواحد.

server.js
1 const { data, meta } = await sada('/calls?status=ringing&per_page=20');
2
3 const call = await sada('/calls/call_k3j9x2m7qa');
4
5 await sada('/calls/call_k3j9x2m7qa/end', { method: 'POST' });

05استقبال الـ webhooks

تحقق من X-Sada-Signature مقابل الجسم الخام قبل تحليله. استخدم express.raw() (أو ما يعادله) على هذا المسار كي لا يُعاد ترميز الجسم.

server.js
1 import { createHmac, timingSafeEqual } from 'node:crypto';
2
3 app.post('/webhooks/sada', express.raw({ type: 'application/json' }), (req, res) => {
4 const [t, v1] = req.get('X-Sada-Signature').split(',').map((p) => p.split('=')[1]);
5
6 const expected = createHmac('sha256', process.env.SADA_WEBHOOK_SECRET)
7 .update(`${t}.${req.body}`)
8 .digest('hex');
9
10 if (!timingSafeEqual(Buffer.from(expected), Buffer.from(v1))) return res.sendStatus(401);
11
12 const { event, data } = JSON.parse(req.body); // call.ended, data.call_id, …
13 res.sendStatus(204);
14 });
✓ شكراً، وصلتنا ملاحظتك.