Metadata-Version: 2.4
Name: nobox-chat-sdk
Version: 1.0.1
Summary: Official Python SDK and SignalR/Webhook Integration for NoBox.Ai platform
Home-page: https://gitlab.ubig.co.id/erik/nobox-chat-python
Author: NoBox.Ai Team
Author-email: support@nobox.ai
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.25.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# NoBox.Ai Chat Python SDK (`nobox-chat-sdk`)

Official Python Client SDK and Real-time Webhook Receiver Application for **NoBox.Ai** Omnichannel Platform Integration.

🔗 **GitLab Repository**: [https://gitlab.ubig.co.id/erik/nobox-chat-python](https://gitlab.ubig.co.id/erik/nobox-chat-python)  
🌐 **Live Web Demo**: [https://nobox-chat-python.ubigdev.com/](https://nobox-chat-python.ubigdev.com/)

---

## 🐍 Preview Aplikasi Demo & Interactive Console Inspector

Package ini menyediakan solusi **Python SDK lengkap** (dukungan Python 3.7+) yang dilengkapi dengan Service REST API, Webhook HMAC-SHA256 Verifier & Parser, serta **Flask Web Application & Interactive Traffic Inspector** bawaan ([Live Web Demo](https://nobox-chat-python.ubigdev.com/)) untuk mempermudah debugging dan integrasi platform NoBox.Ai.

---

## 📦 Instalasi & Dependensi

### Opsi A: Instalasi via PyPI / Pip

```bash
pip install nobox-chat-sdk
```

Atau instalasi langsung dari Git Repository:

```bash
pip install git+https://gitlab.ubig.co.id/erik/nobox-chat-python.git
```

### Opsi B: Import Library di Kode Python

```python
from nobox_chat import NoboxChat

# Inisialisasi SDK
nb = NoboxChat(base_url="https://id.nobox.ai/", app_name="NoBoxChatPython", app_version="1.0.0")
```

---

## ✨ Fitur Utama

- 🔑 **Autentikasi Native Python**: Login ke NoBox.Ai REST API untuk memperoleh Bearer Token secara otomatis.
- 📋 **Chatrooms & Messages Manager**: Service intuitif untuk mengambil daftar percakapan, channel, akun WhatsApp terhubung, serta riwayat pesan.
- 📤 **Fast Message Dispatcher & Media Upload**: Mengirim pesan teks dan konversi attachment base64 ke URL media secara langsung.
- 🔐 **Webhook HMAC-SHA256 Verifier & Event Parser**: Verifikasi keamanan signature `X-Nobox-Signature-256` dan parsing event payload otomatis (`TerimaPesan`, `TerimaAck`, `TerimaRead`).
- 📊 **AppInfo & Metadata Tracking**: Melacak header metadata `X-App-Name: NoBoxChatPython` dan `X-App-Version: 1.0.0` pada setiap request API.

---

## 📂 Struktur Repositori

```text
nobox-chat-python/
├── setup.py                      # Konfigurasi PyPI Package Installer
├── requirements.txt              # Dependensi Python (requests, flask)
├── README.md                     # Dokumentasi Resmi Python SDK
├── nobox_chat.py                # Core Python SDK Library (`NoboxChat`)
├── app.py                        # Flask Web Application & Webhook Receiver
├── templates/
│   └── index.html                # Frontend Web UI Demo
└── static/                       # Custom CSS/JS Static Assets
```

---

## 📖 Panduan Penggunaan Python SDK (`NoboxChat`)

### 1. Autentikasi & Generate Token

```python
from nobox_chat import NoboxChat

nb = NoboxChat()

# Login untuk mendapatkan Bearer token
result = nb.generate_token("user@example.com", "password")

if not result["IsError"]:
    token = result["Data"]
    print("Token Berhasil Didapatkan:", token)
else:
    print("Gagal Login:", result["Error"])
```

---

### 2. Mengambil Daftar Percakapan & Riwayat Chat

```python
# 1. Ambil 20 Percakapan Teratas
chatrooms = nb.fetch_chatrooms(take=20)
print("Daftar Chatroom:", chatrooms["Data"])

# 2. Ambil Riwayat Pesan berdasarkan Room ID
messages = nb.fetch_messages(room_id="ROOM_ID_123", take=50)
print("Riwayat Pesan:", messages["Data"])
```

---

### 3. Tipe Pesan (`body_type`)

| Kode | Tipe Pesan | Deskripsi / Format Payload |
| :---: | :--- | :--- |
| `1` | **Text** | Pesan teks biasa (`text` / `body`) |
| `2` | **Audio** | File suara / rekaman audio |
| `3` | **Image** | File gambar (JPEG, PNG, WebP) |
| `4` | **Video** | File video (MP4) |
| `5` | **File / Document** | File dokumen (PDF, DOCX, ZIP, dll) |
| `6` | **Sticker** | File stiker animasi / WebP |
| `7` | **Location** | Koordinat lokasi geografis |
| `8` | **Contact** | Kartu kontak VCard |

---

### 4. ✉️ Mengirim Pesan Teks via REST API

```python
from nobox_chat import NoboxChat

nb = NoboxChat(token="TOKEN_BEARER_ANDA")

# Kirim pesan teks (body_type: 1)
send_res = nb.send_message(
    ext_id="628123456789",      # ID Eksternal / Nomor WhatsApp penerima
    channel_id=1,               # ID Channel
    account_id="744927678136325", # ID Akun Pengirim
    text="Halo dari Python SDK NoBox.Ai!",
    body_type=1
)
print("Hasil Kirim Teks:", send_res)
```

---

### 5. 🖼️ Mengirim Pesan Media & Attachment via REST API (Gambar, Video, Dokumen/File)

Pengiriman pesan media selain teks biasa memerlukan **2 langkah**:
1. Upload file (Base64) ke server NoBox.Ai menggunakan `upload_base64_to_file()` untuk memperoleh metadata file (`Filename` & `OriginalName`).
2. Kirim pesan media dengan kode `body_type` yang sesuai (misal `3` Gambar, `4` Video, `5` Dokumen) dan kirimkan JSON array metadata attachment.

```python
import base64
import json
from nobox_chat import NoboxChat

nb = NoboxChat(token="TOKEN_BEARER_ANDA")

# 1. Convert file lokal ke Base64 Data String
with open("dokumen.pdf", "rb") as f:
    b64_str = base64.b64encode(f.read()).decode("utf-8")

# 2. Upload file ke server NoBox.Ai
upload_res = nb.upload_base64_to_file({
    "media": {
        "filename": "dokumen.pdf",
        "mimetype": "application/pdf",
        "data": b64_str
    }
})

if not upload_res.get("IsError") and upload_res.get("Data"):
    uploaded_file = upload_res["Data"] # {"Filename": "xyz.pdf", "OriginalName": "dokumen.pdf"}

    # 3. Kirim Pesan Dokumen (body_type: 5)
    send_res = nb.send_message(
        ext_id="628123456789",
        channel_id=1,
        account_id="744927678136325",
        text="", # Text dapat dikosongkan untuk file
        body_type=5, # 5 = File / Document (3 = Image, 4 = Video)
        attachment=json.dumps([uploaded_file]) # Array JSON String
    )
    print("Hasil Kirim Media:", send_res)
```

---

### 6. 📡 Integrasi Real-time WebSocket SignalR

Untuk menerima & mengirim pesan secara real-time via WebSocket SignalR di Web Browser / Client App:

```html
<script src="/static/signalr.min.js"></script>
<script>
const connection = new signalR.HubConnectionBuilder()
    .withUrl("https://id.nobox.ai/messagehub?app_name=NoBoxChatPython&app_ver=1.0.0", {
        accessTokenFactory: () => "TOKEN_BEARER_ANDA",
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
    })
    .withAutomaticReconnect()
    .build();

// 1. Listener Pesan Baru Diterima Real-Time
connection.on("TerimaPesan", (room, msgObj) => {
    console.log("Pesan Baru Diterima di Room:", room, msgObj);
});

// 2. Listener Status ACK (Sent / Delivered / Read)
connection.on("TerimaAck", (roomId, msgId, status) => {
    console.log(`Status Pesan #${msgId} di Room ${roomId}: ${status}`);
});

async function startRealtime() {
    await connection.start();
    
    // 3. Join Room Percakapan
    const roomId = 123456789;
    const accountId = 744927678136325;
    await connection.invoke("JoinConversation", String(roomId), "");

    // a) Kirim Pesan Teks Real-time via WebSocket
    await connection.invoke("KirimPesan", JSON.stringify({
        Room: { IdAccount: accountId, IdRoom: roomId },
        Msg: { Type: "1", Msg: "Halo via SignalR WebSocket!" }
    }));

    // b) Kirim Pesan Media (Gambar/File) Real-time via WebSocket
    const fileObj = { Filename: "xyz.jpg", OriginalName: "foto.jpg" };
    await connection.invoke("KirimPesan", JSON.stringify({
        Room: { IdAccount: accountId, IdRoom: roomId },
        Msg: { Type: "3", Msg: "", File: JSON.stringify(fileObj) } // Type "3" = Image
    }));
}
startRealtime();
</script>
```

---

### 7. 🔒 Webhook Verification & Event Handler

```python
from nobox_chat import NoboxChat

# Verifikasi & Parse Payload Webhook HMAC-SHA256
try:
    event_data = NoboxChat.handle_webhook(
        payload_body=raw_json_body,
        signature_header=request_headers.get("X-Nobox-Signature-256"),
        webhook_secret="YOUR_WEBHOOK_SECRET",
        throw_error=True
    )
    print("Webhook Valid! Event:", event_data)
except ValueError as e:
    print("Webhook Invalid:", str(e))
```

---

## 🌐 Menjalankan Flask Application Demo secara Lokal

Untuk menjalankan aplikasi demo Web UI & Webhook receiver lokal:

```bash
pip install -r requirements.txt
python app.py
```

Buka browser Anda di: `http://localhost:5001` atau `http://127.0.0.1:5001`.

---

## 🌐 Recommendations for Web Server (Nginx)

Untuk lingkungan produksi, sangat **direkomendasikan menggunakan Nginx** sebagai Reverse Proxy / WSGI Server (Gunicorn / uWSGI) di depan Flask:

<details>
<summary>💡 Contoh Konfigurasi Nginx Reverse Proxy (klik untuk membaca)</summary>

```nginx
server {
    listen 80;
    server_name domain-anda.com;

    location / {
        proxy_pass http://127.0.0.1:5001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

</details>

---

## 🛡️ Catatan Keamanan & Best Practices

- 🔒 **Manajemen Token & Kredensial**: Jangan pernah menyimpan Token Autentikasi / API Key secara hardcoded di dalam kode publik. Gunakan Environment Variable (`os.getenv("NOBOX_TOKEN")`) atau backend proxy.
- 🛡️ **Verifikasi Webhook**: Selalu gunakan `NoboxChat.handle_webhook()` untuk memverifikasi signature `X-Nobox-Signature-256` pada setiap request webhook masuk guna mencegah serangan tampering dan replay.
- 📡 **Enkripsi SSL/TLS**: Wajib menggunakan protokol aman (`https://` untuk REST API dan `wss://` untuk SignalR WebSocket) di lingkungan produksi.

---

## 📄 Lisensi

Proyek ini dirilis di bawah lisensi **MIT License**.
