Penjelasan Konfigurasi Callback
Bagian ini menjelaskan cara mengonfigurasi alamat callback EngageLab OTP, serta mekanisme validasi keamanan terkait, untuk memastikan keandalan dan keamanan data callback.
Konfigurasi dan validasi alamat callback
Setelah alamat callback dikonfigurasi, EngageLab OTP akan secara otomatis mengirim satu request HTTP POST ke alamat tersebut untuk memvalidasi ketersediaan endpoint. Layanan Anda harus mengembalikan status code HTTP 200 dalam waktu 3 detik, jika tidak, sistem akan menganggap alamat tersebut tidak tersedia.
Catatan:
Untuk memastikan data callback dapat diterima dengan normal, harap tambahkan 119.8.170.74 dan 114.119.180.30 ke whitelist firewall server Anda.
Contoh request
Misalkan alamat callback Anda adalah https://example.engagelabotp.callback.com, sistem akan mengirim request seperti berikut:
curl -X POST https://example.engagelabotp.callback.com -d '{}'
Persyaratan respons
Layanan Anda hanya perlu mengembalikan status code HTTP 200, tanpa perlu mengembalikan konten apa pun. Contoh:
HTTP/1.1 200 OK
Content-Length: 0
Catatan:
Validasi alamat callback hanya memeriksa status code HTTP, dan tidak mengharuskan pengembalian konten payload tertentu. Pastikan endpoint layanan Anda dapat merespons 200 dengan benar dalam waktu 3 detik.
Mekanisme keamanan callback
Untuk menjamin keamanan data callback dan keterpercayaan sumbernya, EngageLab OTP mendukung berbagai metode validasi keamanan.
Validasi username dan secret key (opsional)
- Konfigurasi opsional. Jika username diatur, secret key juga harus diatur.
- Setelah dikonfigurasi, EngageLab akan menambahkan field
X-CALLBACK-IDpada HTTP Header setiap request callback, dengan format sebagai berikut:
X-CALLBACK-ID: timestamp={timestamp};nonce={nonce};username={username};signature={signature}
- Keterangan:
timestamp: timestamp saat callback dikirimnonce: angka acakusername: username yang Anda konfigurasikansignature: informasi tanda tangan, dihitung dengan cara berikut
Cara menghitung signature (contoh Python)
import hashlib, hmac
def verify(username, secret, timestamp, nonce, signature):
return signature == hmac.new(
key=secret.encode(),
msg=f'{timestamp}{nonce}{username}'.encode(),
digestmod=hashlib.sha256
).hexdigest()
- Server dapat menggunakan cara di atas untuk memvalidasi keabsahan request callback.
Autentikasi Authorization (opsional)
- Jika endpoint callback Anda memerlukan autentikasi (seperti Basic Auth, Bearer Token, dll.), Anda dapat mengisi informasi Authorization saat konfigurasi.
- EngageLab akan otomatis menyertakan field Authorization tersebut saat melakukan request, sehingga memudahkan layanan Anda memvalidasi identitas request.
Penjelasan event callback
Status pesan
Status pesan digunakan untuk melacak perubahan status setiap pesan sepanjang siklus hidupnya. Berguna untuk memantau secara real-time perkembangan di setiap tahap seperti pengiriman, penerimaan, dan verifikasi pesan, sehingga memudahkan analisis statistik, penanganan anomali, dan optimasi pengalaman pengguna.
| Identifier Event | Keterangan |
|---|---|
| plan | Pesan dijadwalkan untuk dikirim, masuk ke antrean pengiriman |
| target_valid | Nomor tujuan valid |
| target_invalid | Nomor tujuan tidak valid |
| sent | Pesan berhasil dikirim |
| sent_failed | Pengiriman pesan gagal |
| delivered | Pesan terkirim ke perangkat pengguna |
| delivered_failed | Pesan telah dikirim, tetapi gagal terkirim ke perangkat pengguna |
| verified | Pengguna telah berhasil menyelesaikan verifikasi OTP |
| verified_failed | Verifikasi pengguna gagal |
| verified_timeout | Pengguna tidak menyelesaikan verifikasi dalam waktu yang ditentukan, melewati batas waktu |
Struktur data callback
Struktur lapisan luar
{
"total": 1,
"rows": [
{
// Objek ReportLifecycle
}
]
}
| Field | Tipe | Keterangan |
|---|---|---|
| total | int | Jumlah data yang disertakan dalam callback ini |
| rows | array | Array data status siklus hidup |
Objek ReportLifecycle
| Field | Tipe | Keterangan |
|---|---|---|
| message_id | string | ID unik pesan |
| to | string | Nomor penerima |
| server | string | Tipe layanan (misalnya otp) |
| channel | string | Tipe channel |
| itime | int64 | Timestamp callback (detik) |
| custom_args | object | Parameter kustom (dikembalikan jika diteruskan) |
| status | object | Objek detail status |
Objek status
| Field | Tipe | Keterangan |
|---|---|---|
| message_status | string | Status pesan saat ini (lihat tabel di bawah) |
| status_data | object | Objek data status |
| billing | object | Objek informasi penagihan (dikembalikan jika ada penagihan) |
| error_code | int | Kode error, 0 berarti tidak ada error |
| error_detail | object | Detail error (dikembalikan saat terjadi error) |
Objek status_data
| Field | Tipe | Keterangan |
|---|---|---|
| msg_time | int64 | Timestamp pembuatan pesan (detik) |
| message_id | string | ID pesan |
| current_send_channel | string | Nama channel pengiriman saat ini |
| template_key | string | Key konfigurasi template |
| business_id | string | ID bisnis |
Objek billing (dikembalikan jika ada penagihan)
| Field | Tipe | Keterangan |
|---|---|---|
| cost | float64 | Jumlah biaya |
| currency | string | Mata uang, selalu "USD" |
Umumnya hanya pesan pada tahap sent yang menyertakan informasi penagihan.
Objek error_detail (dikembalikan saat terjadi error)
| Field | Tipe | Keterangan |
|---|---|---|
| message | string | Deskripsi pesan error |
Contoh: pesan berhasil dikirim
{
"total": 1,
"rows": [
{
"message_id": "123456789",
"to": "+6598765432",
"server": "sms",
"channel": "sms",
"itime": 1701234567,
"custom_args": {
"order_id": "ORDER123",
"user_id": "USER456"
},
"status": {
"message_status": "sent",
"status_data": {
"msg_time": 1701234560,
"message_id": "123456789",
"current_send_channel": "CHANNEL_A",
"template_key": "verify_code",
"business_id": "1001"
},
"billing": {
"cost": 0.005,
"currency": "USD"
},
"error_code": 0
}
}
]
}
Contoh: pengiriman pesan gagal
{
"total": 1,
"rows": [
{
"message_id": "123456790",
"to": "+6598765433",
"server": "sms",
"channel": "sms",
"itime": 1701234568,
"status": {
"message_status": "sent_fail",
"status_data": {
"msg_time": 1701234561,
"message_id": "123456790",
"current_send_channel": "CHANNEL_B",
"template_key": "verify_code",
"business_id": "1001"
},
"error_code": 4001,
"error_detail": {
"message": "Invalid phone number"
}
}
}
]
}
Notifikasi pesan
Notifikasi pesan mengacu pada event bisnis tingkat sistem atau peringatan. Berguna untuk mengingatkan pihak bisnis agar memperhatikan informasi penting seperti status operasional layanan, saldo, dan hasil peninjauan template, sehingga dapat segera ditangani dan menjadi peringatan dini terhadap risiko.
| Identifier Event | Keterangan |
|---|---|
| insufficient_verification_rate | Tingkat verifikasi di bawah ambang batas yang ditetapkan |
| insufficient_balance | Saldo akun tidak mencukupi |
| template_audit_result | Notifikasi hasil peninjauan template |
Contoh
{
"total": 1,
"rows": [{
"server": "otp",
"itime": 1712458844,
"notification": {
"event": "insufficient_balance",
"notification_data": {
"business_id": "1744569418236633088",
"remain_balance": -0.005, // saldo saat ini;
"balance_threshold": 2 // ambang batas peringatan;
}
}
}]
}
Respons pesan
Respons pesan terutama mengacu pada event respons callback saat berinteraksi dengan pengguna atau sistem eksternal.
| Identifier Event | Keterangan |
|---|---|
| uplink_message | Konten pesan uplink yang dibalas pengguna melalui SMS dan cara lainnya |
Contoh
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1741083306,
"message_id": "0",
"business_id": "0",
"response": {
"event": "uplink_message",
"response_data": {
"message_sid": "SM1234567890",
"account_sid": "AC1234567890",
"from": "+1234567890",
"to": "+0987654321",
"body": "Hello, it's time to struggle!"
}
}
}
]
}
Event sistem
Event sistem mencakup tindakan operasional terkait akun, template, panggilan API, dan lainnya. Berguna untuk memantau, mengaudit, dan memproses secara otomatis operasi-operasi penting seperti login akun, perubahan secret key, dan panggilan API.
| Identifier Event | Keterangan |
|---|---|
| account_login | Notifikasi operasi terkait login akun |
| key_manage | Notifikasi operasi terkait perubahan dan pengelolaan secret key |
| msg_history | Notifikasi operasi terkait kueri riwayat pesan |
| template_manage | Notifikasi operasi penambahan, perubahan, dan penghapusan template |
| api_call | Notifikasi operasi terkait panggilan endpoint API |
Struktur data callback
Struktur lapisan luar
{
"total": 1,
"rows": [
{
// Objek event sistem
}
]
}
| Field | Tipe | Keterangan |
|---|---|---|
| total | int64 | Total event yang disertakan dalam callback ini |
| rows | array | Array objek event sistem |
Objek event sistem
| Field | Tipe | Keterangan |
|---|---|---|
| server | string | Selalu "otp" |
| itime | int64 | Timestamp terjadinya event (detik) |
| system_event | object | Konten event sistem |
Objek system_event
| Field | Tipe | Keterangan |
|---|---|---|
| event | string | Tipe event |
| data | object | Data event |
Objek data
| Field | Tipe | Keterangan |
|---|---|---|
| business_id | string | ID bisnis |
| org_id | string | ID organisasi |
| operator | object | Informasi operator |
Objek operator
| Field | Tipe | Keterangan |
|---|---|---|
| string | Email operator (jika ada) | |
| api_key | string | API Key (jika ada) |
| ip_address | string | IP operasi |
Struktur request
{
"total": 1,
"rows": [
{
"server": "otp",
"itime": 1694012345,
"system_event": {
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"api_key": "api-xxxx",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
}
]
}
Event login akun
| Field | Tipe | Keterangan |
|---|---|---|
| action | string | Login berhasil / login gagal / logout |
| fail_reason | string | Alasan login gagal, hanya dikembalikan saat login_failed |
Contoh
{
"event": "account_login",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"account_login": {
"action": "login_success"
}
}
}
Event manajemen template
| Field | Tipe | Keterangan |
|---|---|---|
| action | string | Membuat template / memperbarui template / menghapus template |
| template_id | string | ID template |
| template_name | string | Nama template |
Contoh
{
"event": "template_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"template_manage": {
"action": "update template",
"template_id": "tmpl-456",
"template_name": "Verification Code"
}
}
}
Event manajemen secret key
| Field | Tipe | Keterangan |
|---|---|---|
| action | string | Nilai enum:create api_key: membuat API Keyupdate api_key: memperbarui API Keydelete api_key: menghapus API Keyview api_secret: melihat API Secret |
| api_key | string | API Key |
| description | string | Deskripsi (opsional) |
Contoh
{
"event": "key_manage",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"email": "foo@example.com",
"ip_address": "1.2.3.4"
},
"key_manage": {
"action": "create",
"api_key": "apikey-789",
"description": "Secret key baru"
}
}
}
Event panggilan API
| Field | Tipe | Keterangan |
|---|---|---|
| api_path | string | Path endpoint |
| method | string | Metode HTTP |
Contoh
{
"event": "api_call",
"data": {
"business_id": "123",
"org_id": "org-abc",
"operator": {
"api_key": "apikey-789",
"ip_address": "1.2.3.4"
},
"api_call": {
"api_path": "/api/v1/messages/send",
"method": "POST"
}
}
}










