التحقق الصوتي (OTP)
نموذج "نتصل بكم ونقرأ الرمز": تعطوننا الرقم، فيتصل السنترال ويقرأ رمز التحقق رقمًا رقمًا لمن يرد (وعند ضغط 1 يعيد القراءة) ثم ينهي المكالمة. يمكنكم إرسال الرمز بأنفسكم أو أن تنشئه Buluthat وتعيده في الرد مرة واحدة. لا يُحفظ الرمز في قاعدة البيانات إلا hash يُحفظ كـ؛ status لا تظهر في الرد.
نقطة النهاية: https://api.buluthat.com/api/voice_otp.php — مفتاح التكامل (bt_…، النطاق voice_otp / autocall / voicebot / *). في الحساب voice_otp يجب أن تكون الوحدة مفعّلة.
POSTsend
{
"action": "send",
"phone": "05551112233",
"code": "482913",
"length": 6,
"reference": "CARI-451",
"caller_id": "02124119610",
"trunk_slug": "hat-1",
"repeat": 2,
"ttl_minutes": 5,
"company_name": "Byfix",
"webhook_url": "https://crm.example.com/otp-sonuc.php",
"webhook_secret": "gizli"
}
| المنطقة | إلزامي | الوصف |
|---|---|---|
phone | نعم | الرقم المطلوب الاتصال به |
code | لا | رمزكم الخاص؛ وإن كان فارغًا تنشئه Buluthat |
length | لا | عدد خانات الرمز المُنشأ (4-8، الافتراضي 6) |
reference | لا | تسجيلكم الخاص؛ status/list للعثور عليه بـ |
caller_id, trunk_slug | لا | رقم المتصل والخط |
repeat | لا | كم مرة يُقرأ الرمز (1-5، الافتراضي 2) |
ttl_minutes | لا | مدة صلاحية الرمز (الحد الأقصى 60، الافتراضي 5) |
company_name | لا | اسم الشركة في مقطع الترحيب؛ وإن كان فارغًا فاسم الحساب |
webhook_url, webhook_secret | لا | إشعار الحالة |
الرد:
{ "ok": true, "code": "482913", "data": { "id": 17, "status": "calling", "expires_at": "2026-09-18 10:17:03" } }
code لا يعود إلا إذا أنشأته Buluthat؛ وإن أرسلتموه أنتم null.
الأخطاء (422): رقم غير صالح، أكثر من 3 اتصالات إلى الرقم نفسه خلال 10 دقائق (rate_limited)، الحد اليومي (daily_limit)، مكالمة جارية (in_progress)، لا يوجد خط، لا يوجد مفتاح تحويل نص إلى صوت، تعذّر على السنترال إجراء المكالمة (السبب في الرسالة).
POSTverify
{ "action": "verify", "id": 17, "code": "482913" }
id بدلًا من phone (+ reference) ويمكن أيضًا تحديده؛ يُستخدم آخر تسجيل مفتوح لذلك الرقم.
- الصحيح:
{ "ok": true, "verified": true } - الخطأ:
422وerror:wrong_code(المحاولات المتبقية في الرسالة)،expired,too_many_attempts(5),not_delivered(لم تُجرَ المكالمة)،not_found
الرمز، إذا فُتحت المكالمة (answered/delivered) يمكن التحقق حتى لو أغلق الشخص الهاتف بعد سماع الرمز.
GETstatus
GET https://api.buluthat.com/api/voice_otp.php?action=status&id=17
الحالات: pending → calling → answered → delivered → verified؛ الفاشلة no_answer, busy, failed, expired. final: true فقد انتهت المكالمة. استعلموا كل 2-3 ثانية أو استخدموا Webhook.
GETlist
GET ?action=list&phone=0555…&reference=CARI-451&limit=20
GETcaller_ids · trunks
خيارات رقم المتصل والخط (كما في API الاتصال الآلي).
Webhook
webhook_url إذا أُعطي عند تغيّر الحالات (delivered, verified, no_answer, busy, failed, expired) يُرسَل POST:
{ "event": "voice_otp.delivered", "request": { "id": 17, "status": "delivered", "reference": "CARI-451", "phone": "05551112233" } }
الترويسات X-Buluthat-Event, X-Buluthat-Delivery, webhook_secret إذا أُعطي X-Buluthat-Signature: sha256=<hmac>. عند رد من غير فئة 2xx تُعاد المحاولة بعد 1 د، 5 د، 15 د، 1 س، 3 س، 6 س.
عميل PHP
الملف المُنزَّل من اللوحة buluthat-voice-otp-client.php:
require 'buluthat-voice-otp-client.php';
$otp = new BuluthatVoiceOtp('https://api.buluthat.com', 'bt_xxx');
$r = $otp->send('05551112233', ['reference' => 'CARI-451']); // $r['code'], $r['data']['id']
// ... kullanıcı kodu girer ...
$v = $otp->verify($r['data']['id'], $girilenKod); // $v['ok'] === true
لماذا بدل SMS؟
- لا يتطلب موافقة İYS ولا عنوان SMS، ويعمل على الخط الثابت أيضًا.
- لا مشكلة رسائل SMS غير مسلَّمة: يُعرف هل فُتحت المكالمة وهل قُرئ الرمز.
- للمستخدم المسن أو ضعيف البصر الاستماع إلى الرمز أسهل من قراءته.
- لا يُحتسب إلا للمكالمات التي رُدّ عليها، وفق قواعد باقتكم.
