# Conversation Templates


Conversation template (template percakapan) adalah **skrip langkah-demi-langkah**
yang sudah disiapkan untuk memandu agent menjalankan alur percakapan yang
berulang — misalnya onboarding pelanggan baru, verifikasi identitas, atau
penanganan komplain standar. Berbeda dari balasan satu kali, sebuah template
berisi **beberapa langkah (steps)** yang dijalankan berurutan.

**Rute frontend:** `/conversation-templates` (halaman pengelolaan)

## Conversation Templates vs Quick Replies vs WhatsApp Templates

Ketiganya sama-sama "template", tapi peran dan penyimpanannya berbeda. Jangan
sampai tertukar:

| Aspek | Conversation Template | [Quick Reply](/panduan/agent/quick-replies) | WhatsApp Template |
|---|---|---|---|
| Tujuan | Skrip multi-langkah untuk memandu satu alur percakapan | Satu potongan teks balasan standar | Pesan resmi yang disetujui Meta untuk WhatsApp Business |
| Isi | Array `steps` (beberapa langkah) | Satu `content` teks | Body + header/footer + variabel `{{1}}`, `{{2}}` |
| Disetujui Meta? | Tidak | Tidak | **Ya** — wajib lolos review Meta |
| Penyimpanan | Tabel `conversation_templates` | Tabel `quick_replies` | Tabel `wa_templates` |
| Endpoint dasar | `/api/conversation-templates` | `/api/quick-replies` | `/api/wa-templates` |

Singkatnya:

- **Quick reply** = teks tunggal yang Anda sisipkan saat itu juga (lihat
  [Quick Replies](/panduan/agent/quick-replies)).
- **WhatsApp template** = pesan yang harus disetujui Meta, dipakai untuk
  memulai percakapan WhatsApp di luar jendela 24 jam.
- **Conversation template** = panduan internal berisi banyak langkah agar
  agent menjalankan alur yang konsisten. Tidak dikirim sebagai satu pesan
  resmi dan tidak butuh persetujuan Meta.

:::note
Conversation template bersifat **bersama satu workspace** (tidak per-agent)
dan tidak punya konsep visibility `personal`/`team`/`division` seperti quick
reply. Setiap template hanya menyimpan siapa pembuatnya (`created_by`).
:::

## Struktur sebuah template

Setiap template tersimpan di tabel PostgreSQL `conversation_templates` dengan
field berikut:

| Field | Tipe | Keterangan |
|---|---|---|
| `name` | teks | **Wajib.** Nama template (akan ditolak jika kosong). |
| `description` | teks | Opsional. Penjelasan singkat kegunaan template. |
| `category` | teks | Opsional. Pengelompokan, mis. `onboarding`, `support`. |
| `steps` | JSON array | Daftar langkah. Disimpan apa adanya sebagai JSONB. |
| `is_active` | boolean | Default `true`. Nonaktifkan tanpa menghapus. |

`steps` adalah **array JSON bebas** — backend menyimpannya tanpa memaksakan
skema langkah tertentu. Pada form pengelolaan, kolom **Steps (JSON)** diedit
langsung sebagai teks JSON.

## Membuat template

1. Buka halaman `/conversation-templates`.
2. Klik **New Template**.
3. Isi **Name** (wajib).
4. Isi **Category** bila perlu (mis. `onboarding`, `support`).
5. Isi **Description** singkat.
6. Pada kolom **Steps (JSON)**, masukkan array langkah dalam format JSON.
7. Klik **Create**.

Contoh isi kolom **Steps (JSON)**:

```json
[
  { "type": "message", "text": "Halo {{contact.first_name}}, selamat datang di OmniStream." },
  { "type": "message", "text": "Boleh saya minta nomor pesanan Anda untuk verifikasi?" },
  { "type": "message", "text": "Terima kasih, sedang saya cek sekarang." }
]
```

:::warning
Kolom **Steps (JSON)** harus berupa JSON valid. Jika teks yang Anda ketik
gagal di-parse, perubahan langkah pada form akan diabaikan secara diam-diam.
Pastikan tanda kurung dan kutip lengkap sebelum menyimpan.
:::

Permintaan yang dikirim ke API kira-kira seperti ini:

```http
POST /api/conversation-templates
Authorization: Bearer <JWT>
Content-Type: application/json

{
  "name": "Onboarding Pelanggan Baru",
  "category": "onboarding",
  "description": "Alur sambutan untuk kontak yang baru pertama kali chat",
  "steps": [
    { "type": "message", "text": "Halo {{contact.first_name}}!" }
  ],
  "is_active": true
}
```

## Variabel / placeholder

Field `steps` adalah teks bebas, jadi Anda bisa menulis placeholder di dalam
teks langkah sebagai pengingat data yang perlu diisi, misalnya
`{{contact.first_name}}` atau `{{order.id}}`.

:::warning
Berbeda dari quick reply, conversation template **tidak punya endpoint render
otomatis**. Tidak ada substitusi variabel di sisi server untuk template ini —
placeholder hanyalah teks biasa yang Anda atau agent ganti secara manual saat
mengetik di inbox. Untuk substitusi otomatis (`{{contact.name}}`,
`{{agent.name}}`, `{{org.name}}`), gunakan
[Quick Replies](/panduan/agent/quick-replies).
:::

## Kategori

`category` adalah label teks opsional untuk mengelompokkan template
(mis. `onboarding`, `support`, `billing`).

- Saat membuat/mengedit, isi kolom **Category** dengan teks bebas.
- Daftar template dapat difilter per kategori lewat parameter `category` pada
  endpoint list. Filter menggunakan **kecocokan persis** (exact match), jadi
  konsistenlah dalam penamaan (mis. selalu `support`, bukan kadang `Support`).

```http
GET /api/conversation-templates?category=onboarding
```

Anda juga dapat memfilter berdasarkan status aktif:

```http
GET /api/conversation-templates?is_active=true
```

## Mengaktifkan / menonaktifkan

Setiap template punya flag `is_active`. Menonaktifkan template (`is_active:
false`) menyembunyikannya dari penggunaan tanpa menghapus datanya — berguna
untuk skrip musiman atau yang sedang direvisi. Pada daftar, status ditampilkan
lewat ikon toggle (hijau = aktif).

## Memakai di inbox

Conversation template berfungsi sebagai **panduan alur**: agent membuka
template, lalu menjalankan langkah-langkahnya satu per satu di percakapan.
Untuk setiap langkah, ketik (atau salin) teksnya ke kotak input di
[inbox](/panduan/agent/inbox), ganti placeholder bila ada, lalu kirim.

Pola kerja khas:

1. Buka percakapan dari inbox.
2. Buka template yang relevan dari `/conversation-templates`.
3. Jalankan **Step 1** → ketik/salin teksnya, ganti placeholder, **Send**.
4. Lanjut ke step berikutnya sesuai respons pelanggan.
5. Selesaikan seluruh langkah hingga alur tuntas.

:::tip
Untuk balasan satu kalimat yang sering dipakai dan butuh penyisipan cepat
lewat `/` atau picker, gunakan [Quick Replies](/panduan/agent/quick-replies).
Conversation template lebih cocok untuk **alur bertahap** yang melibatkan
beberapa pesan berurutan.
:::

## Mengelola template (endpoint)

| Aksi | Endpoint |
|---|---|
| List template | `GET /api/conversation-templates` |
| Detail template | `GET /api/conversation-templates/{id}` |
| Buat template | `POST /api/conversation-templates` |
| Ubah template | `PATCH /api/conversation-templates/{id}` |
| Hapus template | `DELETE /api/conversation-templates/{id}` |

Skema lengkap request/response ada di [API Reference](/api).

:::note
Menghapus template bersifat permanen. Jika hanya ingin menonaktifkan
sementara, ubah `is_active` menjadi `false` alih-alih menghapus.
:::

## Praktik terbaik

- Beri **nama** yang jelas sesuai alurnya (mis. "Verifikasi Pesanan", bukan
  "Template 1").
- Kelompokkan dengan **kategori** yang konsisten agar mudah difilter.
- Tulis langkah seringkas mungkin; satu langkah = satu pesan.
- Tandai placeholder dengan format yang seragam (mis. `{{...}}`) agar agent
  ingat mana yang harus diganti manual.
- Nonaktifkan template lama lewat `is_active` daripada langsung menghapus,
  supaya riwayat tetap ada.

Baca juga: [Quick Replies](/panduan/agent/quick-replies) ·
[Inbox](/panduan/agent/inbox).
