صدى
English لوحة التحكم
البدء / البدء السريع

البدء السريع

أجرِ أول مكالمة صوتية بين مستخدمَين في أقل من عشر دقائق: خادمك يصدر رمز انضمام، وتطبيقك يمرّره إلى الـ SDK.

⏱ 10 دقائق حُدّث في 14 أكتوبر 2026 عدّل هذه الصفحة

01ثبّت الحزمة

ثبّت حزمة الخادم في الواجهة الخلفية، وحزمة العميل في تطبيقك.

$ composer require sada/laravel
$ npm install @sada/node
$ flutter pub add sada
$ npm install @sada/web

02أضف مفاتيحك

من لوحة التحكم ← التطبيقات ← المفاتيح، انسخ المفتاحين إلى ملف البيئة على خادمك.

.env
SADA_PUBLIC_KEY=pk_test_7f3a9c2e1b84
SADA_SECRET_KEY=sk_test_4vN8kR2pXa61Jd0s
SADA_REGION=auto # baghdad · dubai · istanbul
!

المفتاح السري للخادم فقط. لا تضعه أبداً داخل تطبيق Flutter أو كود المتصفح — أي شخص يستطيع استخراجه.

03أصدِر رمز انضمام

أنشئ المكالمة على خادمك وأصدر رمزاً لكل مشارك. الرمز صالح لـ 5 دقائق ومرتبط بمستخدم واحد.

routes/api.php server.js
1 use Sada\Laravel\Facades\Sada;
2
3 Route::post('/calls', function (Request $request) {
4 $call = Sada::calls()->create([
5 'type' => 'one_to_one',
6 'ring' => true,
7 ]);
8
9 return [
10 'call_id' => $call->id,
11 'token' => $call->token($request->user()->id, ttl: 300),
12 ];
13 });
1 import { Sada } from '@sada/node';
2
3 const sada = new Sada(process.env.SADA_SECRET_KEY);
4
5 app.post('/calls', async (req, res) => {
6 const call = await sada.calls.create({ type: 'one_to_one', ring: true });
7 const token = await call.token({ userId: req.user.id, ttl: 300 });
8
9 res.json({ callId: call.id, token });
10 });

04انضم من التطبيق

اطلب الرمز من خادمك ومرّره إلى الـ SDK. يتولى الـ SDK الاتصال بأقرب منطقة وإعادة الاتصال عند ضعف الشبكة.

lib/call_screen.dart call.js
1 import 'package:sada/sada.dart';
2
3 final res = await api.post('/calls');
4
5 final call = await Sada.join(
6 token: res['token'],
7 displayName: 'محمود عباس',
8 );
9
10 call.onParticipantJoined.listen((p) => print('${p.name} joined'));
1 import { Sada } from '@sada/web';
2
3 const { token } = await fetch('/calls', { method: 'POST' }).then(r => r.json());
4
5 const call = await Sada.join({
6 token,
7 displayName: 'Hussein Alaa',
8 });
9
10 call.on('participant-joined', (p) => console.log(p.name));

05فعّل الرنين (اختياري)

للمكالمات الفردية، أنشئ المكالمة بـ 'ring' => true وسيظهر للطرف الآخر شاشة الاتصال الأصلية حتى والتطبيق مغلق.

iOS · CallKit ارفع مفتاح Apple VoIP ‏(.p8) في بيانات الإشعارات.
Android · Full-screen intent ارفع ملف حساب خدمة Firebase ‏(JSON).

06استقبل الأحداث

نرسل webhook موقّعاً عند بدء المكالمة وانضمام المشاركين ومغادرتهم وانتهائها أو فواتها.

call.started أُنشئت المكالمة وبدأ الرنين
participant.joined صدر رمز انضمام لمشارك
participant.left غادر مشارك عبر الـ SDK
call.ended انتهت المكالمة، مع المدة ودقائق المشاركين
call.missed انتهت المكالمة قبل أن يتصل أحد

التحقق من التوقيع

كل إرسال يحمل ترويسة X-Sada-Signature — الطابع الزمني وتوقيع HMAC-SHA256 لجسم الطلب الخام بسرّ التوقيع من لوحة التحكم ← Webhooks. قارن التوقيع قبل أن تثق بالبيانات، وارفض أي طلب أقدم من خمس دقائق.

routes/api.php server.js
1 Route::post('/webhooks/sada', function (Request $request) {
2 // X-Sada-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">
3 [$t, $v1] = sscanf($request->header('X-Sada-Signature'), 't=%d,v1=%s');
4
5 $expected = hash_hmac('sha256', $t.'.'.$request->getContent(), env('SADA_WEBHOOK_SECRET'));
6
7 abort_unless(hash_equals($expected, $v1) && abs(time() - $t) < 300, 401);
8
9 $event = $request->input('event'); // call.ended, participant.joined, …
10 $call = $request->input('data.call_id');
11
12 return response()->noContent();
13 });
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 });

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

✓ شكراً، وصلتنا ملاحظتك.