90 lines
3.7 KiB
Markdown
90 lines
3.7 KiB
Markdown
|
|
# Permintaan Integrasi Webhook — Collection Broadcast
|
||
|
|
|
||
|
|
**Ke:** Tim Omnix
|
||
|
|
**Dari:** Tim Collection Broadcast (Gadai Mulia)
|
||
|
|
**Tujuan:** Kami butuh notifikasi real-time saat status pengiriman WhatsApp
|
||
|
|
(sent/delivered/read/failed) berubah, supaya tidak perlu polling
|
||
|
|
`GET /api/client/collar/add-recipient/{id}/detail` berulang-ulang ke sistem
|
||
|
|
Omnix untuk setiap recipient.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. Yang kami minta dari tim Omnix
|
||
|
|
|
||
|
|
1. **Konfirmasi ketersediaan fitur** — apakah Omnix/Sopiga sudah punya (atau bisa
|
||
|
|
dibuatkan) mekanisme outgoing webhook saat status recipient di collar berubah?
|
||
|
|
(Kami cek dokumentasi publik di `/docs?api-docs.yaml` dan tidak menemukan
|
||
|
|
endpoint registrasi webhook untuk collar/recipient — hanya ada `webhook_url`
|
||
|
|
di level `WhatsAppSession`, yang tampaknya untuk keperluan lain.)
|
||
|
|
2. **Endpoint/cara registrasi** URL callback kami ke sistem Omnix (dashboard,
|
||
|
|
API, atau config manual).
|
||
|
|
3. **Shared secret** untuk signing payload (lihat §3) — dikirim lewat kanal aman
|
||
|
|
(bukan email biasa), atau kalau Omnix punya skema signature sendiri (mis. HMAC
|
||
|
|
dengan public key, atau format berbeda), kasih tahu kami spesifikasinya —
|
||
|
|
kami sesuaikan.
|
||
|
|
4. **Kapan callback dikirim** — idealnya setiap kali status berubah
|
||
|
|
(`sent` → `delivered` → `read`, atau → `failed`), bukan cuma sekali di akhir.
|
||
|
|
5. **Retry policy di sisi Omnix** — kalau endpoint kami down/timeout, apakah
|
||
|
|
Omnix retry otomatis? Berapa kali, dengan interval berapa?
|
||
|
|
|
||
|
|
## 2. Endpoint & secret yang kami berikan ke Omnix
|
||
|
|
|
||
|
|
```
|
||
|
|
URL : https://<DOMAIN_PUBLIK_KAMI>/webhooks/sopiga/delivery-status
|
||
|
|
Method: POST
|
||
|
|
Secret: (kirim terpisah lewat kanal aman — JANGAN taruh di email/chat biasa,
|
||
|
|
JANGAN commit ke dokumen/repo ini)
|
||
|
|
```
|
||
|
|
|
||
|
|
> ⚠️ URL di atas masih placeholder — isi dengan domain publik/staging service
|
||
|
|
> `omnix-broadcast` kami sebelum dikirim ke tim Omnix. Saat ini service jalan
|
||
|
|
> lokal di `localhost:8081`, belum bisa diakses dari luar.
|
||
|
|
|
||
|
|
> 🔒 **Secret key** sudah kami generate (64 karakter hex, random 256-bit) dan
|
||
|
|
> tersimpan di `.env` service kami (`WEBHOOK_SECRET`). Kirim nilainya ke PIC
|
||
|
|
> Omnix lewat kanal aman (password manager, secret vault, atau chat terenkripsi
|
||
|
|
> — bukan email/Slack polos). Mereka pakai secret yang SAMA persis untuk
|
||
|
|
> menandatangani tiap request ke kami.
|
||
|
|
|
||
|
|
## 3. Format payload — **dikonfirmasi tim Omnix** ✅
|
||
|
|
|
||
|
|
**Header:**
|
||
|
|
```
|
||
|
|
X-Sopiga-Signature: <hex HMAC-SHA256 dari raw body, pakai secret di atas>
|
||
|
|
```
|
||
|
|
|
||
|
|
**Body:**
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"recipient_detail_id": 1234,
|
||
|
|
"status": "sent",
|
||
|
|
"gateway": "628124878787"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
| Field | Tipe | Keterangan |
|
||
|
|
|---|---|---|
|
||
|
|
| `recipient_detail_id` | integer | Sama dengan `recipient_detail_id` yang dikembalikan saat `add-recipient` |
|
||
|
|
| `status` | string | Salah satu: `pending`, `sent`, `delivered`, `read`, `failed` (atau `undelivered`) |
|
||
|
|
| `gateway` | string | Nomor WhatsApp pengirim (sender) |
|
||
|
|
|
||
|
|
Sudah diuji end-to-end di sisi kami dengan payload persis seperti di atas —
|
||
|
|
`status: "sent"` diabaikan (belum final), `status: "delivered"`/`"read"` update
|
||
|
|
record jadi `delivered`, `status: "failed"`/`"undelivered"` update jadi `failed`.
|
||
|
|
|
||
|
|
> Masih perlu dikonfirmasi: apakah header `X-Sopiga-Signature` (HMAC-SHA256)
|
||
|
|
> di atas juga dipakai Omnix, atau ada skema signature/auth lain di sisi mereka?
|
||
|
|
|
||
|
|
## 4. Response yang kami kirim balik
|
||
|
|
|
||
|
|
- `200 OK` — payload diterima & diproses.
|
||
|
|
- `400 Bad Request` — payload tidak valid/tidak bisa diparse.
|
||
|
|
- `401 Unauthorized` — signature tidak cocok.
|
||
|
|
- `500 Internal Server Error` — gagal proses di sisi kami (mohon di-retry).
|
||
|
|
|
||
|
|
## 5. Fallback
|
||
|
|
|
||
|
|
Selama callback belum aktif/terverifikasi, kami tetap jalankan polling manual
|
||
|
|
ke `GET /api/client/collar/add-recipient/{id}/detail` sebagai cadangan, jadi
|
||
|
|
tidak ada risiko data hilang selama masa transisi.
|