التحقق الصوتي (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 غير مسلَّمة: يُعرف هل فُتحت المكالمة وهل قُرئ الرمز.
  • للمستخدم المسن أو ضعيف البصر الاستماع إلى الرمز أسهل من قراءته.
  • لا يُحتسب إلا للمكالمات التي رُدّ عليها، وفق قواعد باقتكم.