Metadata-Version: 2.4
Name: bloonio-chat-relay-client
Version: 0.1.1
Summary: Client SDK for the bloonio_chat_relay. Backend integration for the bloonio chat PaaS — provision conversations, send messages, mint visitor tokens, receive HMAC-signed webhook callbacks. Framework-agnostic core + thin FastAPI / Django adapters.
Author: Bloonio
License-Expression: LicenseRef-Proprietary
Project-URL: Repository, https://github.com/Bloonio/bloonio_chat_relay_client
Keywords: bloonio,chat,support,customer-support,webhook,paas
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Chat
Classifier: Operating System :: POSIX
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.6
Requires-Dist: pydantic-settings>=2.2
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.110; extra == "fastapi"
Requires-Dist: starlette>=0.36; extra == "fastapi"
Provides-Extra: django
Requires-Dist: django>=4.2; extra == "django"
Provides-Extra: redis
Requires-Dist: redis>=5.0; extra == "redis"
Provides-Extra: all
Requires-Dist: fastapi>=0.110; extra == "all"
Requires-Dist: starlette>=0.36; extra == "all"
Requires-Dist: django>=4.2; extra == "all"
Requires-Dist: redis>=5.0; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"
Dynamic: license-file

# bloonio_chat_relay_client

Python SDK for `bloonio_chat_relay`. Lets a tenant backend integrate the
bloonio chat PaaS via the same `tenant_id` + `tenant_secret` model that
`bloonio_auth_relay_client` uses for auth.

## Install

```bash
pip install bloonio-chat-relay-client[fastapi]   # for FastAPI tenants
pip install bloonio-chat-relay-client[django]    # for Django tenants
pip install bloonio-chat-relay-client            # framework-agnostic core only
```

## Two-minute integration (FastAPI)

```python
# .env
BLOONIO_CHAT_BASE_URL=https://chat-relay.example.com
BLOONIO_CHAT_TENANT_ID=<uuid>
BLOONIO_CHAT_TENANT_SECRET=sk_...
BLOONIO_CHAT_CALLBACK_BASE_URL=https://your-backend.example.com
```

```python
# main.py
from fastapi import FastAPI
from bloonio_chat_relay_client.adapters.fastapi import BloonioChatAdapter

app = FastAPI()
BloonioChatAdapter.from_env(app)   # mounts /api/v1/chat-callbacks/* + wires the client
```

```python
# anywhere
from bloonio_chat_relay_client import get_chat_client

chat = get_chat_client()
convo = chat.create_conversation(
    visitor_user_id="user-123",
    visitor_display_name="Marie",
    locale="fr",
    metadata={"order_id": "ORD-9981"},
)
chat.send_message(convo.id, role="visitor", content="Where is my order?")

# For in-app SDKs (web/Flutter) — mint a short-lived signed token your
# client SDK uses to authenticate its WebSocket to chat-relay.
token = chat.mint_visitor_token(
    visitor_user_id="user-123",
    visitor_email_hash="sha256:...",
    ttl_seconds=3600,
)
```

## Public surface

```python
from bloonio_chat_relay_client import (
    ChatRelayClient,         # sync
    AsyncChatRelayClient,    # async
    ChatRelaySettings,
    ChatRelayError,
    # Domain types (Pydantic)
    Conversation,
    Message,
    Ticket,
    KnowledgeDocument,
    WebhookEvent,
    # Enums
    MessageRole,
    ConversationStatus,
    TicketStatus,
    TicketPriority,
    WebhookEventType,
)
```

## Webhook callbacks

The adapter mounts nine HMAC#1-verified endpoints under
`/api/v1/chat-callbacks/*`:

| Path | Event | Phase |
|---|---|---|
| `POST /api/v1/chat-callbacks/conversation-started` | New conversation opened | 8 |
| `POST /api/v1/chat-callbacks/message-received`     | Visitor sent a message | 8 |
| `POST /api/v1/chat-callbacks/ticket-created`       | Ticket auto-created via escalation | 8 |
| `POST /api/v1/chat-callbacks/ticket-assigned`      | Ticket claimed by a human agent | 8 |
| `POST /api/v1/chat-callbacks/ticket-resolved`      | Ticket marked resolved | 8 |
| `POST /api/v1/chat-callbacks/escalation-triggered` | Bot escalated to human handoff | 8 |
| `POST /api/v1/chat-callbacks/agent-assigned`       | Operator claimed a conversation (visitor handoff in progress) | **10a** |
| `POST /api/v1/chat-callbacks/agent-released`       | Operator released the conversation back to inbox | **10a** |
| `POST /api/v1/chat-callbacks/agent-resolved`       | Operator marked the conversation resolved | **10a** |

Provide handlers in `BloonioChatAdapter.from_env(app, handlers={...})`
to react to events on your side. Handlers are optional — events without
a registered handler are accepted (HMAC#1 verified), logged at debug, and
return `{"received": True}`.

### Agent-takeover event payloads (phase 10a)

The three `agent_*` events share the same body shape:

```jsonc
{
  "conversation_id": "<chat_api ObjectId>",
  "tenant_id": "<UUID v7>",
  "status": "ASSIGNED" | "WAITING" | "RESOLVED",
  "operator_id": "<UUID v7>",
  "operator_display_name": "Sarah Chen",   // only on agent_assigned
  "visitor_session_id": "vs_<base64url>",
  "escalation_reason": "user_requested" | "restricted_topic" | "low_confidence" | "user_request" | "direct" | null,
  "claim_count": 1,
  "claimed_at":  "2026-05-22T12:34:56Z",
  "released_at": null,
  "resolved_at": null
}
```

Use these to update your CRM, send push notifications, or trigger
analytics — apps_api's `ChatIntegrationService.handle_agent_assigned(...)`
is the canonical reference handler (phase 10d).

## Relationship to `bloonio_auth_relay_client`

This SDK is the chat analog of `bloonio_auth_relay_client`. The HMAC
scheme is identical (header names, signature format, replay-protection
window), so a backend that already integrates the auth SDK can reuse
operator muscle memory. Only the domain types and the wrapped methods
differ. See
`bloonio_chat_api/docs/12_PAAS_CONVERSION_PLAN.md` §4.2 / §7.1.

## License

Proprietary — Bloonio internal.
