اتصال مستقیم به موتور تماس صوتی داریوش
سامانه پیام صوتی داریوش بستری امن، با پایداری ۹۹.۹۵٪ و تاخیر بسیار پایین (Low Latency) برای برقراری تماسهای صوتی انبوه، نظرسنجی تلفنی، یادآوری بدهی و رمز یکبار مصرف صوتی (Voice OTP) از طریق اینترفیس استاندارد RESTful است.
پایگاههای آدرس (Base URLs)
| محیط | آدرس پایه (Host) | پروتکل |
|---|---|---|
| عملیاتی (Production) | https://api.idehvoice.com | HTTPS / TLS 1.3 |
| محیط تست (Staging Sandbox) | https://stage-api.idehvoice.com | HTTPS |
تمام پاسخهای وبسرویس دارای فیلدهای ثابت succeed (بولین) و data (داده عملیاتی) یا error (شرح خطا در صورت بروز) هستند.
{
"succeed": true,
"message": "operation completed successfully",
"data": {
// شیء دادههای عملیاتی هر متد
"tracking_code": "CMP-84729104",
"status": "completed"
}
}
احراز هویت، وایتلیست IP و کنترل نرخ درخواست
هر درخواست ارسالی به وبسرویس ماشینی داریوش از ۳ لایه امنیتی توزیعشده با تاخیر زیر ۵ میلیثانیه عبور میکند:
کلید API اختصاصی خود را میتوانید از پنل کاربری بخش تنظیمات وبسرویس دریافت نمایید. این کلید باید در تمامی درخواستها در هدر X-API-Key ارسال شود.
جهت جلوگیری از سوءاستفاده حتی در صورت افشای کلید، میتوانید IP سرورهای خود یا سابنت آنها (مانند 185.190.20.0/24) را در پنل وایتلیست کنید.
نکته: در صورتی که هیچ IP در پنل تعریف نشده باشد، دسترسی از کلیه IPها مجاز خواهد بود.
هر کاربر سهمیه مشخصی از تعداد درخواست در ثانیه دارد. سرور داریوش با هدرهای استاندارد زیر وضعیت سهمیه را بازمیگرداند:
برای تضمین عدم ارسال مجدد تماس در قطع لحظهای شبکه کلاینت، میتوانید هدر Idempotency-Key یا فیلد client_reference_id را ارسال کنید. داریوش درخواستهای همسان را فقط یکبار پردازش و هزینه را یکبار کسر میکند.
# احراز هویت استاندارد با کلید اختصاصی
curl -i -X GET \
"https://api.idehvoice.com/api/v1/m2m/account/balance" \
-H "X-API-Key: dsh_live_9f8c2b7e1a4d6f03" \
-H "Idempotency-Key: 994a3e81-b21a-42c1" \
-H "Accept: application/json"
فلوچارت چرخه ارسال تماس، تایید و گزارش تحویل (DLR)
نحوه تعامل کلاینت با لایه Gateway، کسر اتمیک اعتبار از کیف پول، فرآیند تایید ادمین و تزریق رویداد به صف مخابراتی در دیاگرام تعاملی زیر تشریح شده است:
راهنمای وبهوک و اعتبارسنجی امضای HMAC-SHA256
به محض برقراری یا پایان هر تماس صوتی، سرور داریوش یک رویداد HTTP POST با بدنه JSON به آدرس webhook_url تعریف شده شما ارسال میکند. برای اطمینان از اصالت درخواست و ممانعت از حملات جعل، تمامی درخواستها با امضای کریپتوگرافیک هش میشوند.
هدرهای ارسال شده به سرور شما
| هدر | نمونه مقدار | کاربرد |
|---|---|---|
| X-IdehVoice-Signature | sha256=3a1b...c8f2 | امضای هگزادسیمال HMAC-SHA256 بدنه با کلید وبهوک |
| X-IdehVoice-Timestamp | 1726051200 | تایماستمپ یونیکس زمان ارسال برای دفاع Replay Attack |
نمونه کد اعتبارسنجی امضا در زبانهای مختلف
import hmac, hashlib
def verify_idehvoice_webhook(payload_raw_bytes: bytes, signature_header: str, secret_key: str) -> bool:
received_hash = signature_header.replace("sha256=", "")
computed_hash = hmac.new(secret_key.encode('utf-8'), payload_raw_bytes, hashlib.sha256).hexdigest()
return hmac.compare_digest(received_hash, computed_hash)
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"strings"
)
func VerifyWebhook(payload []byte, signatureHeader string, secret string) bool {
cleanSig := strings.TrimPrefix(signatureHeader, "sha256=")
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(payload)
expectedSig := hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(cleanSig), []byte(expectedSig))
}
const crypto = require('crypto');
function verifyWebhook(rawPayload, signatureHeader, secretKey) {
const received = signatureHeader.replace('sha256=', '');
const computed = crypto.createHmac('sha256', secretKey).update(rawPayload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(received), Buffer.from(computed));
}
<?php
function verifyIdehVoiceWebhook($rawPayload, $signatureHeader, $secretKey) {
$received = str_replace("sha256=", "", $signatureHeader);
$computed = hash_hmac("sha256", $rawPayload, $secretKey);
return hash_equals($received, $computed);
}
{
"event_id": "e2c34567-89ab-4cde-0123-456789abcdef",
"event_type": "call.completed",
"tracking_code": "CMP-84729104",
"destination_number": "09123456789",
"status": "answered",
"duration_seconds": 18,
"cost": 150.0,
"refunded_amount": 0.0,
"hangup_cause": "NORMAL_CLEARING",
"dtmf_digits": "1",
"timestamp": "2026-09-11T19:22:30Z"
}
جدول کدهای وضعیت تماس (Call Delivery Statuses)
وضعیتهای نهایی و میانی تماسهای صوتی ارسالی به همراه وضعیت عودت وجه به کیف پول:
| کد وضعیت (Status) | شرح وضعیت | استرداد وجه (Refund) | توضیحات مخابراتی |
|---|---|---|---|
| queued | در صف ارسال | - | درخواست با موفقیت ثبت شده و در نوبت تحویل به گیتوی مخابراتی است. |
| ringing | در حال بوق خوردن | - | گوشی مقصد در حال زنگ خوردن است و منتظر پاسخ کاربر میباشد. |
| answered | پاسخ داده شد (موفق) | کسر قطعی | تماس توسط کاربر پاسخ داده شد و فایل صوتی با موفقیت پخش گردید. |
| busy | خط مشغول بود | استرداد ۱۰۰٪ | شماره مخاطب در حال مکالمه بوده و هزینه تماس به کیف پول کلاینت بازگشت داده شد. |
| no_answer | عدم پاسخگویی | استرداد ۱۰۰٪ | مخاطب به تماس پاسخ نداد و پس از پایان زمان زنگ، مبلغ ریفاند شد. |
| failed | ناموفق / در دسترس نبود | استرداد ۱۰۰٪ | شماره خاموش یا خارج از دسترس، یا اختلال در شبکه اپراتور مقصد. |
| canceled | لغو توسط کاربر | استرداد ۱۰۰٪ | کمپین پیش از ارسال توسط کلاینت از طریق متد Cancel لغو گردید. |
جدول کدهای خطای وبسرویس (API Error Codes)
در هنگام بروز خطا، فیلد error.code یکی از مقادیر جدول زیر خواهد بود:
| کد خطا | کد وضعیت HTTP | نام شناسه فنی | راهنمای رفع خطا |
|---|---|---|---|
| 2000 | 401 Unauthorized | APIKeyMissing | هدر X-API-Key ارسال نشده است. |
| 2001 | 401 Unauthorized | APIKeyInvalid | کلید API ارسالی معتبر نیست یا منقضی شده است. |
| 2002 | 403 Forbidden | APIKeyInactive | حساب کاربری یا کلید به صورت موقت غیرفعال شده است. |
| 2003 | 403 Forbidden | WebServiceNotAllowed | دسترسی وبسرویس برای حساب کاربری شما فعال نشده است (با پشتیبانی تماس بگیرید). |
| 2004 | 403 Forbidden | IPNotWhitelisted | آیپی سرور درخواستدهنده در لیست سفید (Whitelist) پنل ثبت نشده است. |
| 2005 | 429 Too Many Requests | RateLimitExceeded | نرخ ارسال از سقف مجاز در ثانیه فراتر رفته است (درخواستها را با فاصله ارسال کنید). |
| 2006 | 404 Not Found | AudioFileNotFound | شناسه فایل صوتی (audio_file_uuid) در سیستم یافت نشد. |
| 2007 | 400 Bad Request | AudioFileNotApproved | فایل صوتی هنوز در صف بررسی ناظر است یا رد شده است. |
| 2008 | 404 Not Found | LineNotFound | خط فرستنده انتخابی معتبر نیست یا به حساب شما تخصیص نیافته است. |
| 2010 | 400 Bad Request | InvalidRecipientNumber | فرمت شماره موبایل نامعتبر است (باید ۱۱ رقم و با 09 شروع شود). |
| 2011 | 400 Bad Request | RecipientBlacklisted | شماره در لیست سیاه عمومی مخابرات یا بلکلیست شخصی شما قرار دارد. |
| 2015 | 409 Conflict | IdempotencyRequestPending | درخواست همزمان با همین کلید یکتا در حال پردازش است. |
| 2016 | 409 Conflict | DuplicateClientReferenceID | شناسه مرجع قبلاً استفاده شده است (نتیجه پیشین برگردانده شد). |
| 406 | 403 Forbidden | InsufficientBalance | موجودی کیف پول شما برای برقراری این تماس کافی نیست (نیاز به شارژ آنلاین). |
| 5000 | 500 Internal Error | InternalError | خطای پیشبینی نشده سرور (به پشتیبانی اطلاع دهید). |
علل قطع تماس مخابراتی (Hangup Causes)
فیلد hangup_cause در گزارش ریز گیرندگان و پیلود وبهوک وضعیت قطع سیگنالینگ مخابرات را نشان میدهد:
| کد ISDN / علت | شرح فنی رویداد مخابراتی | اقدام پیشنهادی |
|---|---|---|
| NORMAL_CLEARING (16) | تماس به صورت طبیعی پس از پخش کامل پیام یا قطع مشترک پایان یافت. | تماس موفق بوده است. |
| USER_BUSY (17) | مشترک در حال مکالمه دیگری بود یا تماس را بلافاصله رد (Reject) کرد. | تلاش مجدد در صورت فعال بودن max_retries. |
| NO_ANSWER (19) | گوشی زنگ خورد ولی کاربر ظرف ۶۰ ثانیه پاسخ نداد. | مبلغ به صورت خودکار ریفاند گردید. |
| SUBSCRIBER_ABSENT (20) | گوشی خاموش یا خارج از محدوده پوششدهی آنتن اپراتور همراه است. | مبلغ به صورت خودکار ریفاند گردید. |