Skip to content

SDK TypeScript / JavaScript

@volara/sdk adalah klien resmi TypeScript/JavaScript untuk Volara. Klien kecil, typed, tanpa dependensi, dan berjalan di mana pun fetch tersedia: Node 18+, browser, dan Cloudflare Workers / edge.

Kode sumber: github.com/volara-asia.

Install

bash
npm install @volara/sdk
# atau
pnpm add @volara/sdk
# atau
bun add @volara/sdk

Autentikasi

Buat API key di dashboard Volara (Settings → API Keys). Kunci membawa tenant dan scope Anda, jadi SDK cukup mengirimkannya di setiap permintaan.

ts
import { Volara } from '@volara/sdk'

// Set kunci lewat constructor...
const volara = new Volara({ apiKey: 'sk_live_xxx' })

// ...atau set env VOLARA_API_KEY dan biarkan SDK membacanya.
const volara2 = new Volara()

Self-host atau pakai endpoint regional? Override base URL:

ts
const volara = new Volara({ apiKey: '...', baseUrl: 'https://api.volara.chat' })

Jaga kerahasiaan API key

API key memberi akses penuh ke data tenant. Jangan menaruhnya di bundel klien atau repo publik — pakai hanya dari server.

Quickstart — kirim pesan pertama

ts
import { Volara } from '@volara/sdk'

const volara = new Volara({ apiKey: process.env.VOLARA_API_KEY })
await volara.messages.send({ conversationId: 'conv_123', text: 'Halo 👋' })

Contoh resource

Conversations

ts
const { data, total } = await volara.conversations.list({ status: 'open', perPage: 20 })
const conversation = await volara.conversations.get('conv_123')

// Auto-paging — iterasi semua percakapan tanpa mengelola nomor halaman.
for await (const c of volara.conversations.iterate({ status: 'open' })) {
  console.log(c.id, c.status)
}

Messages

ts
await volara.messages.send({ conversationId: 'conv_123', text: 'Pesanan kamu sudah dikirim.' })

// Payload lebih kaya (template, media) diteruskan sesuai dokumentasi API.
await volara.messages.send({
  conversationId: 'conv_123',
  type: 'template',
  content: { name: 'order_update', language: 'id', variables: ['#A123'] },
})

Contacts (CRM)

ts
const { data } = await volara.contacts.list({ q: 'budi', perPage: 50 })
const contact = await volara.contacts.create({
  name: 'Budi Santoso',
  phoneNumber: '+6281234567890',
  email: 'budi@example.com',
})

Broadcasts

ts
const broadcast = await volara.broadcasts.create({
  title: 'Promo Lebaran',
  messageContent: 'Diskon 30% minggu ini!',
})

Knowledge base & metrics

ts
const sources = await volara.knowledge.search('refund policy')
const faqs = await volara.knowledge.search('cara melacak pesanan', { scope: 'faqs' })
const dashboard = await volara.metrics.dashboard()

Escape hatch

Butuh endpoint yang belum dimodelkan? Panggil langsung di bawah /api/v1:

ts
const tickets = await volara.request('/tickets', { query: { status: 'open' } })

Verifikasi webhook

Verifikasi webhook masuk dengan HMAC-SHA256. Helper memakai Web Crypto, jadi jalan di Node, browser, dan Workers — dengan perbandingan constant-time.

ts
import { verifyWebhook } from '@volara/sdk/webhooks'

// Baca body MENTAH dan verifikasi SEBELUM parse — re-serialize mengubah byte-nya.
const raw = await request.text()
const ok = await verifyWebhook({
  payload: raw,
  signature: request.headers.get('x-volara-signature') ?? '',
  secret: process.env.VOLARA_WEBHOOK_SECRET,
})
if (!ok) return new Response('invalid signature', { status: 401 })

const event = JSON.parse(raw)
if (event.type === 'message.received') {
  // ...
}

Error handling

Setiap respons non-2xx, timeout, dan kegagalan jaringan melempar VolaraError. Selalu catat requestId agar support Volara bisa menelusuri panggilan yang tepat.

ts
import { Volara, VolaraError } from '@volara/sdk'

try {
  await volara.conversations.get('missing')
} catch (err) {
  if (err instanceof VolaraError) {
    console.error(err.status)    // mis. 404
    console.error(err.code)      // mis. "VLR-..." (saat API mengirimnya)
    console.error(err.requestId) // sertakan ini di tiket support
    console.error(err.message)
  }
}

VolaraTimeoutError dan VolaraConnectionError adalah subclass dari VolaraError, jadi satu catch (err instanceof VolaraError) sudah mencakup semuanya.

Resilience

  • Retry pada 429/5xx (dan gangguan jaringan) dengan exponential backoff + jitter, menghormati header Retry-After. Atur dengan maxRetries (default 2).
  • Timeout lewat AbortSignal.timeout. Atur dengan timeoutMs (default 30000).
  • Idempotency key otomatis menempel di setiap operasi tulis (POST/PUT/PATCH/DELETE) agar retry tidak menggandakan data.
ts
const volara = new Volara({ apiKey: '...', timeoutMs: 10_000, maxRetries: 4 })

Langkah selanjutnya