ظاهر
راهاندازی Issabel و اتصال به CRM
خلاصه کاربردی
این صفحه راهنمای صفر تا صد سمت سرور تلفن (Issabel / Asterisk) و اتصال آن به ماژول VoIP در NikaCRM است. بدون این مراحل، Click-to-Call، لیست تماس (CDR)، تماس زنده و ضبط مکالمه کامل کار نمیکنند. برای تلفن نرمافزاری مرورگر به Soft Phone بروید.
تنظیمات هر فضای کاری
NikaCRM چندفضایی است. هر فضای کاری تنظیمات VoIP خودش را در پنل دارد (AMI، دیتابیس CDR، Webhook، Soft Phone، داخلیها و …).
چند فضای کاری / چند Issabel
هر فضای کاری میتواند به Issabel و دیتابیس CDR خودش وصل شود. روی یک PBX مشترک هم میتوان همان مشخصات را برای چند فضای کاری گذاشت؛ تفکیک ردیفهای تماس با داخلیهای تعریفشده همان فضای کاری انجام میشود.
تصویر کلی اتصال CRM ↔ Issabel
┌──────────────────────┐ AMI :5038 (Originate) ┌─────────────────────┐
│ NikaCRM │ ─────────────────────────────────────► │ Issabel │
│ (پنل + سرویس ابری) │ │ Asterisk + AMI │
│ │ ◄──── MySQL CDR :3306 (asteriskcdrdb) │ │
│ │ ◄──── Webhook HTTP POST (رویداد تماس) │ Dialplan / AGI │
│ مرورگر اپراتور │ Soft Phone (WebSocket امن) │ HTTP/WS + SIP │
└──────────────────────┘ └─────────────────────┘| مسیر | جهت | کاربرد در CRM | کجا تنظیم میشود |
|---|---|---|---|
AMI (پورت 5038) | CRM → Issabel | تست اتصال، Click-to-Call، وضعیت peer سافتفون | پنل → Host / User / Secret |
MySQL CDR (asteriskcdrdb) | CRM → Issabel | لیست تماسها، داشبورد، گزارش | پنل → بخش دیتابیس CDR |
| Webhook | Issabel → CRM | زنگ / پاسخ / پایان تماس در پنل زنده و پاپآپ | پنل (Webhook Secret) + اسکریپت روی Issabel |
| Soft Phone | مرورگر ↔ Issabel | رجیستر SIP و مکالمه از مرورگر | پنل + تنظیمات Issabel — Soft Phone |
آدرس Webhook:
text
POST https://YOUR_CRM_HOST/api/public/voip/{workspaceId}/webhook
Header: X-Voip-Secret: YOUR_SECRETworkspaceId همان شناسه فضای کاری در CRM است (از URL یا تنظیمات فضای کاری).
مفاهیم پایه
| مفهوم | معنی ساده |
|---|---|
| Issabel | PBX مبتنی بر Asterisk؛ داخلی، ترانک، صف و ضبط روی آن ساخته میشود |
| AMI | رابط مدیریت Asterisk؛ CRM از آن برای Originate و تست استفاده میکند |
| داخلی (Extension) | شماره داخلی اپراتور (مثلاً 1001)؛ در CRM و Issabel باید یکی باشد |
| CDR | گزارش تماسها در دیتابیس asteriskcdrdb.cdr |
| Click-to-Call | از پنل شماره میزنید؛ AMI اول داخلی شما را زنگ میزند، بعد شماره مقصد |
| Webhook | Issabel رویداد تماس را به CRM میفرستد تا پاپآپ و تماس فعال لحظهای شود |
| Channel Prefix | پیشوند کانال: SIP/ یا PJSIP/ بسته به نوع داخلی روی Issabel |
| Dial Context | معمولاً from-internal برای Originate خروجی |
از کجا در CRM وارد شوم؟
VoIP → تنظیمات → اتصال و یکپارچگی با سرور VoIP
فیلدهای AMI، دیتابیس CDR، پیشوند کانال، Context، داخلی پیشفرض، Webhook Secret و ضبط اینجا هستند. جزئیات UI: تنظیمات.
پیشنیازها
- Issabel با Asterisk سالم (داخلیها بین خود زنگ میخورند)
- دسترسی مدیریت به سرور Issabel
- دسترسی شبکهای بین سرور CRM و Issabel (و برعکس برای Webhook روی HTTPS)
- شناسه فضای کاری و مجوز ماژول VoIP برای آن فضای کاری
۱) فایروال و شبکه
روی Issabel (یا فایروال جلوی آن) فقط برای IP سرور CRM باز کنید:
| پورت | پروتکل | کاربرد |
|---|---|---|
5038 | TCP | AMI |
3306 | TCP | MySQL CDR |
22 | TCP | SSH — در صورت نیاز برای پخش ضبط |
8088 | TCP | به اینترنت باز نکنید؛ فقط برای Soft Phone روی localhost |
Issabel باید بتواند به آدرس CRM روی HTTPS درخواست Webhook بزند.
تست از ماشینی که به Issabel دسترسی دارد:
bash
nc -vz ISSABEL_IP 5038
nc -vz ISSABEL_IP 3306۲) کاربر AMI
فایل Manager
معمولاً یکی از اینها:
text
/etc/asterisk/manager.conf
/etc/asterisk/manager_custom.confنمونه کاربر اختصاصی CRM:
ini
[nikacrm]
secret = ChangeMe_StrongSecret_2026
deny = 0.0.0.0/0.0.0.0
permit = CRM_SERVER_IP/255.255.255.255
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,user,config,originate
writetimeout = 5000نکتهها:
permitرا فقط روی IP سرور CRM بگذارید (نه0.0.0.0/0).- برای Click-to-Call حداقل
writeشاملoriginateلازم است. - اگر داخلیها
PJSIPهستند، در CRM فیلد Channel Prefix راPJSIP/بگذارید (پیشفرض:SIP/).
اعمال:
bash
asterisk -rx "manager reload"
# یا
rasterisk -x "manager reload"تست دستی
bash
printf 'Action: Login\r\nUsername: nikacrm\r\nSecret: ChangeMe_StrongSecret_2026\r\n\r\n' \
| nc -q 2 ISSABEL_IP 5038اگر Response: Success دیدید، AMI درست است. در پنل CRM دکمه تست اتصال همین کار را میکند.
۳) داخلیها، Channel و Context
داخلی اپراتور
- در Issabel داخلی واقعی بسازید (مثلاً
1001). - همان عدد را در CRM بهعنوان داخلی پیشفرض و در اپراتورها / پرسنل منابع انسانی ذخیره کنید.
- تلفن رومیزی یا Soft Phone آن داخلی باید آنلاین باشد؛ Click-to-Call اول همان داخلی را زنگ میزند.
پیشوند کانال (Channel Prefix)
CRM کانال را اینطور میسازد:
text
{پیشوند}{داخلی}
مثال: SIP/1001 یا PJSIP/1001روی Issabel چک کنید:
bash
asterisk -rx "sip show peers"
asterisk -rx "pjsip show endpoints"همان را در تنظیمات VoIP پنل ست کنید.
Context شمارهگیری (Dial Context)
Originate نمونه:
text
Channel: SIP/1001
Context: from-internal
Exten: 09121234567
Priority: 1
Async: true
CallerID: NikaCRM <1001>پیشفرض پنل: from-internal (استاندارد FreePBX/Issabel).
اگر outbound شما context دیگری دارد، همان را در Dial Context بگذارید.
پیششماره خروجی (مثلاً 9) در فیلد مربوطه در پنل است.
۴) دسترسی MySQL به CDR (asteriskcdrdb)
لیست تماس، گزارش و بخشی از وضعیت «فعال» VoIP از این دیتابیس میآید. هر فضای کاری Host، نام کاربری و رمز خودش را در پنل ذخیره میکند.
در پنل CRM
VoIP → تنظیمات → اتصال و یکپارچگی → بخش دیتابیس CDR
| فیلد | نمونه |
|---|---|
| Host | IP یا دامنه MySQL Issabel |
| Port | 3306 |
| Database | asteriskcdrdb |
| Username | مثلاً nikacrm_cdr |
| Password | رمز کاربر فقطخواندنی |
سپس ذخیره و تست اتصال.
روی Issabel — کاربر فقطخواندنی
برای هر فضای کاری میتوانید کاربر جدا بسازید، یا یک کاربر مشترک با دسترسی فقطخواندنی بدهید و در چند فضای کاری همان مشخصات را وارد کنید:
sql
CREATE USER 'nikacrm_cdr'@'CRM_SERVER_IP' IDENTIFIED BY 'StrongCdrPassword';
GRANT SELECT ON asteriskcdrdb.* TO 'nikacrm_cdr'@'CRM_SERVER_IP';
FLUSH PRIVILEGES;اگر MySQL فقط localhost گوش میدهد، bind-address را برای دسترسی کنترلشده باز کنید و فایروال 3306 را فقط برای IP سرور CRM باز بگذارید.
تست:
bash
mysql -h ISSABEL_IP -u nikacrm_cdr -p asteriskcdrdb -e "SELECT COUNT(*) FROM cdr LIMIT 1;"بعد از اتصال CDR
- AMI و داخلیهای اپراتور / Soft Phone / صف را درست تعریف کنید.
- بدون داخلیهای شناختهشده برای فضای کاری، حتی با CDR سالم، لیست تماس فیلترشده خالی میماند.
۵) Webhook تماسها (برای پنل زنده)
بدون Webhook ممکن است Originate تلفن را زنگ بزند، ولی کارت «تماس فعال»، ringing/answered لحظهای و پاپآپ مشتری کامل نمیشود.
در CRM
- فعالسازی VoIP روشن باشد
- Webhook Secret = رشته تصادفی قوی (مثلاً خروجی
openssl rand -hex 24)
آدرس:
text
https://YOUR_CRM_HOST/api/public/voip/WORKSPACE_ID/webhookرویدادهایی که CRM میپذیرد
event | معنی | فیلدهای مهم |
|---|---|---|
incoming (پیشفرض) | زنگ / شروع | caller_id, extension, unique_id, direction, caller_id_name |
answered / answer / bridge / connect | پاسخ | unique_id, extension, caller_id, agent_name |
cdr / hangup / call_end | پایان | unique_id, phone/src, duration/billsec, disposition, recording, direction |
تست با curl از Issabel
bash
curl -sS -X POST "https://YOUR_CRM_HOST/api/public/voip/WORKSPACE_ID/webhook" \
-H "Content-Type: application/json" \
-H "X-Voip-Secret: YOUR_SECRET" \
-d '{
"event": "incoming",
"caller_id": "09121234567",
"extension": "1001",
"unique_id": "test-1730000000.1",
"direction": "inbound",
"caller_id_name": "Test"
}'پاسخ موفق معمولاً "status":"success" است.401 → Secret اشتباه.
اگر پیام غیرفعال بودن VoIP دیدید، در پنل فعالسازی را روشن کنید.
نمونه answered و CDR:
bash
# answered
curl -sS -X POST "https://YOUR_CRM_HOST/api/public/voip/WORKSPACE_ID/webhook" \
-H "Content-Type: application/json" \
-H "X-Voip-Secret: YOUR_SECRET" \
-d '{"event":"answered","unique_id":"test-1730000000.1","extension":"1001","caller_id":"09121234567"}'
# cdr
curl -sS -X POST "https://YOUR_CRM_HOST/api/public/voip/WORKSPACE_ID/webhook" \
-H "Content-Type: application/json" \
-H "X-Voip-Secret: YOUR_SECRET" \
-d '{
"event":"cdr","unique_id":"test-1730000000.1","src":"09121234567",
"duration":95,"billsec":90,"disposition":"ANSWERED","extension":"1001",
"direction":"inbound","recording":"2026/08/02/out-1001-09121234567.wav"
}'۶) اتصال Dialplan / AGI به Webhook
اسکریپت نمونه روی Issabel
مسیر پیشنهادی:
text
/var/lib/asterisk/agi-bin/nikacrm-voip-webhook.shbash
#!/bin/bash
# usage: nikacrm-voip-webhook.sh <event> <uniqueid> <caller> <extension> [duration] [disposition] [recording]
EVENT="$1"
UNIQUE="$2"
CALLER="$3"
EXTEN="$4"
DURATION="${5:-0}"
DISPO="${6:-}"
RECORDING="${7:-}"
CRM_URL="https://YOUR_CRM_HOST/api/public/voip/WORKSPACE_ID/webhook"
SECRET="YOUR_SECRET"
PAYLOAD=$(cat <<EOF
{"event":"${EVENT}","unique_id":"${UNIQUE}","caller_id":"${CALLER}","extension":"${EXTEN}","duration":${DURATION},"disposition":"${DISPO}","recording":"${RECORDING}","direction":"inbound"}
EOF
)
curl -sS -m 5 -X POST "$CRM_URL" \
-H "Content-Type: application/json" \
-H "X-Voip-Secret: ${SECRET}" \
-d "$PAYLOAD" >/dev/null 2>&1 &bash
chmod +x /var/lib/asterisk/agi-bin/nikacrm-voip-webhook.sh
chown asterisk:asterisk /var/lib/asterisk/agi-bin/nikacrm-voip-webhook.shقلاب dialplan (نمونه مفهومی)
Context ورودی بسته به نسخه فرق میکند (from-pstn, from-trunk, …). ایده: بعد از دانستن CallerID و داخلی، اسکریپت را صدا بزنید.
در extensions_custom.conf:
ini
[from-pstn-custom]
exten => _X.,1,NoOp(NikaCRM incoming hook)
same => n,System(/var/lib/asterisk/agi-bin/nikacrm-voip-webhook.sh incoming ${UNIQUEID} ${CALLERID(num)} ${EXTEN})
same => n,Return()برای answered / hangup معمولاً از hangup handler یا CDR custom استفاده میشود. همان unique_id باید از شروع تا پایان حفظ شود.
نکته
اگر فعلاً فقط CDR MySQL دارید و Webhook را بعداً میگذارید، لیست تماس از دیتابیس میآید؛ ولی «تماس فعال» لحظهای ضعیفتر است.
۷) ضبط مکالمه
- در Issabel ضبط را برای داخلی/صف موردنظر روشن کنید.
- مسیر پیشفرض مانیتور معمولاً:
/var/spool/asterisk/monitor - در تنظیمات CRM:
- فعالسازی ضبط تماس
- مسیر Monitor روی Issabel
- در صورت نیاز آدرس پایه HTTP یا مشخصات SSH برای پخش فایل
در Webhook رویداد پایان تماس، فیلد recording یا recordingfile را بفرستید.
جزئیات شنود در پنل: ضبط مکالمه.
۸) پر کردن پنل CRM (بعد از Issabel)
مسیر: VoIP → تنظیمات → اتصال و یکپارچگی
| فیلد | مقدار نمونه |
|---|---|
| فعالسازی VoIP | روشن |
| AMI Host | IP یا دامنه Issabel |
| AMI Port | 5038 |
| AMI Username | nikacrm |
| AMI Secret | رمز manager |
| CDR Host / Port / DB / User / Password | اتصال MySQL به asteriskcdrdb |
| Default Extension | 1001 |
| Channel Prefix | SIP/ یا PJSIP/ |
| Dial Context | from-internal |
| پیششماره خروجی | مثلاً 9 |
| Webhook Secret | همان secret اسکریپت |
| SSH / Recording | در صورت نیاز برای پخش فایل |
سپس:
- تست اتصال → موفق شود.
- از تلفن یک Click-to-Call تست بزنید → داخلی زنگ بخورد.
- با curl یا تماس واقعی Webhook را تست کنید → در تماسها / داشبورد دیده شود.
- اپراتور، صف، مسیر Click-to-Call و در صورت نیاز Soft Phone را کامل کنید.
۹) ترتیب پیشنهادی اجرا (چکلیست)
- فایروال
5038(و در صورت نیاز3306و22) را برای IP CRM باز کنید. - کاربر AMI بسازید و
manager reloadکنید. - از CRM تست AMI بزنید.
- داخلی تست بسازید / آنلاین کنید؛ داخلی پیشفرض را ست کنید.
- Channel Prefix و Dial Context را با واقعیت Issabel همخوان کنید.
- کاربر MySQL فقطخواندنی روی Issabel بسازید و Host/User/Password را در بخش CDR پنل ذخیره کنید؛ تست اتصال را بزنید.
- Webhook Secret را بسازید و در پنل ذخیره کنید.
- اسکریپت webhook را روی Issabel بگذارید و با curl تست کنید.
- dialplan/CDR hook را وصل کنید.
- ضبط را روشن کنید و یک تماس رفتوبرگشت کامل تست کنید.
- برای تماس از مرورگر: راهاندازی Soft Phone.
- در CRM: اپراتور، صف، عضو صف، مسیر CTC را با داخلیهای واقعی پر کنید.
۱۰) ارتباط ماژول با بقیه CRM
| بخش CRM | نقش |
|---|---|
| پرونده مشتری → تماسها | تاریخچه تماس روی پروفایل |
| HCMS / پرسنل | داخلی مبدأ اپراتور وقتی Soft Phone خاموش است |
| گردش کار | رویدادهای پیگیری / اپراتور / صف / قالب |
| گزارشساز | منابع گزارش ماژول VoIP |
| پیامک / قالبها | قالبها در تنظیمات VoIP تعریف میشوند؛ ارسال خودکار روی همه رویدادها تضمین نیست — مسیر را تست کنید |
۱۱) عیبیابی سریع
| مشکل | احتمال علت |
|---|---|
| تست AMI ناموفق / timeout | فایروال، permit اشتباه، AMI روی IP دیگر bind شده |
| Auth failed | username/secret یا reload نشدن manager |
| Originate میرود ولی تلفن زنگ نمیخورد | داخلی آفلاین، SIP/ بهجای PJSIP/، context اشتباه |
| لیست تماس خالی | Host/User/Password بخش CDR در پنل، GRANT/فایروال MySQL، یا داخلیهای فضای کاری خالی/اشتباه |
| Webhook 401 | Secret هدر با پنل یکی نیست |
| Webhook نادیده گرفته شد / VoIP غیرفعال | فعالسازی VoIP در پنل خاموش است |
| تماس فعال در پنل نمیآید | webhook incoming/answered نمیرسد یا unique_id خالی است |
| ضبط پخش نمیشود | مسیر فایل، SSH، فعال بودن ضبط، نام فایل در CDR |
| Soft Phone رجیستر نمیشود | راهنمای Soft Phone |
لاگ مفید روی Issabel:
bash
tail -f /var/log/asterisk/full
asterisk -rx "manager show connected"نکات کلیدی و سوالات متداول
هشدار امنیتی
Secretهای AMI، Webhook و SIP را در تیکت عمومی ننویسید. پورت 8088 Asterisk HTTP را به اینترنت باز نکنید.
نکته کاربردی
اول AMI و CDR را سبز کنید؛ بعد Webhook؛ در آخر Soft Phone. ترتیب برعکس عیبیابی را سخت میکند.
سوال: منوی صوتی (IVR) کجای CRM است؟
پاسخ: صفحه جدا در پنل نیست؛ IVR فقط روی Issabel / dialplan پیکربندی میشود.سوال: Soft Phone کامل کجاست؟
پاسخ: راهاندازی Soft Phone.سوال: بعد از Apply Config در Issabel Soft Phone قطع میشود؟
پاسخ: HTTP Asterisk را پایدار نگه دارید (بخش HTTP در سند Soft Phone) و در صورت تکرار با پشتیبانی فنی هماهنگ کنید.