Skip to content

Webhooks

Webhook mengirim event Volara ke endpoint HTTPS Anda secara real-time, sehingga Anda tidak perlu polling. Gunakan webhook untuk bereaksi atas pesan masuk, perubahan status, percakapan baru, dan event lainnya.

Cara kerja

  1. Daftarkan URL endpoint HTTPS Anda (di dashboard atau via API).
  2. Volara mengirim POST JSON ke URL itu setiap kali event terjadi.
  3. Endpoint Anda memverifikasi tanda tangan, lalu membalas 2xx secepatnya.
  4. Jika endpoint gagal/timeout, Volara mengulang dengan backoff.

Contoh payload

json
{
  "id": "evt_01HZ...",
  "type": "message.received",
  "createdAt": "2026-06-23T08:12:00.000Z",
  "data": {
    "channelId": "ch_123",
    "conversationId": "conv_456",
    "message": {
      "id": "msg_789",
      "from": "6281234567890",
      "type": "text",
      "text": "Halo, saya mau tanya produk"
    }
  }
}

Contoh tipe event: message.received, message.status, conversation.created, conversation.assigned, ticket.updated. Katalog event lengkap dan bentuk payload persisnya ada di Referensi API interaktif.

Verifikasi tanda tangan (HMAC-SHA256)

Setiap permintaan webhook menyertakan header tanda tangan yang dihitung sebagai HMAC-SHA256 dari raw body menggunakan signing secret webhook Anda. Wajib verifikasi sebelum memproses, dan gunakan body mentah (jangan body yang sudah di-parse ulang).

ts
import crypto from 'node:crypto'

// Pastikan dapat membaca raw body, mis. express.raw({ type: 'application/json' })
app.post('/webhooks/volara', (req, res) => {
  const signature = req.header('X-Volara-Signature') || ''
  const secret = process.env.VOLARA_WEBHOOK_SECRET!

  const expected = crypto
    .createHmac('sha256', secret)
    .update(req.body) // Buffer mentah
    .digest('hex')

  const ok =
    signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))

  if (!ok) return res.status(401).send('invalid signature')

  const event = JSON.parse(req.body.toString('utf8'))
  // ... proses event (idempotent), lalu:
  res.sendStatus(200)
})
python
import hmac, hashlib, os
from flask import Flask, request, abort

app = Flask(__name__)

@app.post("/webhooks/volara")
def volara_webhook():
    signature = request.headers.get("X-Volara-Signature", "")
    secret = os.environ["VOLARA_WEBHOOK_SECRET"].encode()
    expected = hmac.new(secret, request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(signature, expected):
        abort(401)
    event = request.get_json()
    # ... proses event (idempotent)
    return "", 200

Gunakan perbandingan konstan-waktu

Bandingkan tanda tangan dengan timingSafeEqual / hmac.compare_digest, bukan ==, untuk mencegah timing attack. Verifikasi memakai raw body, bukan JSON yang diserialisasi ulang (urutan field/spasi bisa berubah).

Nama header

Nama header tanda tangan (mis. X-Volara-Signature) dan secret-nya tampil saat Anda membuat webhook di dashboard. Selalu konfirmasi di Referensi API interaktif.

Retry & idempotency

  • Retry/backoff — jika endpoint tidak membalas 2xx (atau timeout), Volara mengulang pengiriman dengan jeda yang membesar.
  • Idempotency — event yang sama bisa terkirim lebih dari sekali. Simpan event.id yang sudah diproses dan abaikan duplikat.
  • Balas cepat — kembalikan 2xx segera, lalu proses berat di background agar tidak timeout dan memicu retry.

Langkah selanjutnya