DRWhatsapp CRM

Ubah chat jadi closing. Follow-up otomatis, dibantu AI, tanpa ribet.

Akun baru otomatis role guest — hubungi super-admin untuk akses lebih.

DRWhatsapp CRM v ·© DRW Corp

Kirim pesan dari nomor

⚠️

Peringatan Risiko Banned WhatsApp

  • Melanggar ToS WhatsApp — nomor bisa di-banned kapan saja, apalagi kalau kirim massal ke nomor yang belum pernah chat Anda.
  • Nomor baru + blast = cepat kena banned. Untuk follow-up ke kontak existing (yang sudah pernah interaksi) risikonya jauh lebih rendah.

🔥 Hot

balas ≤ 3 hari — prioritas closing

🌤️ Warm

interaksi ≤ 30 hari — nurture

❄️ Cold

belum interaksi — re-engage

⛔ Lost

berhenti langganan

Aktivitas Pesan

Status Follow-up

Distribusi Jam Pengiriman

Segmen Tag Customer

💬 Inbox = daftar percakapan (1 baris per kontak, pesan terbaru + status belum dibaca) — untuk membalas chat masuk. Beda dengan Pesan yang menampilkan log tiap pesan keluar/masuk.

Total percakapan

Leads

🔥 🌤️ ❄️

hot / warm / cold

Belum dibaca

Pesan masuk (total)

Pesan dibalas (total)

hari ini

Belum ada percakapan.

Total customer

baru hari ini

Leads

🔥 🌤️ ❄️

hot / warm / cold

Aktif

bisa di-follow-up

Berhenti Langganan

Reply rate

retensi balasan

Nama & Nomor WA TagFollow-up BalasStatus AktivitasAksi
Belum ada data.

📋 Pesan = log audit tiap pesan keluar & masuk (waktu, arah, status kirim, sumber: manual/API/AI) — untuk melacak & filter riwayat. Untuk membalas chat, gunakan Inbox.

Pesan keluar

Pesan masuk

Delivery rate

berhasil terkirim

Total di halaman

sesuai filter

ArahKontak PesanWaktu
Belum ada pesan.

Total

Pending

Terkirim

Dibalas

Gagal

Jatuh tempo

antre kirim

KontakTemplate JadwalStatus PercobaanAksi
Belum ada follow-up.

Rangkaian follow-up otomatis bertahap (mis. H+1, H+3, H+7); tiap langkah terkirim sesuai jeda. Berhenti otomatis saat customer membalas. Untuk memakainya: Enroll customer ke sequence (dari kartu di bawah, halaman Customer, atau drawer customer).

Total sequence

Enrollment aktif

Total langkah

Belum ada sequence.

Gunakan placeholder {{name}}, {{phone}}.

Total template

Dipakai di sequence

Halaman

Belum ada template.

Pengguna login via Google SSO. Akun baru otomatis role guest. Atur role tiap pengguna di sini; super-admin utama (email di env) tak bisa diubah/dihapus.

Total pengguna

baru per 7 hari

Aktif

bisa login

Nonaktif

akses dicabut

Online 24 jam

login terkini

PenggunaRole Akun WhatsApp StatusLogin terakhir Aksi
Belum ada pengguna.

Buat role custom dengan izin view/write per modul fitur, lalu terapkan ke pengguna.

Belum ada role.

Riwayat percobaan login (berhasil & gagal).

Total login

email unik

Berhasil

sesi terautentikasi

Gagal

percobaan ditolak

Aktivitas terkini

24 jam · per 7 hari

WaktuEmail HasilIPPerangkat
Belum ada aktivitas.

Asisten & analis CRM bertenaga AI. Tanya apa saja soal data CRM, minta analisis, atau draft balasan.

AI belum dikonfigurasi. Set CLAUDE_API_KEY dan/atau OPENAI_API_KEY di .env, lalu restart.

🔥 Hot

balas ≤ 3 hari — prioritas closing

🌤️ Warm

interaksi ≤ 30 hari — nurture

❄️ Cold

belum interaksi — re-engage

⛔ Lost

berhenti langganan

Draft AI menunggu

⚠️ Kuota / kredit AI habis

Provider menolak permintaan (kuota/billing). Top-up kredit atau ganti provider di Pengaturan AI.

Asisten CRM DRW

Punya akses ringkasan CRM real-time. Coba salah satu:

Riwayat dibagi per akun WhatsApp. "Bersihkan" hanya mengosongkan tampilan; "Hapus" permanen untuk semua user akun.

Analisis Expert

Klik "Buat analisis" untuk laporan kondisi CRM, temuan, dan rekomendasi aksi minggu ini.
Menganalisis data…
⚙️ Otomasi untuk akun: Tiap nomor WhatsApp punya pengaturan otomasi sendiri (tidak dibagi antar akun).
Memuat otomasi…
Belum ada akun WhatsApp. Sambungkan nomor di menu Koneksi dulu.

Pilih AI & model default (hemat / medium / expert) yang dipakai di semua fitur AI, lalu atur otomasi. Model hemat cocok untuk testing.

Aturan perilaku pengiriman yang menekan risiko nomor diblokir WhatsApp. Setiap aturan bisa dimatikan/dinyalakan dan berlaku langsung tanpa restart.

Basis pengetahuan produk & FAQ. Dipakai AI sebagai acuan saat menjawab / draft balasan agar akurat.

🧴

Katalog Produk DRW Skincare

produk (sinkron dari drwrnd) · dipakai AI otomatis · terakhir

Belum ada produk tersinkron.
Entri manual
Belum ada entri. Tambahkan info produk/FAQ agar AI menjawab akurat.

Monitoring semua aktivitas kirim ke server WhatsApp: Integration API (server lain) & internal (follow-up, balasan, auto-reply, test).

Total

per 24 jam

Terkirim

Sampai/Dibaca

/

Dibalas

Gagal

Integration/Internal

/

pengirim

WaktuKanalPengirim TujuanPesanStatus
Belum ada aktivitas.

Panduan integrasi server-to-server: kirim follow-up WhatsApp dari aplikasi lain melalui server ini, dengan pengirim = nomor yang tertaut ke email (role). Aktivitas terekam di Log Aktivitas.

Endpoint

Metode GET atau POST (JSON). Alias param: e|email_enc, phone|to, text|message, account (opsional bila email tertaut >1 nomor).

Cara kerja & keamanan

  1. Aplikasi lain login Google SSO yang sama → dapat email user.
  2. Aplikasi mengenkripsi email (AES-256-GCM) dengan shared secret yang sama (INTEGRATION_SECRET), menghasilkan token.
  3. Panggil endpoint dengan token sebagai param e (bukan token sesi).
  4. Server ini mendekripsi → cek email tertaut ke nomor WA tersambung (via role/Pengguna) → jika ya, kirim & catat.
  5. Token punya masa berlaku (anti-replay).

Batas & aturan anti-ban

Endpoint ini kanal otomatis, jadi tunduk pada SEMUA aturan di Pengaturan Anti-ban. Status di bawah dibaca langsung dari pengaturan aktif.

  • • Maks pesan/menit per nomor (selalu)
  • • Cooldown detik ke kontak yang sama (selalu)
  • • Kontak opt-out ditolak (selalu)
  • • Delay manusiawi tiap kirim (selalu)

Plafon harian efektif per nomor

Ditolak → respons memuat rule (alasan tepatnya). 429 = coba lagi nanti (ada Retry-After), 409 = jangan diulang tanpa perbaikan.

Daftar endpoint

Semua memakai otentikasi yang sama (?e=<token>) dan otomatis dibatasi ke nomor yang tertaut ke email tersebut. Param account (id atau nomor) opsional untuk mempersempit ke satu nomor; wajib bila email tertaut ke >1 nomor pada endpoint kirim/QR.

EndpointIzinKegunaan
GET|POST /api/send inbox/followups write Kirim pesan. Param: phone, text, account.
GET /api/accounts connection view Daftar nomor + status: connected, hasQR, idle.
GET /api/qr connection write Barcode pairing untuk ditampilkan di server lain. qr = data URL PNG, langsung dipakai <img src>. Panggil ulang tiap ±3 dtk sampai connected:true.
GET /api/contacts customers view Daftar kontak + message_count & last_message_at. Param: search, limit (maks 200), offset.
GET /api/messages inbox view Riwayat pesan. Tanpa phone = semua percakapan; dengan phone = riwayat satu kontak. Polling pakai since_id (balikan last_id), atau since/direction.
GET /api/stream inbox view Notifikasi realtime (SSE). Event pesan masuk/keluar & perubahan centang, sudah tersaring per nomor.

Endpoint baca & QR TIDAK memakai API key dashboard — jadi aplikasi lain tak perlu diberi akses penuh ke server ini.

Contoh: notifikasi pesan masuk & tampilkan barcode

// 1) NOTIFIKASI REALTIME (SSE) — pesan masuk langsung sampai ke server Anda
const es = new EventSource(`https://wa.drwapp.com/api/stream?e=${token}`);
es.onmessage = (ev) => {
  const m = JSON.parse(ev.data);
  if (m.direction === 'in') simpanKeInboxAnda(m); // { phone, name, body, account_id, at }
};

// 2) ATAU POLLING (lebih tahan putus) — simpan last_id sebagai kursor
let lastId = bacaKursorTersimpan() || 0;
setInterval(async () => {
  const r = await fetch(`https://wa.drwapp.com/api/messages?e=${token}&since_id=${lastId}&direction=in`);
  const d = await r.json();
  for (const m of d.rows) simpanKeInboxAnda(m);
  lastId = d.last_id; simpanKursor(lastId);  // hanya yang BARU di panggilan berikutnya
}, 10000);

// 3) RIWAYAT SATU KONTAK (untuk halaman detail di aplikasi Anda)
const riwayat = await (await fetch(
  `https://wa.drwapp.com/api/messages?e=${token}&phone=628123456789&limit=100`)).json();

// 4) TAMPILKAN BARCODE KONEKSI DI SERVER LAIN
async function tampilkanQR(account) {
  const d = await (await fetch(`https://wa.drwapp.com/api/qr?e=${token}&account=${account}`)).json();
  if (d.connected) return tampilkanStatus('Nomor sudah tersambung ✅');
  if (d.qr) document.querySelector('#qr').src = d.qr; // data URL PNG, langsung tampil
  setTimeout(() => tampilkanQR(account), 3000);       // QR berganti berkala
}

Token berumur pendek (). Untuk SSE/polling jangka panjang, generate ulang token di server Anda sebelum tiap koneksi/permintaan baru.

Uji cepat: generate token

Buat token untuk email tertentu (khusus super-admin) untuk mencoba endpoint.

Contoh: enkripsi email & kirim (Node.js)

import crypto from 'node:crypto';

const SECRET = process.env.INTEGRATION_SECRET; // SAMA dgn server WA
const key = crypto.createHash('sha256').update(SECRET).digest();

function encryptEmail(email) {
  const iv = crypto.randomBytes(12);
  const c = crypto.createCipheriv('aes-256-gcm', key, iv);
  const payload = Buffer.from(JSON.stringify({ e: email.toLowerCase(), t: Math.floor(Date.now()/1000) }));
  const ct = Buffer.concat([c.update(payload), c.final()]);
  return Buffer.concat([iv, c.getAuthTag(), ct]).toString('base64url');
}

const token = encryptEmail(req.session.user.email); // email user yg login SSO
const url = `https://wa.drwapp.com/api/send?e=${token}`
  + `&phone=628123456789&text=${encodeURIComponent('Halo, ini follow-up dari kami')}`;

const r = await fetch(url);
const data = await r.json();

if (r.ok) {
  console.log('terkirim:', data.wa_message_id); // { ok, from, to, wa_message_id }

} else if (r.status === 429) {
  // DITAHAN SEMENTARA (rate_menit | cooldown_kontak | daily_cap | warmup |
  // pesan_identik | jam_kerja). Jadwalkan ulang di antrean Anda — JANGAN
  // retry beruntun, itu justru menaikkan risiko nomor kena banned.
  const jeda = Number(r.headers.get('retry-after') || data.retryAfterSec || 60);
  console.warn(`ditahan (${data.rule}), coba lagi ${jeda} detik lagi`);
  await antrean.jadwalkanUlang({ phone, text, setelahDetik: jeda });

} else if (r.status === 409) {
  // DITOLAK PERMANEN. Mengulang dgn isi & tujuan yang sama akan ditolak lagi:
  //   kontak_dingin       -> nomor belum pernah chat; jangan hubungi duluan
  //   link_pesan_pertama  -> kirim perkenalan tanpa link dulu
  //   opt_out             -> kontak berhenti langganan; hormati, jangan kirim
  console.error(`ditolak (${data.rule}): ${data.error}`);
  await antrean.batalkan({ phone, alasan: data.rule });

} else {
  // 400 param kurang | 401 token salah/kadaluarsa | 403 email tak berizin
  // 503 integrasi nonaktif
  console.error(`gagal ${r.status}: ${data.error}`);
}

Contoh: PHP

<?php
$secret = getenv('INTEGRATION_SECRET');
$key = hash('sha256', $secret, true);
$iv = random_bytes(12);
$payload = json_encode(['e' => strtolower($email), 't' => time()]);
$tag = '';
$ct = openssl_encrypt($payload, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
$token = rtrim(strtr(base64_encode($iv.$tag.$ct), '+/', '-_'), '=');
$url = "https://wa.drwapp.com/api/send?e=$token&phone=628123456789&text=".urlencode('Halo');

// PENTING: tanpa ignore_errors, file_get_contents() mengembalikan false pada
// 4xx sehingga alasan penolakan (rule) tidak pernah terbaca.
$ctx  = stream_context_create(['http' => ['ignore_errors' => true, 'timeout' => 20]]);
$body = file_get_contents($url, false, $ctx);
$code = (int) substr($http_response_header[0], 9, 3);
$res  = json_decode($body, true);

if ($code === 200) {
  echo "terkirim: ".$res['wa_message_id'];

} elseif ($code === 429) {
  // Ditahan sementara -> jadwalkan ulang, jangan retry beruntun.
  $jeda = $res['retryAfterSec'] ?? 60;
  error_log("ditahan ({$res['rule']}), ulangi {$jeda} detik lagi");
  antrean_jadwalkan_ulang($phone, $text, $jeda);

} elseif ($code === 409) {
  // Ditolak permanen: kontak_dingin | link_pesan_pertama | opt_out.
  // Perbaiki dulu isi/tujuannya — mengulang sama saja akan ditolak lagi.
  error_log("ditolak ({$res['rule']}): {$res['error']}");
  antrean_batalkan($phone, $res['rule']);

} else {
  error_log("gagal {$code}: ".($res['error'] ?? $body));
}

Kode respons

200{ ok:true, from, to, wa_message_id } — terkirim & tercatat
400Param kurang (e/phone/text)
401Token tidak valid / secret salah / kadaluarsa
403Email tidak terdaftar / tidak tertaut nomor / tanpa izin
409Ditolak permanen — nomor tak tersambung / >1 nomor (sertakan account) / rule: opt_out, kontak_dingin, link_pesan_pertama. Jangan diulang dengan isi yang sama.
429Ditahan sementara — rule: rate_menit, cooldown_kontak, daily_cap, warmup, pesan_identik, jam_kerja. Coba lagi sesuai Retry-After/retryAfterSec.
503Integration API belum diaktifkan

Kelola beberapa nomor WhatsApp (multi-sesi). Tiap nomor punya data & ringkasan sendiri; gabungan lihat di Semua Akun.

Belum ada akun. Klik + Tambah Nomor.
WA WA 🔕 Berhenti langganan

Status WA

Lead

Analisis AI

Belum dianalisa. Klik "Analisa" untuk auto-tag, minat, keberatan & rekomendasi aksi.

Enroll ke Sequence

Follow-up terjadwal

Belum ada follow-up terjadwal.
Belum ada percakapan.
AI menyarankan balasan (menunggu persetujuan)

AI menyusun draft balasan…
🖼️ Gambar siap dikirim (teks jadi caption)

✨ Draft dari AI — tinjau & edit sebelum kirim.

WhatsApp belum tersambung — pesan bisa gagal terkirim.

Nama ini tidak akan tertimpa saat sinkron ulang kontak WhatsApp.

Nama dari WhatsApp (hasil sync)

Pisahkan beberapa tag dengan koma. Kosongkan untuk menghapus semua tag.

💡 Emoji didukung. Untuk mengirim gambar, lampirkan langsung dari kotak chat customer (tombol 🖼️).

H+ = jumlah hari sejak customer di-enroll. H+0 = kirim langsung. Jeda antar langkah minimal 24 jam (H+ tiap langkah wajib naik ≥ 1 hari, anti-spam).

Format kolom: name,phone,tags (baris pertama header). Tag dipisah ;

· +
Tidak ada kontak cocok

Minimal hari & jam ini ke depan — tidak bisa memilih waktu yang sudah lewat.

Jendela menutup otomatis begitu tersambung.