# Integrasi WhatsApp


Panduan ini menjelaskan cara menghubungkan nomor WhatsApp Business melalui **Meta WhatsApp Cloud API** ke OmniStream menggunakan alur manual. Setelah selesai, pesan masuk ke nomor tersebut akan muncul di inbox OmniStream, dan balasan keluar akan dikirim kembali melalui Cloud API.

> **Peran:** Hanya **Admin** yang dapat membuka halaman Integrations.
> **Rute frontend:** `/integrations`

## Prasyarat

1. **Meta App** di [developers.facebook.com](https://developers.facebook.com/) dengan produk **WhatsApp** aktif.
2. **WhatsApp Business Account (WABA)** yang terhubung ke Meta App.
3. **Nomor telepon** yang telah ditambahkan ke WABA dan memiliki `phone_number_id`.
4. **Permanent access token** dengan izin `whatsapp_business_messaging` dan `whatsapp_business_management`.
5. Akses ke server OmniStream Anda pada URL publik (misalnya `https://omnistream.example.com`) agar Meta dapat memanggil webhook.

## Kredensial yang dibutuhkan

Nilai berikut diperlukan untuk menghubungkan WhatsApp. Masukkan di UI Integrations atau konfigurasikan pada server oleh administrator:

| Kredensial | Asal |
|---|---|
| **Meta App Secret** | Meta App Dashboard → Settings → Basic — untuk verifikasi tanda tangan webhook |
| **Meta Verify Token** | Nilai bebas yang Anda tentukan — untuk handshake verifikasi webhook Meta |
| **Meta Access Token** | Meta App Dashboard → WhatsApp → API Setup |
| **Meta Phone Number ID** | Meta App Dashboard → WhatsApp → API Setup |

## Langkah-langkah

### 1. Dapatkan kredensial Meta

1. Masuk ke [developers.facebook.com](https://developers.facebook.com/apps).
2. Pilih app Anda, lalu buka **App Settings → Basic**.
3. Salin **App Secret**; berikan ke administrator server untuk dikonfigurasi.
4. Buka **WhatsApp → API Setup** dan salin:
   - **Temporary access token** (untuk uji coba) atau buat **System User** untuk permanent token.
   - **Phone number ID** dari nomor yang akan dipakai.
5. Tentukan **Verify Token** sendiri — nilai bebas yang Anda tentukan, harus cocok antara konfigurasi OmniStream dan Meta App Dashboard.

### 2. Konfigurasikan kredensial

Masukkan nilai yang didapat dari Meta ke UI Integrations → tab **WhatsApp**, atau minta administrator server untuk mengisi konfigurasi. Perubahan via UI Integrations aktif dalam 30 detik (hot-reload otomatis).

### 3. Konfigurasi webhook di Meta App Dashboard

1. Di Meta App → **WhatsApp → Configuration → Webhook**, klik **Edit**.
2. Masukkan **Callback URL**: `https://<host-omnistream>/webhook/whatsapp`
   - Di development lokal, Anda memerlukan tunnel publik (misalnya ngrok) agar Meta dapat menjangkau server Anda.
3. Masukkan **Verify Token**: nilai yang sama dengan yang dikonfigurasi di OmniStream.
4. Klik **Verify and Save**. Meta akan mengirim `GET /webhook/whatsapp` dengan `hub.mode=subscribe`; OmniStream akan membalas `hub.challenge` jika token cocok.
5. Pada bagian **Webhook fields**, langganan ke event `messages`.

### 4. Tambahkan integrasi di UI OmniStream

1. Masuk sebagai admin dan buka **Integrations** (`/integrations`).
2. Klik **+ Add Integration**, pilih channel **WhatsApp**.
3. Masukkan `phone_number_id`, `access_token`, dan setelan opsional lain (misalnya `division_id` jika memakai divisi).
4. Klik **Save**. Baris baru muncul pada tabel `integrations` dengan `is_active = true`.
5. Tunggu sampai 30 detik agar konfigurasi aktif (hot-reload otomatis).

### 5. Kirim pesan uji

1. Dari perangkat lain, kirim pesan WhatsApp ke nomor yang baru saja dikonfigurasi.
2. Buka **Inbox** di OmniStream; percakapan baru akan muncul dalam beberapa detik.
3. Balas dari Inbox. Pesan akan dikirim kembali melalui Graph API menggunakan `META_ACCESS_TOKEN`.
4. Jika pesan uji tidak muncul, periksa bahwa **Meta App Secret** di konfigurasi OmniStream cocok dengan yang ada di Meta App Dashboard — ini adalah penyebab paling umum kegagalan.

## Cek kesehatan akun

Setiap nomor WhatsApp yang terhubung punya tombol **Kesehatan akun** (ikon denyut jantung) pada baris akun di **Channels → WhatsApp**. Dialognya menarik status terkini langsung dari Meta:

| Baris | Arti |
| --- | --- |
| **Rating kualitas** | Penilaian Meta atas kualitas pesan Anda: Tinggi (Hijau), Sedang (Kuning), atau Rendah (Merah). Kuning/merah muncul saat pelanggan memblokir atau melaporkan nomor Anda. |
| **Batas pesan** | Jumlah percakapan berbayar yang boleh Anda mulai per 24 jam (50, 250, 1.000, 10.000, 100.000, atau tidak terbatas). |
| **Throughput** | Kecepatan pengiriman yang diizinkan Meta untuk nomor ini: Standar atau Tinggi. |
| **Status operasional** | Status koneksi nomor pada Cloud API. `CONNECTED` berarti siap kirim-terima. |
| **Status nama tampilan** | Status peninjauan nama bisnis. `NON_EXISTS` adalah kondisi normal bila Anda belum pernah mengajukan perubahan nama. |

Bila Meta melaporkan nomor tidak bisa mengirim — misalnya akun bisnis dibatasi — dialog menampilkan banner berisi alasan dan saran perbaikan dari Meta di atas tabel.

Data diambil langsung dari Meta setiap kali dialog dibuka; tombol **Segarkan** mengambil ulang, dan baris **Terakhir dicek** menunjukkan waktu pengambilan terakhir. Fitur ini butuh izin `integrations.view`.

:::tip
Rating kualitas turun ke Kuning atau Merah sebelum Meta menurunkan batas pesan Anda. Perlakukan Kuning sebagai peringatan dini: kurangi volume pesan keluar dan perbaiki relevansi isi pesan sebelum batas ikut turun.
:::

## Multi-tenant dan atribusi akun

OmniStream menangani payload WhatsApp multi-akun dengan benar: satu request dari Meta yang berisi pesan untuk beberapa nomor akan diproses secara terpisah berdasarkan `phone_number_id`, tanpa ada pesan yang bocor ke akun lain.

## Troubleshooting

- **Webhook verification gagal (`HTTP 401`)** — periksa bahwa **Meta Verify Token** di konfigurasi OmniStream identik dengan yang dimasukkan di Meta App Dashboard.
- **Semua payload masuk ditolak `InvalidSignature`** — **Meta App Secret** tidak cocok. Hubungi administrator untuk memperbarui konfigurasi server.
- **Pesan keluar ditolak `(#190) Invalid OAuth access token`** — **Meta Access Token** kedaluwarsa. Buat token permanen lewat System User, lalu perbarui lewat UI Integrations.
- **Nomor tidak dikenali** — pastikan **Phone Number ID** pada integrasi sesuai dengan nomor yang ada di Meta App Dashboard.

## WhatsApp Embedded Signup

:::warning
**Ditangguhkan di v1**

OmniStream memiliki draf awal untuk alur **WhatsApp Embedded Signup** yang memungkinkan admin mendaftarkan nomor tanpa keluar aplikasi (commit `6f5f4dd`). Namun dokumentasi dan hardening lengkap belum termasuk di v1. Untuk v1, gunakan alur manual pada halaman ini.

Detail deferral dan jadwal v1.1 tercatat pada `docs-site/SCOPE.md` Bagian 2.1 baris 4 dan 4 (Backend follow-up BE4). Jangan mengandalkan alur Embedded Signup sampai banner ini dihapus.
:::

## Hubungan dengan API Reference

Endpoint REST untuk mengelola integrasi WhatsApp tersedia di bawah tag **Integrations** pada [API Reference](/api), termasuk `PUT /api/integrations/whatsapp` untuk upsert dan `GET /api/integrations/whatsapp` untuk inspeksi (config di-mask).
