Metadata-Version: 2.4
Name: simotel-connect
Version: 1.0.0
Summary: A professional Django/Python client for the Simotel PBX API
License: MIT
Keywords: simotel,pbx,voip,django,api,asterisk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Framework :: Django
Classifier: Topic :: Communications :: Telephony
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.28.0
Provides-Extra: django
Requires-Dist: django>=3.2; extra == "django"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-django; extra == "dev"
Requires-Dist: responses>=0.23; extra == "dev"
Requires-Dist: django>=3.2; extra == "dev"

# 📞 Simotel Connect (کتابخانه پایتون و جنگو برای سیموتل)

[![Python Versions](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue)](https://pypi.org/project/simotel-connect/)
[![Django](https://img.shields.io/badge/django-%3E%3D3.2-green)](https://www.djangoproject.com/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

یک پکیج پایتونی و ماژول Reusable Django حرفه‌ای، مقیاس‌پذیر و تمیز برای ارتباط با وب‌سرویس **مرکز تلفن سیموتل (Simotel PBX API v4)**.

---

## 🌟 ویژگی‌ها

- 🔐 **پشتیبانی کامل از احراز هویت دوگانه سیموتل** (`X-APIKEY` به همراه HTTP Basic Auth)
- ⚙️ **سیستم کانفیگ انعطاف‌پذیر و سه لایه** (Django `settings.py` > متغیرهای محیطی `.env` > ورودی مستقیم سازنده)
- 🏗️ **طراحی ماژولار با الگوهای Facade و Manager**: تمام متدها دسته‌بندی‌شده و خوانا
- 🔄 **مکانیزم Retry و Connection Pooling خودکار** با Session پایدار
- 🛡️ **مدیریت خطای جامع (Exception Handling)** با خطاهای اختصاصی
- 📊 **پوشش کامل بیش از ۸۰ اندپوینت سیموتل**:
  - مدیریت کاربران و داخلی‌ها (`users`)
  - ترانک‌ها (`trunks`)
  - صف‌ها و اپراتورها به صورت تک و گروهی (`queues`, `agents`)
  - لیست سیاه و سفید (`blacklists`, `whitelists`)
  - فایل‌های صوتی و اعلامیه‌ها (`announcements`)
  - موسیقی انتظار (`musiconholds`)
  - ارسال، دریافت و دانلود فکس (`faxes`)
  - برقراری تماس خودکار (Click-to-Call / `originate`)
  - صندوق‌های صوتی و دانلود پیام (`voicemails`)
  - گزارشات کامل CDR، صف، اپراتور، نظرسنجی و دانلود فایل صوتی مکالمه تک و دو کاناله (`reports`)
  - ماژول تماس انبوه و کمپین‌ها (`autodialer`)
  - بررسی وضعیت اتصال (`ping`)

---

## 📦 نصب

نصب در محیط پروژه:

```bash
pip install simotel-connect
```

یا برای توسعه به صورت Editable:

```bash
git clone https://github.com/yourusername/simotel-django-app.git
cd simotel-django-app
pip install -e ".[dev]"
```

---

## ⚙️ راه‌اندازی و کانفیگ

### روش ۱: از طریق Django `settings.py` (توصیه‌شده برای پروژه‌های جنگو)

در فایل `settings.py` پروژه جنگو:

```python
# settings.py

INSTALLED_APPS = [
    ...,
    "simotel_connect",
]

SIMOTEL = {
    "HOST": "192.168.1.10",             # آدرس IP یا دامنه سرور سیموتل
    "API_KEY": "YOUR_SIMOTEL_API_KEY",  # از مسیر Maintenance > API Accounts
    "USERNAME": "admin",                # نام کاربری پنل سیموتل
    "PASSWORD": "your_password",        # رمز عبور سیموتل
    "PORT": 80,                         # اختیاری (پیش‌فرض 80)
    "SCHEME": "http",                   # اختیاری (پیش‌فرض http)
    "TIMEOUT": 30,                      # اختیاری (پیش‌فرض 30 ثانیه)
    "VERIFY_SSL": True,                 # اختیاری
}
```

سپس در هر کجای پروژه (Views, Celery Tasks, Services):

```python
from simotel_connect import Simotel

# به صورت خودکار مقادیر را از settings.py می‌خواند
sm = Simotel()
```

---

### روش ۲: از طریق متغیرهای محیطی (`.env`)

```env
SIMOTEL_HOST=192.168.1.10
SIMOTEL_API_KEY=YOUR_SIMOTEL_API_KEY
SIMOTEL_USERNAME=admin
SIMOTEL_PASSWORD=your_password
SIMOTEL_TIMEOUT=30
```

```python
from simotel_connect import Simotel

sm = Simotel()
```

---

### روش ۳: مقداردهی مستقیم (بدون جنگو یا چند سروری)

```python
from simotel_connect import Simotel

sm = Simotel(
    host="192.168.1.10",
    api_key="YOUR_SIMOTEL_API_KEY",
    username="admin",
    password="your_password",
    timeout=15,
)
```

---

## 🚀 راهنمای کاربردی و مثال‌ها

### ۱. تست وضعیت اتصال (Health Check)

```python
response = sm.setting.ping()
if response.success:
    print("اتصال به سیموتل برقرار است:", response.message)
```

---

### ۲. برقراری تماس (Click-to-Call / Originate)

```python
# تماس بین یک داخلی و شماره موبایل
resp = sm.call.originate(
    src_type="internal",
    src_number="1001",
    dst_type="trunk",
    dst_number="09121234567",
    caller_id="1001"
)

# تماس بین دو داخلی
resp = sm.call.originate(
    src_type="internal",
    src_number="1001",
    dst_type="internal",
    dst_number="1002"
)
```

---

### ۳. مدیریت کاربران و داخلی‌ها (Users)

```python
# افزودن داخلی جدید
sm.pbx.users.add(
    extension="1001",
    name="علی رضایی",
    password="StrongPassword123",
    email="ali@example.com",
    mobile="09121234567"
)

# جستجوی کاربران
users = sm.pbx.users.search(extension="1001")
print(users.data)

# ویرایش کاربر
sm.pbx.users.update(extension="1001", name="علی رضایی (پشتیبانی)")

# حذف کاربر
sm.pbx.users.remove(extension="1001")
```

---

### ۴. مدیریت صف‌ها و اپراتورها (Queues)

```python
# ایجاد صف جدید
sm.pbx.queues.add(name="2000", strategy="leastrecent", timeout=30)

# افزودن اپراتور به صف
sm.pbx.queues.add_agent(queue="2000", agent="1001", penalty=0)

# شروع استراحت اپراتور (Pause)
sm.pbx.queues.pause_agent(queue="2000", agent="1001", reason="استراحت ناهار")

# پایان استراحت اپراتور (Resume)
sm.pbx.queues.resume_agent(queue="2000", agent="1001")

# افزودن دسته‌ای اپراتورها
sm.pbx.queues.batch_add_agent(queue="2000", agents=["1001", "1002", "1003"])

# توقف دسته‌ای اپراتورها
sm.pbx.queues.batch_pause_agent(queue="2000", agents=["1001", "1002"])

# خروج اپراتور از صف
sm.pbx.queues.remove_agent(queue="2000", agent="1001")
```

---

### ۵. گزارشات و دانلود صوت مکالمات (Reports)

```python
# گزارش CDR تماس‌ها در بازه زمانی
cdr = sm.reports.cdr_search(
    from_date="2024-01-01 08:00:00",
    to_date="2024-01-31 18:00:00",
    limit=50
)
for call in cdr.data:
    print(call)

# گزارش صف‌ها
queue_report = sm.reports.queue_search(queue="2000")

# گزارش عملکرد اپراتورها
agent_report = sm.reports.agent_search(agent="1001")

# دانلود فایل صوتی مکالمه ضبط‌شده
audio_bytes = sm.reports.download_audio(call_id="unique_call_id_123")
with open("recorded_call.wav", "wb") as f:
    f.write(audio_bytes)

# دانلود مکالمه دو کاناله (کانال اپراتور و مشتری مجزا)
dual_audio = sm.reports.download_audio_dual_channel(call_id="unique_call_id_123")
with open("dual_call.wav", "wb") as f:
    f.write(dual_audio)
```

---

### ۶. لیست سیاه و سفید (Blacklist & Whitelist)

```python
# مسدود کردن شماره مزاحم
sm.pbx.blacklists.add(number="09999999999", description="مزاحم تلفنی")

# رفع مسدودیت
sm.pbx.blacklists.remove(number="09999999999")

# افزودن به لیست سفید (مشتری VIP)
sm.pbx.whitelists.add(number="09120000000", description="مدیرعامل")
```

---

### ۷. تماس خودکار و کمپین‌ها (Autodialer)

```python
# آپلود فایل صوتی کمپین
sm.autodialer.announcements.upload(
    file_path="/path/to/promo.wav",
    name="جشنواره_نوروزی"
)

# ایجاد گروه مخاطبین
sm.autodialer.groups.add(name="مشتریان_ویژه")

# افزودن مخاطب به گروه
sm.autodialer.contacts.add(
    number="09121234567",
    name="محمد محمدی",
    group="مشتریان_ویژه"
)

# ایجاد کمپین تماس انبوه
sm.autodialer.campaigns.add(
    name="کمپین عیدانه",
    announcement="جشنواره_نوروزی",
    group="مشتریان_ویژه",
    trunk="main_trunk"
)

# مشاهده گزارشات کمپین
reports = sm.autodialer.reports.search(campaign="کمپین عیدانه")
```

---

## ⚠️ مدیریت خطاها (Exception Handling)

تمام خطاهای پکیج از `SimotelError` ارث‌بری دارند:

```python
from simotel_connect import (
    Simotel,
    SimotelError,
    SimotelAuthError,
    SimotelAPIError,
    SimotelConnectionError,
    SimotelTimeoutError,
)

sm = Simotel()

try:
    sm.call.originate(src_type="internal", src_number="1001", dst_type="internal", dst_number="1002")
except SimotelAuthError:
    print("خطا در نام کاربری، رمز عبور یا API Key سیموتل")
except SimotelAPIError as e:
    print(f"سیموتل با پیام خطا پاسخ داد: {e.args[0]}")
    print(f"اطلاعات خطا: {e.data}")
except SimotelConnectionError:
    print("ارتباط با سرور سیموتل برقرار نشد (بررسی شبکه یا IP)")
except SimotelTimeoutError:
    print("درخواست با تایم‌اوت مواجه شد")
except SimotelError as e:
    print(f"خطای نامشخص سیموتل: {e}")
```

---

## 🧪 اجرای تست‌ها

```bash
pip install -e ".[dev]"
pytest simotel_connect/tests/ -v
```

---

## 📄 لایسنس

این پروژه تحت مجوز **MIT** منتشر شده است.
