commit dee06ba093282f19b778079dc7db459acb6cfe86 Author: Mehdi Aslani Date: Sat Jul 18 01:24:53 2026 +0330 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..9799fdb --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ +# چت‌بات تلفنی فارسی (Asterisk + STT + Ollama + TTS) + +## ساختار پروژه +``` +voicebot/ +├── docker-compose.yml +├── .env.example # قالب فایل تنظیمات - کپی کن به .env و پرش کن +├── asterisk/ +│ ├── Dockerfile +│ ├── entrypoint.sh # کانفیگ‌ها رو موقع استارت از .env می‌سازه +│ ├── templates/ # قالب‌های کانفیگ (دستی ادیت نکن) +│ │ ├── pjsip-base.conf.template +│ │ ├── pjsip-trunk.conf.template +│ │ ├── extensions.conf.template +│ │ ├── agi.conf +│ │ └── modules.conf +│ └── config/ # اینجا خالیه - خروجی خودکار ساخته می‌شه +├── agi-scripts/ +│ └── voicebot.py # orchestrator اصلی (STT -> Ollama -> TTS) +├── stt/ # سرویس گفتار-به-متن (faster-whisper) +├── tts/ # سرویس متن-به-گفتار (Piper) +└── models/ + ├── whisper/ # مدل‌ whisper اینجا کش می‌شه (خودکار دانلود می‌شه) + └── piper/ # باید مدل صدای فارسی رو دستی بذاری + +``` + +## همه‌ی تنظیمات فقط در یک فایل: `.env` + +دیگه لازم نیست تو چند فایل کانفیگ Asterisk بگردی. کافیه `.env.example` رو کپی کنی و مقادیر رو پر کنی: + +```bash +cp .env.example .env +nano .env # یا هر ادیتوری که دوست داری +``` + +محتوای فایل: + +```ini +# ---------- Ollama ---------- +OLLAMA_URL=http://OLLAMA_HOST:11434/api/generate +OLLAMA_MODEL=llama3 + +# ---------- STT (faster-whisper) ---------- +WHISPER_MODEL=medium +WHISPER_DEVICE=cpu + +# ---------- TTS (Piper) ---------- +PIPER_VOICE=/models/piper/fa_IR-model.onnx + +# ---------- ترانک مرکز تماس شماره ۱ ---------- +TRUNK1_NAME=callcenter1 +TRUNK1_HOST=CALLCENTER1_IP +TRUNK1_USERNAME=USERNAME +TRUNK1_PASSWORD=CALLCENTER1_PASS + +# ---------- ترانک مرکز تماس شماره ۲ (اختیاری) ---------- +TRUNK2_NAME= +TRUNK2_HOST= +TRUNK2_USERNAME= +TRUNK2_PASSWORD= + +# ---------- SIP User داخلی (تست) ---------- +TEST_USER_EXTEN=1000 +TEST_USER_PASSWORD=CHANGE_ME_STRONG_PASSWORD +``` + +با هر بار اجرای `docker compose up -d --build`، اسکریپت `entrypoint.sh` داخل کانتینر Asterisk خودکار فایل‌های `pjsip.conf` و `extensions.conf` رو از روی همین `.env` می‌سازه. یعنی: +- اگه `TRUNK2_HOST` رو خالی بذاری، ترانک دوم اصلاً ساخته نمی‌شه. +- اگه پرش کنی، ترانک دوم هم خودکار به `pjsip.conf` اضافه می‌شه (بدون این‌که چیزی رو دستی بنویسی). +- تغییر شماره‌ی تست (`TEST_USER_EXTEN`) هم فقط با عوض کردن همین متغیر انجام می‌شه. + +> ⚠️ فایل `.env` رو در `.gitignore` نگه دار (چون رمزها توشه) - فقط `.env.example` رو commit کن. +> +> 💡 بعد از هر تغییر در `.env`، کافیه `docker compose up -d` بزنی (نیازی به `--build` نیست، چون کانفیگ موقع استارت کانتینر ساخته می‌شه، نه موقع build). فقط اگه خود Dockerfile یا کد رو عوض کردی `--build` لازمه. + +## مرحله ۱: دانلود مدل صدای فارسی Piper + +Piper به یک مدل ONNX فارسی نیاز دارد. مدل‌های آماده را از مخزن رسمی دانلود کن: + +```bash +mkdir -p models/piper +cd models/piper +wget https://huggingface.co/rhasspy/piper-voices/resolve/main/fa/fa_IR/gyro/medium/fa_IR-gyro-medium.onnx -O fa_IR-model.onnx +wget https://huggingface.co/rhasspy/piper-voices/resolve/main/fa/fa_IR/gyro/medium/fa_IR-gyro-medium.onnx.json -O fa_IR-model.onnx.json +cd ../.. +``` +> اگر لینک بالا در دسترس نبود، در صفحه‌ی huggingface.co/rhasspy/piper-voices دنبال پوشه‌ی `fa/fa_IR` بگرد و آخرین نسخه رو بردار. + +## مرحله ۲: تنظیم اطلاعات ترانک SIP و Ollama + +همه‌ی این‌ها الان در همون فایل `.env` هست (بخش بالا رو ببین) - نیازی به دست زدن به فایل‌های داخل `asterisk/` نیست. + +## مرحله ۳: بالا آوردن سرویس‌ها + +```bash +docker compose up -d --build +docker compose logs -f asterisk +``` + +بار اول که stt-service بالا میاد، مدل whisper (چند صد مگابایت) دانلود می‌شه - صبر کن کامل بشه. + +## مرحله ۴: تست + +با هر سافت‌فون (مثل Zoiper یا Linphone) به extension داخلی که در `.env` تحت `TEST_USER_EXTEN` تعریف کردی (پیش‌فرض `1000`) با یوزر `test-user` و پسورد `TEST_USER_PASSWORD` وصل شو و تماس بگیر. باید صدای خوش‌آمدگویی رو بشنوی، بعد صحبت کن و منتظر پاسخ بات باش. + +برای اتصال واقعی مرکز تماس، تماس روی ترانک PJSIP وارد context به نام `from-trunk` می‌شه که در `extensions.conf` تعریف شده. + +## نکات مهم برای Production + +1. **لتنسی**: اگه سرعت پاسخ کند بود: + - مدل whisper رو از `medium` به `small` تغییر بده (دقت کمتر، سرعت بیشتر) + - اگه GPU داری، `WHISPER_DEVICE=cuda` رو در docker-compose ست کن + - مدل Ollama رو سبک‌تر انتخاب کن (مثلاً یک مدل 7B به جای 70B) + +2. **Barge-in (قطع صحبت بات)**: نسخه‌ی فعلی ساده است (نوبتی: بات حرف می‌زنه، بعد کاربر). برای barge-in واقعی باید از AMI events مثل `TALK_DETECT` استفاده کنی که پیچیده‌تره - در صورت نیاز می‌تونم اضافه‌اش کنم. + +3. **مدیریت چند تماس همزمان**: چون AGI برای هر تماس یک پراسس جداست، همزمانی به‌صورت خودکار پشتیبانی می‌شه؛ فقط مطمئن شو سرویس‌های STT/TTS/Ollama منابع کافی (CPU/RAM/GPU) برای بار همزمان دارن. + +4. **امنیت SIP Trunk**: حتماً `type=identify` رو با IP دقیق مرکز تماس محدود کن و فایروال روی پورت 5060 و رنج RTP بذار. + +5. **لاگ و مانیتورینگ**: `agi.verbose()` در اسکریپت لاگ‌ها رو تو کنسول Asterisk می‌ریزه (`asterisk -rvvv` برای دیدن زنده). + +## گام بعدی (اختیاری) +اگه بخوای می‌تونم این‌ها رو هم اضافه کنم: +- پشتیبانی از AMI برای barge-in و real-time monitoring +- ذخیره‌ی تاریخچه‌ی مکالمات در دیتابیس (برای گزارش‌گیری) +- health-check و auto-restart برای سرویس‌ها +- صف تماس (queue) قبل از رسیدن به بات