Auto Reply WA dengan Conditional Logic
Cara buat auto reply WhatsApp dengan conditional logic. If-then rules, branching, dynamic responses. Bot yang lebih pintar!
Satu keyword, response berbeda tergantung kondisi!
Conditional logic membuat bot lebih pintar dengan response yang dinamis berdasarkan berbagai faktor.
Apa Itu Conditional Logic?
BASIC AUTO REPLY:
Keyword "harga" → Selalu response yang sama
CONDITIONAL AUTO REPLY:
Keyword "harga" → Check kondisi:
├─ Jika jam kerja → Response lengkap + CTA
├─ Jika malam → Response + "Besok kita follow up"
├─ Jika customer VIP → Response + diskon khusus
└─ Jika stock habis → Response + alternatif produkJenis Kondisi yang Bisa Dipakai
1. Time-Based Conditions
javascript
function getTimeBasedResponse(message) {
const hour = new Date().getHours();
const day = new Date().getDay(); // 0 = Sunday
// Weekend
if (day === 0 || day === 6) {
return responses.weekend;
}
// Time of day
if (hour >= 8 && hour < 12) {
return responses.morning;
} else if (hour >= 12 && hour < 17) {
return responses.afternoon;
} else if (hour >= 17 && hour < 21) {
return responses.evening;
} else {
return responses.night;
}
}2. Customer-Based Conditions
javascript
async function getCustomerBasedResponse(phone, message) {
const customer = await db.customers.findOne({ phone });
if (!customer) {
return responses.newCustomer;
}
// VIP customer
if (customer.tier === 'vip' || customer.totalSpent > 5000000) {
return responses.vipCustomer;
}
// Repeat customer
if (customer.orderCount >= 3) {
return responses.loyalCustomer;
}
// Has pending order
if (customer.pendingOrders > 0) {
return responses.hasPendingOrder;
}
return responses.regularCustomer;
}3. Product/Stock Conditions
javascript
async function getProductResponse(productName) {
const product = await db.products.findOne({
name: { $regex: productName, $options: 'i' }
});
if (!product) {
return responses.productNotFound;
}
if (product.stock <= 0) {
return {
...responses.outOfStock,
alternatives: await getSimilarProducts(product.category)
};
}
if (product.stock < 5) {
return {
...responses.lowStock,
urgency: `Sisa ${product.stock} pcs!`
};
}
if (product.onSale) {
return {
...responses.onSale,
discount: product.discountPercent
};
}
return responses.normalStock;
}4. Location-Based Conditions
javascript
async function getLocationBasedResponse(phone, keyword) {
const customer = await db.customers.findOne({ phone });
const city = customer?.city || 'unknown';
// Shipping availability
const shippingZones = {
'jakarta': { available: ['same-day', 'next-day', 'regular'] },
'bandung': { available: ['next-day', 'regular'] },
'surabaya': { available: ['regular'] }
};
const zone = shippingZones[city.toLowerCase()] || { available: ['regular'] };
if (zone.available.includes('same-day')) {
return responses.sameDayAvailable;
}
return responses.standardShipping;
}5. Conversation History Conditions
javascript
async function getHistoryBasedResponse(phone, message) {
const history = await db.conversations.find({
phone,
timestamp: { $gte: Date.now() - 24 * 60 * 60 * 1000 } // Last 24h
});
// Check if already asked same question
const askedBefore = history.some(h =>
h.intent === detectIntent(message)
);
if (askedBefore) {
return responses.alreadyAsked;
}
// Check if in middle of flow
const lastMessage = history[history.length - 1];
if (lastMessage?.awaitingResponse) {
return handleAwaitingResponse(lastMessage, message);
}
return null; // Process normally
}Implementation Examples
Example 1: Smart Greeting
javascript
async function getSmartGreeting(phone) {
const customer = await db.customers.findOne({ phone });
const hour = new Date().getHours();
let greeting = hour < 12 ? 'Selamat pagi' :
hour < 18 ? 'Selamat siang' : 'Selamat malam';
if (customer) {
greeting += ` ${customer.name}! 👋`;
// Check recent activity
if (customer.lastOrder) {
const daysSinceOrder = getDaysSince(customer.lastOrder);
if (daysSinceOrder < 3) {
return `${greeting}\n\nGimana pesanan terakhirnya? Sudah sampai dengan baik? 📦`;
} else if (daysSinceOrder < 30) {
return `${greeting}\n\nSenang ketemu lagi! Ada yang bisa dibantu hari ini? 😊`;
} else {
return `${greeting}\n\nLama tidak jumpa! Ada koleksi baru yang mungkin cocok buat kakak nih 🛍️`;
}
}
return `${greeting}\n\nAda yang bisa dibantu?`;
}
return `${greeting}! 👋\n\nSelamat datang di [TOKO]! Ada yang bisa dibantu?`;
}Example 2: Dynamic Pricing Response
javascript
async function getPriceResponse(productName, phone) {
const product = await db.products.findOne({ name: productName });
const customer = await db.customers.findOne({ phone });
if (!product) {
return 'Produk tidak ditemukan. Coba cek katalog kami di [LINK]';
}
let price = product.price;
let message = `💰 ${product.name}\n\n`;
// Check for active promotions
const promo = await getActivePromo(product.id);
if (promo) {
const discountedPrice = price * (1 - promo.discount / 100);
message += `Harga normal: ~Rp ${price.toLocaleString()}~\n`;
message += `🔥 PROMO: Rp ${discountedPrice.toLocaleString()} (${promo.discount}% OFF)\n`;
message += `⏰ Berlaku sampai: ${promo.endDate}\n`;
price = discountedPrice;
} else {
message += `Harga: Rp ${price.toLocaleString()}\n`;
}
// VIP discount
if (customer?.tier === 'vip') {
const vipPrice = price * 0.95;
message += `👑 Harga VIP: Rp ${vipPrice.toLocaleString()} (Extra 5% OFF)\n`;
}
// Stock status
if (product.stock > 10) {
message += `\n✅ Ready stock!`;
} else if (product.stock > 0) {
message += `\n⚠️ Sisa ${product.stock} pcs, order sekarang!`;
} else {
message += `\n❌ Stock habis. Restock estimasi: ${product.restockDate}`;
message += `\nMau dinotify saat ready? Ketik NOTIFY`;
}
return message;
}Example 3: Order Flow dengan Conditions
javascript
async function handleOrderFlow(phone, message, state) {
switch (state.step) {
case 'select_product':
const product = await findProduct(message);
if (!product) {
return 'Produk tidak ditemukan. Ketik KATALOG untuk lihat produk.';
}
if (product.stock <= 0) {
return `${product.name} sedang habis 😔\n\nMau lihat alternatif serupa? Ketik YA`;
}
state.product = product;
state.step = 'select_variant';
if (product.variants?.length > 0) {
return `${product.name} tersedia dalam:\n${formatVariants(product.variants)}\n\nPilih varian:`;
} else {
state.step = 'select_quantity';
return `${product.name} - Rp ${product.price.toLocaleString()}\n\nMau order berapa?`;
}
case 'select_quantity':
const qty = parseInt(message);
if (isNaN(qty) || qty <= 0) {
return 'Masukkan jumlah yang valid (contoh: 2)';
}
if (qty > state.product.stock) {
return `Stock hanya tersedia ${state.product.stock} pcs. Mau order ${state.product.stock}?`;
}
state.quantity = qty;
state.step = 'confirm_address';
const customer = await db.customers.findOne({ phone });
if (customer?.address) {
return `Kirim ke alamat ini?\n\n${customer.address}\n\nKetik YA atau kirim alamat baru:`;
}
return 'Kirim alamat lengkap untuk pengiriman:';
// ... more steps
}
}Condition Building Blocks
IF-THEN Structure:
javascript
const conditions = {
rules: [
{
if: { type: 'time', operator: 'between', value: [8, 17] },
then: { action: 'reply', template: 'business_hours' }
},
{
if: { type: 'customer.tier', operator: 'equals', value: 'vip' },
then: { action: 'reply', template: 'vip_greeting' }
},
{
if: { type: 'product.stock', operator: 'lessThan', value: 5 },
then: { action: 'reply', template: 'low_stock_urgency' }
}
],
default: { action: 'reply', template: 'standard' }
};
function evaluateCondition(condition, context) {
const { type, operator, value } = condition;
const actualValue = getValueByPath(context, type);
switch (operator) {
case 'equals':
return actualValue === value;
case 'notEquals':
return actualValue !== value;
case 'greaterThan':
return actualValue > value;
case 'lessThan':
return actualValue < value;
case 'between':
return actualValue >= value[0] && actualValue <= value[1];
case 'contains':
return actualValue.includes(value);
default:
return false;
}
}Complex Conditions (AND/OR)
javascript
const complexRule = {
if: {
AND: [
{ type: 'customer.tier', operator: 'equals', value: 'vip' },
{ type: 'time', operator: 'between', value: [8, 17] },
{
OR: [
{ type: 'product.category', operator: 'equals', value: 'premium' },
{ type: 'cart.total', operator: 'greaterThan', value: 1000000 }
]
}
]
},
then: { action: 'reply', template: 'vip_premium_offer' }
};
function evaluateComplexCondition(condition, context) {
if (condition.AND) {
return condition.AND.every(c => evaluateComplexCondition(c, context));
}
if (condition.OR) {
return condition.OR.some(c => evaluateComplexCondition(c, context));
}
return evaluateCondition(condition, context);
}Best Practices
DO ✅
- Start simple, add complexity gradually
- Test each condition thoroughly
- Log which conditions triggered
- Have a sensible default/fallback
- Document your rulesDON'T ❌
- Terlalu banyak nested conditions
- Conditions yang saling conflict
- Tidak ada default response
- Overcomplicate untuk simple use case
- Tidak test edge casesFAQ
Berapa banyak kondisi yang ideal?
3-5 kondisi per flow sudah cukup. Lebih dari itu, consider simplify atau split flows.
Bagaimana debug conditional logic?
Log everything! Log kondisi mana yang match, data apa yang dicek, dan response apa yang dikirim.
Bisa tanpa coding?
Platform visual seperti Balaswa support conditional logic tanpa coding via UI drag-drop.
Kesimpulan
Conditional logic = Smart bot!
| Static Response | Conditional Response |
|---|---|
| Same for everyone | Personalized |
| Ignores context | Context-aware |
| Limited usefulness | Highly relevant |
| Feels robotic | Feels intelligent |
Build smarter bots with conditions!