Bot WA AI untuk Survey & Feedback

Cara membuat bot AI WhatsApp untuk survey dan feedback. Collect insights, NPS, CSAT otomatis. Tutorial lengkap!

Bot WA AI untuk Survey & Feedback
Bot WA AI untuk Survey & Feedback

AI Survey = Higher response rate!

Survey via WhatsApp dengan AI bisa lebih conversational, adapt pertanyaan, dan mendapat response rate 3-5x lebih tinggi dari email survey.


Kenapa Survey via WhatsApp?

📊 PERBANDINGAN RESPONSE RATE:

Email Survey: 5-15%
SMS Survey: 10-20%
WhatsApp Survey: 35-50%
WhatsApp AI Survey: 45-60%

KENAPA LEBIH TINGGI:
- Familiar platform
- Conversational
- Quick to respond
- No app/link needed
- Personal feel

Jenis Survey

📋 SURVEY TYPES:

1. NPS (Net Promoter Score)
   "Seberapa likely merekomendasikan kami?"
   Scale: 0-10

2. CSAT (Customer Satisfaction)
   "Seberapa puas dengan layanan kami?"
   Scale: 1-5

3. CES (Customer Effort Score)
   "Seberapa mudah menyelesaikan masalah?"
   Scale: 1-5

4. POST-PURCHASE
   "Gimana pengalaman belanja hari ini?"

5. POST-SUPPORT
   "Apakah masalah terselesaikan?"

6. PRODUCT FEEDBACK
   "Gimana pendapat tentang produk X?"

NPS Survey Implementation

System Prompt:

javascript

const NPS_SURVEY_PROMPT = `Kamu adalah AI yang bertugas mengumpulkan feedback NPS untuk [BRAND].

FLOW SURVEY:
1. Sapa dan jelaskan survey singkat (30 detik)
2. Tanya NPS score (0-10)
3. Tanya alasan singkat
4. Ucapkan terima kasih

ATURAN:
- Conversational, tidak kaku
- Jangan memaksa jika tidak mau
- Validasi score 0-10
- Follow up berdasarkan score:
  - 0-6 (Detractor): Tanya apa yang bisa diperbaiki
  - 7-8 (Passive): Tanya apa yang bisa lebih baik
  - 9-10 (Promoter): Minta testimonial/review

IMPORTANT:
- Jangan terlalu banyak pertanyaan
- Max 3 exchanges
- Extract score dengan [NPS_SCORE: X]
- Extract feedback dengan [FEEDBACK: text]`;

Implementation:

javascript

const surveyStates = new Map();

async function handleNPSSurvey(userId, userMessage) {
    let state = surveyStates.get(userId) || { step: 'intro', data: {} };
    
    switch (state.step) {
        case 'intro':
            surveyStates.set(userId, { step: 'score', data: {} });
            return `Hai Kak! 👋

Boleh minta waktu 30 detik untuk feedback?

Dari skala 0-10, seberapa likely kakak merekomendasikan [BRAND] ke teman/keluarga?

0 = Tidak akan sama sekali
10 = Pasti rekomendasikan

Ketik angkanya ya! 😊`;

        case 'score':
            const score = parseInt(userMessage);
            
            if (isNaN(score) || score < 0 || score > 10) {
                return 'Mohon masukkan angka 0-10 ya kak 🙏';
            }
            
            state.data.score = score;
            state.step = 'reason';
            surveyStates.set(userId, state);
            
            if (score <= 6) {
                return `Terima kasih kak! 

Kami ingin improve. Boleh ceritakan apa yang perlu kami perbaiki? 🙏`;
            } else if (score <= 8) {
                return `Terima kasih kak! 

Apa yang bisa kami lakukan agar bisa dapat nilai 9 atau 10 dari kakak? 😊`;
            } else {
                return `Wow, terima kasih banyak kak! 🎉

Boleh ceritakan apa yang paling kakak suka dari [BRAND]?`;
            }

        case 'reason':
            state.data.feedback = userMessage;
            state.step = 'done';
            
            // Save to database
            await saveSurveyResponse(userId, {
                type: 'NPS',
                score: state.data.score,
                feedback: state.data.feedback,
                timestamp: new Date()
            });
            
            // Clear state
            surveyStates.delete(userId);
            
            // Customize thank you based on score
            if (state.data.score >= 9) {
                return `Terima kasih banyak atas feedback positifnya kak! 💕

Kalau berkenan, boleh bantu kami dengan review di Google/Tokopedia? Akan sangat membantu! 🙏

[LINK REVIEW]

Sekali lagi, terima kasih! 🎁`;
            } else {
                return `Terima kasih atas masukannya kak! 🙏

Feedback kakak sangat berharga untuk kami improve.

Ada yang bisa kami bantu lagi hari ini?`;
            }
    }
}

AI-Powered Conversational Survey

javascript

async function handleAISurvey(userId, userMessage, surveyType) {
    const context = await getSurveyContext(userId);
    
    const systemPrompt = buildSurveyPrompt(surveyType, context);
    
    const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [
            { role: 'system', content: systemPrompt },
            ...context.history,
            { role: 'user', content: userMessage }
        ],
        tools: surveyTools
    });
    
    const aiResponse = response.choices[0].message;
    
    // Extract survey data from AI response
    const extractedData = extractSurveyData(aiResponse.content);
    
    if (extractedData.score !== null) {
        await saveSurveyResponse(userId, extractedData);
    }
    
    // Check for survey completion
    if (extractedData.complete) {
        await markSurveyComplete(userId);
    }
    
    return cleanResponse(aiResponse.content);
}

const surveyTools = [
    {
        type: 'function',
        function: {
            name: 'save_survey_response',
            description: 'Save survey response when customer provides a score or feedback',
            parameters: {
                type: 'object',
                properties: {
                    score: { type: 'number' },
                    feedback: { type: 'string' },
                    category: { type: 'string' },
                    complete: { type: 'boolean' }
                }
            }
        }
    }
];

Post-Purchase Survey

javascript

async function sendPostPurchaseSurvey(orderId) {
    const order = await db.orders.findOne({ orderId });
    const customer = await db.customers.findOne({ oderId
oderId
userId: order.userId });
    
    // Wait 1 day after delivery
    const surveyMessage = `Hai Kak ${customer.name}! 👋

Pesanan #${orderId} sudah sampai ya?

Kami mau tau pengalaman belanja kakak:

1️⃣ Gimana kualitas produknya?
   ⭐⭐⭐⭐⭐ (ketik 1-5)

2️⃣ Gimana pengiriman/packagingnya?
   ⭐⭐⭐⭐⭐ (ketik 1-5)

Reply dengan format: [rating produk] [rating pengiriman]
Contoh: 5 4

Atau ceritakan langsung pendapat kakak! 😊`;

    await sendWhatsApp(order.customerPhone, surveyMessage);
    
    // Track survey sent
    await db.surveys.insertOne({
        orderId,
        userId: order.userId,
        type: 'post_purchase',
        sentAt: new Date(),
        status: 'pending'
    });
}

// Parse response
async function parsePostPurchaseResponse(userId, message) {
    // Try to extract ratings
    const ratingPattern = /(\d)\s*(\d)?/;
    const match = message.match(ratingPattern);
    
    if (match) {
        const productRating = parseInt(match[1]);
        const deliveryRating = match[2] ? parseInt(match[2]) : null;
        
        return {
            productRating,
            deliveryRating,
            rawFeedback: message
        };
    }
    
    // Use AI to extract from free-form response
    const extraction = await openai.chat.completions.create({
        model: 'gpt-4o-mini',
        messages: [{
            role: 'user',
            content: `Extract ratings and sentiment from this feedback.
Return JSON with: productRating (1-5), deliveryRating (1-5), sentiment (positive/neutral/negative), summary

Feedback: "${message}"`
        }],
        response_format: { type: 'json_object' }
    });
    
    return JSON.parse(extraction.choices[0].message.content);
}

Survey Triggers

javascript

// Automated survey triggers
const surveyTriggers = {
    // After purchase delivered
    postPurchase: {
        event: 'order_delivered',
        delay: '24h',
        condition: (order) => order.status === 'delivered'
    },
    
    // After support ticket closed
    postSupport: {
        event: 'ticket_closed',
        delay: '1h',
        condition: (ticket) => ticket.resolution !== 'spam'
    },
    
    // After first purchase
    newCustomer: {
        event: 'first_order',
        delay: '7d',
        condition: (customer) => customer.orderCount === 1
    },
    
    // Periodic NPS
    periodicNPS: {
        event: 'schedule',
        schedule: '0 10 1 * *', // 1st of each month
        condition: (customer) => customer.lastSurvey < daysAgo(90)
    }
};

// Register triggers
async function setupSurveyTriggers() {
    // Order delivered trigger
    eventEmitter.on('order_delivered', async (order) => {
        await scheduleSurvey(order.userId, 'postPurchase', {
            delay: 24 * 60 * 60 * 1000, // 24 hours
            context: { orderId: order.id }
        });
    });
    
    // Support ticket closed
    eventEmitter.on('ticket_closed', async (ticket) => {
        if (ticket.resolution !== 'spam') {
            await scheduleSurvey(ticket.userId, 'postSupport', {
                delay: 60 * 60 * 1000, // 1 hour
                context: { ticketId: ticket.id }
            });
        }
    });
}

Survey Analytics Dashboard

javascript

// NPS calculation
async function calculateNPS(startDate, endDate) {
    const surveys = await db.surveys.find({
        type: 'NPS',
        completedAt: { $gte: startDate, $lte: endDate }
    }).toArray();
    
    const total = surveys.length;
    const promoters = surveys.filter(s => s.score >= 9).length;
    const detractors = surveys.filter(s => s.score <= 6).length;
    
    const nps = ((promoters - detractors) / total * 100).toFixed(0);
    
    return {
        nps: parseInt(nps),
        promoters: (promoters / total * 100).toFixed(1) + '%',
        passives: ((total - promoters - detractors) / total * 100).toFixed(1) + '%',
        detractors: (detractors / total * 100).toFixed(1) + '%',
        totalResponses: total
    };
}

// CSAT calculation
async function calculateCSAT(startDate, endDate) {
    const surveys = await db.surveys.find({
        type: 'CSAT',
        completedAt: { $gte: startDate, $lte: endDate }
    }).toArray();
    
    const satisfied = surveys.filter(s => s.score >= 4).length;
    const csat = (satisfied / surveys.length * 100).toFixed(1);
    
    return {
        csat: `${csat}%`,
        avgScore: (surveys.reduce((a, s) => a + s.score, 0) / surveys.length).toFixed(2),
        totalResponses: surveys.length
    };
}

// Feedback analysis
async function analyzeFeedback(startDate, endDate) {
    const feedbacks = await db.surveys.find({
        feedback: { $exists: true, $ne: '' },
        completedAt: { $gte: startDate, $lte: endDate }
    }).toArray();
    
    // Use AI to categorize and summarize
    const analysis = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [{
            role: 'user',
            content: `Analyze these customer feedbacks. 
            
Identify:
1. Top 5 positive themes
2. Top 5 areas for improvement
3. Common keywords
4. Overall sentiment

Feedbacks:
${feedbacks.map(f => f.feedback).join('\n---\n')}`
        }]
    });
    
    return analysis.choices[0].message.content;
}

Response Templates

javascript

const surveyResponses = {
    declined: `Tidak masalah kak! 🙏
Terima kasih sudah menjadi customer [BRAND].
Kalau ada pertanyaan, chat aja ya!`,

    lowScore: `Terima kasih atas kejujurannya kak 🙏

Feedback ini sangat berharga. Tim kami akan review dan improve.

Ada yang bisa kami bantu sekarang?`,

    highScore: `Yeay, terima kasih kak! 🎉💕

Senang banget kakak puas dengan [BRAND]!

Kalau berkenan, boleh bantu review di:
⭐ Google: [link]
⭐ Tokopedia: [link]

Terima kasih banyak! 🙏`,

    reminder: `Hai Kak! 👋

Kemarin kami kirim survey singkat, belum sempat isi ya?

Cuma butuh 30 detik dan sangat membantu kami improve!

Mau isi sekarang? Reply YES 😊`
};

Best Practices

DO ✅

- Keep survey short (2-3 questions)
- Conversational tone
- Timing yang tepat
- Follow up low scores
- Celebrate high scores
- Analyze trends

DON'T ❌

- Terlalu banyak pertanyaan
- Kaku seperti form
- Survey saat tidak tepat
- Ignore negative feedback
- No follow up action
- Survey terlalu sering

FAQ

Berapa pertanyaan ideal?

2-3 pertanyaan max. Lebih dari itu, completion rate drop drastis.

Kapan timing terbaik kirim survey?

Post-purchase: 1-2 hari setelah terima. Post-support: 1 jam setelah resolved.


Kesimpulan

AI Survey = Actionable insights!

Traditional SurveyAI WhatsApp Survey
5-15% response45-60% response
Static questionsAdaptive
Delayed insightsReal-time

Setup AI Survey →


Artikel Terkait