# Otomasi Pesan & Percakapan


Halaman ini menjelaskan empat fitur otomasi yang tersedia di `/settings`: **Away Messages**, **Auto-Close Rules**, **Chat Expiration**, dan **Assignment Rules**. Keempatnya membutuhkan permission `settings.manage` (admin atau supervisor).

---

## Pesan Otomatis (Away Messages)

### Cara kerja

Away messages adalah balasan otomatis yang dikirim ke pelanggan saat mereka mengirim pesan di luar jam kerja yang dikonfigurasi. Alur kerjanya:

```
Pesan masuk (inbound)
       ↓
Sistem memeriksa jam kerja yang dikonfigurasi
       ↓
Jika di luar jam kerja → cari away_message yang cocok (channel + division)
       ↓
Dedup: skip jika sudah dikirim dalam cooldown period
       ↓
Pesan otomatis dikirim ke pelanggan
```

:::note
Jika tabel `working_hours` kosong (tidak ada jam kerja dikonfigurasi), sistem mengasumsikan selalu buka dan **tidak** mengirim away message. Pastikan jam kerja dikonfigurasi terlebih dahulu di `/settings/working-hours`.
:::

### Scoping & prioritas

Setiap away message dapat disempitkan ke kombinasi channel dan/atau divisi. Saat ada beberapa aturan aktif, sistem memilih aturan paling spesifik yang cocok.

### Kolom konfigurasi

| Field | Wajib | Keterangan |
|---|---|---|
| **Message** | Ya | Teks balasan otomatis. Tidak boleh kosong atau hanya spasi. |
| **Channel** | Tidak | Scope ke satu channel: `whatsapp`, `instagram`, `email`, `messenger`. Kosong = semua channel. |
| **Division** | Tidak | Scope ke satu divisi. Kosong = semua divisi (global). |
| **Cooldown (hours)** | Ya | Interval minimum sebelum pesan yang sama dikirim ulang ke kontak yang sama. Rentang: **1–168 jam** (1 jam – 7 hari). Default: 24 jam. |
| **Active** | Ya | Toggle aktif/nonaktif. Default: aktif. |

:::tip
Atur cooldown lebih panjang (mis. 48 jam) untuk menghindari spam jika pelanggan mengirim banyak pesan di luar jam kerja dalam satu sesi.
:::

### Endpoint (tag **Away Messages**)

| Aksi | Endpoint |
|---|---|
| List | `GET /api/away-messages` |
| Buat | `POST /api/away-messages` |
| Update | `PATCH /api/away-messages/{id}` |
| Hapus | `DELETE /api/away-messages/{id}` |

Contoh payload buat:

```json
{
  "message": "Terima kasih sudah menghubungi kami. Kami sedang di luar jam kerja dan akan membalas secepatnya.",
  "channel": "whatsapp",
  "division_id": null,
  "is_active": true,
  "cooldown_hours": 24
}
```

---

## Aturan Tutup Otomatis (Auto-Close Rules)

### Cara kerja

Auto-close rules mendefinisikan berapa jam sebuah percakapan boleh idle sebelum status-nya diubah otomatis ke `resolved` atau `closed`.

:::warning
**Catatan implementasi saat ini:** Tabel `conversation_auto_close_rules` tersimpan di database, tetapi belum ada background processor yang mengeksekusi aturan ini secara berkala. Rules dapat dibuat dan disimpan lewat UI maupun API, namun belum aktif dijalankan oleh scheduler. Pantau rilis berikutnya untuk update.
:::

### Kolom konfigurasi

| Field | Wajib | Keterangan |
|---|---|---|
| **Name** | Ya | Nama deskriptif aturan, tidak boleh kosong. |
| **Channel** | Tidak | Filter ke satu channel. Kosong = semua channel. |
| **Idle Hours** | Ya | Jam idle sebelum aturan aktif. Minimal: **1 jam**. Default: 24 jam. |
| **Target Status** | Ya | Status tujuan saat aturan terpicu: `resolved` atau `closed`. Default: `resolved`. |
| **Active** | Ya | Toggle aktif/nonaktif. |

### Endpoint (tag **Auto-Close Rules**)

| Aksi | Endpoint |
|---|---|
| List | `GET /api/auto-close-rules` |
| Buat | `POST /api/auto-close-rules` |
| Update | `PATCH /api/auto-close-rules/{id}` |
| Hapus | `DELETE /api/auto-close-rules/{id}` |

Contoh payload:

```json
{
  "name": "Tutup WhatsApp setelah 48 jam",
  "channel": "whatsapp",
  "idle_hours": 48,
  "target_status": "resolved",
  "is_active": true
}
```

---

## Kedaluwarsa Chat (Chat Expiration)

### Cara kerja

Chat expiration mengonfigurasi batas waktu idle untuk percakapan Email. Sistem memeriksa aturan ini secara berkala dan menjalankan tindakan yang dikonfigurasi.

:::note
**Hanya channel Email** yang dapat dikonfigurasi di halaman ini. WhatsApp, Instagram, dan Messenger menggunakan jendela pesan yang diberlakukan oleh Meta (misalnya jendela layanan pelanggan 24 jam untuk WhatsApp) — batas waktu platform tersebut tidak dapat diubah dari OmniStream.
:::

### Kolom konfigurasi

| Field | Keterangan |
|---|---|
| **Idle Timeout (window_hours)** | Jam tidak aktif sebelum aturan terpicu. **0 = tidak pernah kedaluwarsa**. Nilai >= 0. |
| **Auto-resolve** | Jika aktif, percakapan otomatis berubah ke status `resolved` saat window habis. |
| **Block outbound text** | Jika aktif, agen tidak dapat mengirim pesan teks bebas setelah window tutup. |
| **Active** | Toggle aktif/nonaktif. Menonaktifkan berhenti memeriksa aturan ini. |

Endpoint menggunakan pola **upsert per channel** — satu rule per channel, `PUT` menggantikan nilai yang ada atau membuat baru jika belum ada:

### Endpoint (tag **Chat Expiration**)

| Aksi | Endpoint |
|---|---|
| List semua aturan | `GET /api/chat-expiration-rules` |
| Buat / update aturan | `PUT /api/chat-expiration-rules/{channel}` |

`{channel}` hanya menerima nilai: `whatsapp`, `instagram`, `email`. Untuk saat ini hanya `email` yang ditampilkan di UI.

Contoh payload update aturan Email:

```http
PUT /api/chat-expiration-rules/email
Content-Type: application/json

{
  "window_hours": 72,
  "auto_resolve": true,
  "block_text_after_window": true,
  "is_active": true
}
```

:::tip
Set `window_hours` ke **0** untuk menonaktifkan kedaluwarsa tanpa menonaktifkan aturan sepenuhnya — berguna jika ingin mempertahankan konfigurasi `block_text_after_window` sambil menangguhkan auto-resolve sementara.
:::

---

## Aturan Penugasan (Assignment Rules)

### Cara kerja

Assignment rules menentukan strategi penugasan agen otomatis saat percakapan masuk. Aturan dievaluasi berdasarkan **prioritas** (nilai lebih tinggi = diperiksa lebih dulu) dan dicocokkan berdasarkan channel dan/atau divisi.

Penugasan dieksekusi saat endpoint `POST /api/assignment-rules/assign` dipanggil — biasanya oleh integrasi atau alur kerja yang memanggil API ini setelah percakapan dibuat. Sistem mencari aturan aktif dengan prioritas tertinggi yang cocok, lalu memilih agen berdasarkan strategi yang dikonfigurasi.

### Strategi penugasan

| Strategi | Keterangan |
|---|---|
| `round_robin` | Giliran merata: memilih agen online berikutnya dalam rotasi berdasarkan `last_assigned_agent_id`. |
| `load_based` | Beban terendah: memilih agen online dengan jumlah percakapan `open` paling sedikit. |
| `manual` | Tidak ada penugasan otomatis — percakapan tetap tanpa agen hingga ditugaskan secara manual. |

:::note
Jika tidak ada agen dengan status `is_online = true` saat penugasan dipicu, respons mengembalikan `agent_id: null` tanpa error — percakapan tetap tidak terassign.
:::

### Kolom konfigurasi

| Field | Wajib | Keterangan |
|---|---|---|
| **Name** | Ya | Nama aturan, 1–100 karakter. |
| **Strategy** | Ya | `round_robin`, `load_based`, atau `manual`. Default: `round_robin`. |
| **Channel** | Tidak | Filter ke satu channel: `whatsapp`, `instagram`, `messenger`, `email`. Kosong = semua channel. |
| **Division** | Tidak | Filter ke satu divisi (UUID). Kosong = semua divisi. |
| **Priority** | Ya | Angka 0–100. Lebih tinggi = diperiksa lebih dulu. Default: 0. |
| **Active** | Ya | Toggle aktif/nonaktif. |

### Logika matching

Aturan cocok jika **kedua kondisi** terpenuhi:

- Channel rule = channel percakapan, **atau** channel rule kosong (wildcard).
- Division rule = division percakapan, **atau** division rule kosong (wildcard).

Aturan aktif dengan prioritas tertinggi yang cocok yang digunakan.

### Endpoint (tag **Assignment Rules**)

| Aksi | Endpoint |
|---|---|
| List aturan | `GET /api/assignment-rules` |
| Buat aturan | `POST /api/assignment-rules` |
| Update aturan | `PATCH /api/assignment-rules/{id}` |
| Hapus aturan | `DELETE /api/assignment-rules/{id}` |
| Jalankan penugasan | `POST /api/assignment-rules/assign` |

Contoh payload assign:

```json
{
  "channel": "whatsapp",
  "division_id": "uuid-divisi-vip"
}
```

Respons:

```json
{
  "agent_id": "uuid-agen",
  "agent_name": "Budi Santoso",
  "rule_id": "uuid-aturan",
  "strategy": "round_robin"
}
```

---

## Rute terkait

- [Kebijakan SLA](/panduan/admin/kebijakan-sla) — batas waktu respons dan resolusi per channel/divisi
- [Divisi](/panduan/admin/divisi) — konfigurasi divisi yang dipakai di scoping aturan
- [Activity Logs](/panduan/admin/activity-logs) — audit perubahan konfigurasi otomasi
