Metadata-Version: 2.4
Name: aicaller-sdk
Version: 0.1.0
Summary: Python SDK cho hệ thống AI Caller — cấu hình kịch bản, gửi SĐT cho AI gọi, đọc kết quả & lịch sử cuộc gọi qua REST API /api/v1.
Project-URL: Homepage, https://github.com/your-org/aicaller
Project-URL: Documentation, https://github.com/your-org/aicaller/tree/main/sdk/python
Author: AI Caller
License: MIT
Keywords: call-center,sdk,telesales,voice-ai
Requires-Python: >=3.9
Requires-Dist: httpx<1,>=0.24
Requires-Dist: pydantic<3,>=2
Provides-Extra: dev
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Description-Content-Type: text/markdown

# aicaller — Python SDK

SDK Python cho hệ thống **AI Caller** (gọi điện telesales bằng AI). Cho phép đội CRM
tích hợp: cấu hình kịch bản/tiêu chí, **gửi SĐT cho AI gọi**, đọc kết quả chấm điểm,
tải ghi âm, lấy lịch sử cuộc gọi — qua REST API `/api/v1` bằng **API key**.

> Thiết kế đầy đủ (endpoint, scope, webhook, điều kiện tiên quyết) xem
> [`docs/phases/phase-7-public-api-sdk.md`](../../docs/phases/phase-7-public-api-sdk.md).

## Cài đặt

```bash
pip install aicaller-sdk          # từ PyPI / private index (khi đã publish)

# hoặc cài từ mã nguồn trong repo (dev):
pip install -e sdk/python
```

Yêu cầu Python ≥ 3.9. Phụ thuộc: `httpx`, `pydantic v2`.

## Lấy API key

Tạo trên Portal → **Cài đặt → API keys → Tạo key**. Full key (`sk_live_...`) chỉ hiện
**1 lần**; lưu vào biến môi trường, đừng hard-code.

## Quickstart

```python
import os
from aicaller import AICallerClient

client = AICallerClient(
    api_key=os.environ["AICALLER_API_KEY"],   # "sk_live_..."
    base_url="https://your-app.com",           # mặc định http://localhost:3000
)

# 1) Cấu hình kịch bản + tiêu chí
sc = client.scenarios.create(name="Bán bảo hiểm", content_md="# Xin chào ...")
cr = client.criteria.create(name="Chấm telesales", content_md="## Nhóm điểm ...")

# 2) Gửi SĐT cho AI gọi (vào campaign đã tạo sẵn trên Portal)
client.campaigns.add_customers(
    campaign_id=7,
    customers=[
        {"phone": "0901234567", "name": "Nguyễn Văn A", "metadata": {"crm_id": "C-123"}},
        {"phone": "+84902345678", "name": "Trần B"},
    ],
)
client.campaigns.start(campaign_id=7)

# 3) Lịch sử + kết quả chấm điểm (tự lật hết các trang)
for call in client.calls.iter(campaign_id=7, outcome="potential"):
    detail = client.calls.get(call.id)     # score, outcome, summary, group_scores, transcript
    print(detail.id, detail.score, detail.summary)

# 4) Tải ghi âm (signed URL từ R2, hết hạn sau ít phút)
link = client.calls.recording_url(call_id=123)
print(link.url)
```

## Nhận kết quả qua Webhook (khỏi phải poll)

Khai báo `webhook_url` khi tạo API key. Khi mỗi cuộc gọi chấm điểm xong, server đẩy
`POST {webhook_url}` với event `call.scored`, ký HMAC-SHA256 ở header `X-Signature`.

```python
# Trong endpoint CRM của bạn (ví dụ Flask):
from aicaller import webhooks

@app.post("/aicaller/webhook")
def hook():
    raw = request.get_data()                       # RAW body, KHÔNG json.loads trước
    sig = request.headers.get("X-Signature", "")
    try:
        event = webhooks.verify(raw, sig, secret=os.environ["AICALLER_WEBHOOK_SECRET"])
    except webhooks.WebhookVerificationError:
        return "", 400
    # event.call_id, event.score, event.outcome, event.customer["crm_id"] ...
    return "", 200
```

## Xử lý lỗi

Mọi lỗi kế thừa `AICallerError`:

| Lớp | Khi nào |
|-----|---------|
| `AuthenticationError` | 401 — key sai / thu hồi |
| `PermissionError_` | 403 — thiếu scope |
| `NotFoundError` | 404 — không thấy (hoặc không thuộc key) |
| `ValidationError_` | 400/422 — payload sai |
| `RateLimitError` | 429 — vượt rate limit/quota (có `.retry_after`) |
| `ServerError` | 5xx |
| `APIConnectionError` | không kết nối được |

SDK tự retry (backoff) cho lỗi mạng + 429/5xx; **không** retry lỗi logic 4xx.

```python
from aicaller import RateLimitError

try:
    client.campaigns.start(7)
except RateLimitError as e:
    print("Chờ", e.retry_after, "giây")
```

## Tài nguyên & method

| Resource | Method |
|----------|--------|
| `client.scenarios` | `list`, `get`, `create`, `update` |
| `client.criteria` | `list`, `get`, `create`, `update` |
| `client.campaigns` | `list`, `get`, `add_customers`, `list_customers`, `start`, `pause` |
| `client.calls` | `list`, `iter`, `get`, `recording_url` |
| `client.webhooks`* | `verify`, `compute_signature` (module `aicaller.webhooks`) |

\* Webhook là module tiện ích, không cần API key.

## Chạy test (dev)

```bash
pip install -e "sdk/python[dev]"
pytest sdk/python
```

Test dùng `httpx.MockTransport` — không cần server thật, không đụng mạng.

## Tài liệu API đầy đủ

- Trang tương tác (Redoc): `https://your-app.com/api-docs.html`
- Spec máy đọc (OpenAPI 3.0): `https://your-app.com/openapi.yaml` — dùng để sinh client cho ngôn ngữ khác.

## Versioning

SDK pin `/api/v1`. Server đổi phá vỡ → lên `/api/v2` + SDK bump major; v1 giữ nguyên
để tích hợp cũ không vỡ.
