Flow Code Documentation

Panduan menulis chatbot flow menggunakan JSON code editor.

Terakhir diperbarui: 4 April 2026

Struktur JSON

Setiap flow terdiri dari dua bagian: nodes (kotak-kotak aksi) dan edges (garis penghubung antar node).

{
  "nodes": [ ... ],
  "edges": [ ... ]
}

Node Types

Setiap node memiliki id, type, position, dan data.

start

Titik awal flow. Setiap flow harus punya tepat 1 node start.

{
  "id": "start-1",
  "type": "start",
  "position": { "x": 250, "y": 50 },
  "data": { "label": "Start" }
}

send_message

Kirim pesan teks ke customer.

{
  "type": "send_message",
  "data": {
    "label": "Greeting",
    "message": "Halo {{name}}, ada yang bisa dibantu?"
  }
}

Gunakan {{variableName}} untuk menyisipkan variabel dari konteks flow.

send_buttons

Kirim pesan dengan tombol interaktif WhatsApp (maks 3 tombol).

{
  "type": "send_buttons",
  "data": {
    "label": "Menu",
    "message": "Pilih salah satu:",
    "buttons": [
      { "id": "order", "title": "Cek Pesanan" },
      { "id": "promo", "title": "Info Promo" },
      { "id": "help", "title": "Bantuan" }
    ]
  }
}

send_list

Kirim pesan dengan list menu WhatsApp.

{
  "type": "send_list",
  "data": {
    "label": "Katalog",
    "message": "Lihat produk kami:",
    "listButtonText": "Lihat Menu",
    "sections": [
      {
        "title": "Makanan",
        "rows": [
          { "id": "nasi", "title": "Nasi Goreng", "description": "Rp 25.000" },
          { "id": "mie", "title": "Mie Goreng", "description": "Rp 22.000" }
        ]
      },
      {
        "title": "Minuman",
        "rows": [
          { "id": "es-teh", "title": "Es Teh", "description": "Rp 8.000" }
        ]
      }
    ]
  }
}

ask_question

Kirim pertanyaan dan tunggu jawaban customer. Jawaban disimpan sebagai variabel.

{
  "type": "ask_question",
  "data": {
    "label": "Tanya Nama",
    "question": "Siapa nama Anda?",
    "variableName": "name"
  }
}

Jawaban customer akan tersimpan di variabel name dan bisa dipakai di node selanjutnya dengan {{name}}.

condition

Percabangan berdasarkan kondisi. Edge dari node ini harus punya sourceHandle: "yes" atau "no".

Tipe kondisi:

  • keyword — cek apakah pesan mengandung kata kunci tertentu
  • variable — cek nilai variabel (equals, contains, not_empty)
  • button_reply — cek ID tombol yang diklik customer
  • any — selalu true
// Cek button reply
{
  "type": "condition",
  "data": {
    "label": "Cek Menu",
    "conditionType": "button_reply",
    "conditionKeywords": ["order", "track"]
  }
}

// Cek keyword
{
  "type": "condition",
  "data": {
    "label": "Cek Keyword",
    "conditionType": "keyword",
    "conditionKeywords": ["beli", "order", "pesan"]
  }
}

// Cek variabel
{
  "type": "condition",
  "data": {
    "label": "Cek Email",
    "conditionType": "variable",
    "conditionVariable": "email",
    "conditionOperator": "not_empty"
  }
}

set_tag

Tambahkan tag ke customer.

{
  "type": "set_tag",
  "data": {
    "label": "Tag VIP",
    "tags": ["vip", "repeat-buyer"]
  }
}

assign_agent

Assign percakapan ke agen manusia. Flow akan berakhir setelah node ini.

{
  "type": "assign_agent",
  "data": {
    "label": "Ke CS",
    "agentId": "user_id_agen"
  }
}

delay

Jeda sebelum melanjutkan ke node berikutnya.

{
  "type": "delay",
  "data": {
    "label": "Tunggu 5 detik",
    "delaySeconds": 5
  }
}

ai_reply

Biarkan AI membalas berdasarkan konfigurasi AI chatbot. Flow akan berhenti dan AI auto-reply mengambil alih.

{
  "type": "ai_reply",
  "data": {
    "label": "AI Reply",
    "aiPrompt": "Jawab pertanyaan customer tentang produk."
  }
}

end

Akhiri flow. Bisa menyertakan pesan penutup (opsional).

{
  "type": "end",
  "data": {
    "label": "Selesai",
    "message": "Terima kasih telah menghubungi kami!"
  }
}

Edges

Edge menghubungkan satu node ke node lainnya. Setiap edge punya source dan target yang merujuk ke id node.

{
  "id": "edge-1",
  "source": "start-1",
  "target": "msg-1"
}

Untuk node condition, gunakan sourceHandle untuk menentukan jalur:

// Jalur jika kondisi TRUE
{ "id": "e-yes", "source": "cond-1", "target": "reply-yes", "sourceHandle": "yes" }

// Jalur jika kondisi FALSE
{ "id": "e-no", "source": "cond-1", "target": "reply-no", "sourceHandle": "no" }

Position

Setiap node punya position untuk layout visual: { "x": 250, "y": 150 }. Atur posisi agar flow terlihat rapi di visual editor.

Variabel

Gunakan {{variableName}} di field message untuk menyisipkan nilai. Ada dua jenis variabel:

Variabel Bawaan (Built-in)

Otomatis tersedia tanpa perlu di-set — diambil dari data customer:

VariabelDeskripsiContoh Nilai
{{name}} atau {{nama}}Nama customerAhmad Fauzi
{{phone}} atau {{telepon}}Nomor telepon customer628123456789
{{email}}Email customer (jika ada)[email protected]
{{tags}}Tag customer, dipisah komavip, repeat-buyer
{{lead_score}}Skor lead customer (0-100)75

Variabel Custom

Dikumpulkan selama flow berjalan via node ask_question:

  • Node ask_question menyimpan jawaban ke variabel yang ditentukan di variableName
  • Variabel custom bisa dipakai di node selanjutnya: {{invoiceId}}, {{orderId}}, dll
  • Variabel custom menimpa variabel bawaan jika namanya sama
  • Node condition bisa mengecek variabel dengan conditionType: "variable"

Contoh Penggunaan

// Pakai variabel bawaan
"message": "Halo {{name}}! Nomor kamu {{phone}}"

// Pakai variabel dari ask_question
"message": "Invoice #{{invoiceId}} sudah kami catat"

// Kombinasi keduanya
"message": "{{nama}}, pesanan {{orderId}} sedang diproses"

Contoh Lengkap

Flow dengan menu tombol, percabangan, dan balasan berbeda:

{
  "nodes": [
    {
      "id": "start-1",
      "type": "start",
      "position": { "x": 250, "y": 50 },
      "data": { "label": "Start" }
    },
    {
      "id": "msg-1",
      "type": "send_message",
      "position": { "x": 250, "y": 150 },
      "data": {
        "label": "Kirim Pesan",
        "message": "Halo! Selamat datang. Pilih menu:"
      }
    },
    {
      "id": "btn-1",
      "type": "send_buttons",
      "position": { "x": 250, "y": 280 },
      "data": {
        "label": "Menu Utama",
        "message": "Silakan pilih:",
        "buttons": [
          { "id": "order", "title": "Cek Pesanan" },
          { "id": "promo", "title": "Info Promo" },
          { "id": "help", "title": "Bantuan" }
        ]
      }
    },
    {
      "id": "cond-1",
      "type": "condition",
      "position": { "x": 250, "y": 420 },
      "data": {
        "label": "Cek Pilihan",
        "conditionType": "button_reply",
        "conditionKeywords": ["order"]
      }
    },
    {
      "id": "order-reply",
      "type": "send_message",
      "position": { "x": 100, "y": 560 },
      "data": {
        "label": "Info Pesanan",
        "message": "Silakan kirim nomor pesanan Anda."
      }
    },
    {
      "id": "promo-reply",
      "type": "send_message",
      "position": { "x": 400, "y": 560 },
      "data": {
        "label": "Info Promo",
        "message": "Promo minggu ini: Diskon 20% untuk semua produk!"
      }
    },
    {
      "id": "end-1",
      "type": "end",
      "position": { "x": 250, "y": 700 },
      "data": {
        "label": "Selesai",
        "message": "Terima kasih! Ada yang bisa dibantu lagi?"
      }
    }
  ],
  "edges": [
    { "id": "e1", "source": "start-1", "target": "msg-1" },
    { "id": "e2", "source": "msg-1", "target": "btn-1" },
    { "id": "e3", "source": "btn-1", "target": "cond-1" },
    { "id": "e4", "source": "cond-1", "target": "order-reply", "sourceHandle": "yes" },
    { "id": "e5", "source": "cond-1", "target": "promo-reply", "sourceHandle": "no" },
    { "id": "e6", "source": "order-reply", "target": "end-1" },
    { "id": "e7", "source": "promo-reply", "target": "end-1" }
  ]
}

Tips

  • Setiap flow harus dimulai dari node start
  • ID node harus unik dalam satu flow
  • WhatsApp membatasi maksimal 3 tombol per send_buttons
  • WhatsApp membatasi maksimal 10 item per section di send_list
  • Gunakan code editor untuk duplikasi flow — salin JSON, edit, dan tempel di flow baru
  • Klik "Visual" untuk melihat hasil visual dari kode yang ditulis