Bot WA AI dengan Image Recognition

Cara membuat bot AI WhatsApp dengan image recognition. Analisis foto, OCR, product identification. Tutorial lengkap!

Bot WA AI dengan Image Recognition
Bot WA AI dengan Image Recognition

Vision AI = Bot yang bisa "lihat"!

Bot dengan image recognition bisa analisis foto produk, baca teks dari gambar (OCR), verifikasi bukti transfer, dan banyak lagi.


Use Cases

📸 USE CASES IMAGE AI:

1. BUKTI TRANSFER
   Customer kirim screenshot
   → Auto-verify pembayaran

2. PRODUCT IDENTIFICATION
   Foto produk kompetitor
   → "Kami punya yang mirip!"

3. OCR (Text Extraction)
   Foto KTP/dokumen
   → Extract data otomatis

4. DAMAGE REPORT
   Foto produk rusak
   → Auto-assess untuk klaim

5. STYLE MATCHING
   Foto outfit inspirasi
   → Rekomendasi produk mirip

6. RECEIPT SCANNING
   Foto struk belanja
   → Input data otomatis

Implementation dengan GPT-4 Vision

Basic Image Analysis:

javascript

const OpenAI = require('openai');
const openai = new OpenAI();

async function analyzeImage(imageUrl, prompt) {
    const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [
            {
                role: 'user',
                content: [
                    {
                        type: 'text',
                        text: prompt
                    },
                    {
                        type: 'image_url',
                        image_url: {
                            url: imageUrl,
                            detail: 'high' // atau 'low' untuk hemat token
                        }
                    }
                ]
            }
        ],
        max_tokens: 1000
    });
    
    return response.choices[0].message.content;
}

// Dengan base64 (untuk gambar dari WhatsApp)
async function analyzeImageBase64(base64Data, mimeType, prompt) {
    const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [
            {
                role: 'user',
                content: [
                    { type: 'text', text: prompt },
                    {
                        type: 'image_url',
                        image_url: {
                            url: `data:${mimeType};base64,${base64Data}`
                        }
                    }
                ]
            }
        ]
    });
    
    return response.choices[0].message.content;
}

WhatsApp Integration:

javascript

async function handleImageMessage(userId, message) {
    const imageInfo = message.imageMessage || message.image;
    
    // 1. Download image
    const imageBuffer = await downloadMedia(imageInfo.id);
    const base64 = imageBuffer.toString('base64');
    const mimeType = imageInfo.mimetype || 'image/jpeg';
    
    // 2. Get caption/context if any
    const caption = imageInfo.caption || '';
    
    // 3. Determine analysis type
    const analysisType = detectAnalysisType(caption);
    
    // 4. Analyze based on type
    let result;
    switch (analysisType) {
        case 'payment_proof':
            result = await verifyPaymentProof(base64, mimeType);
            break;
        case 'product_search':
            result = await findSimilarProducts(base64, mimeType);
            break;
        case 'damage_report':
            result = await assessDamage(base64, mimeType);
            break;
        default:
            result = await generalImageAnalysis(base64, mimeType, caption);
    }
    
    return result;
}

function detectAnalysisType(caption) {
    const lowerCaption = caption.toLowerCase();
    
    if (lowerCaption.includes('bukti') || lowerCaption.includes('transfer')) {
        return 'payment_proof';
    }
    if (lowerCaption.includes('cari') || lowerCaption.includes('mirip')) {
        return 'product_search';
    }
    if (lowerCaption.includes('rusak') || lowerCaption.includes('cacat')) {
        return 'damage_report';
    }
    
    return 'general';
}

Verifikasi Bukti Transfer

javascript

async function verifyPaymentProof(base64, mimeType) {
    const prompt = `Analisis screenshot bukti transfer ini.

Extract informasi berikut dalam format JSON:
{
  "bank_pengirim": "nama bank",
  "bank_tujuan": "nama bank",
  "nominal": "jumlah dalam angka",
  "tanggal": "tanggal transfer",
  "jam": "jam transfer",
  "no_referensi": "nomor referensi jika ada",
  "nama_pengirim": "nama pengirim",
  "nama_penerima": "nama penerima",
  "is_valid": true/false,
  "confidence": "high/medium/low",
  "notes": "catatan jika ada yang mencurigakan"
}

Perhatikan tanda-tanda screenshot palsu seperti:
- Font tidak konsisten
- Angka tidak sejajar
- Watermark aneh
- Format tidak sesuai bank`;

    const analysis = await analyzeImageBase64(base64, mimeType, prompt);
    
    try {
        const data = JSON.parse(analysis);
        
        // Verify against pending orders
        if (data.is_valid && data.confidence !== 'low') {
            const matchedOrder = await findMatchingOrder(data.nominal);
            
            if (matchedOrder) {
                await updateOrderPayment(matchedOrder.id, {
                    verified: true,
                    proofData: data
                });
                
                return `✅ Pembayaran terverifikasi!

📋 Detail:
- Nominal: Rp ${parseInt(data.nominal).toLocaleString()}
- Order: #${matchedOrder.orderId}
- Bank: ${data.bank_pengirim}

Pesanan akan segera diproses! 🎉`;
            }
        }
        
        return `⚠️ Tidak dapat memverifikasi otomatis.

Tim kami akan cek manual dalam 1x24 jam.
Atau hubungi CS untuk verifikasi lebih cepat.`;
        
    } catch (e) {
        return 'Maaf, gambar kurang jelas. Bisa kirim ulang dengan kualitas lebih baik?';
    }
}

Product Search by Image

javascript

async function findSimilarProducts(base64, mimeType) {
    // 1. Analyze image to get product attributes
    const analysisPrompt = `Analisis gambar produk fashion ini.

Identifikasi:
{
  "category": "dress/blouse/pants/etc",
  "style": "casual/formal/sporty/etc",
  "colors": ["warna utama", "warna sekunder"],
  "pattern": "polos/motif/stripes/etc",
  "material_guess": "katun/silk/polyester/etc",
  "occasion": ["casual", "kerja", "pesta"],
  "keywords": ["keyword1", "keyword2"]
}`;

    const analysis = await analyzeImageBase64(base64, mimeType, analysisPrompt);
    const attributes = JSON.parse(analysis);
    
    // 2. Search similar products in catalog
    const similarProducts = await db.products.find({
        category: attributes.category,
        $or: [
            { colors: { $in: attributes.colors } },
            { tags: { $in: attributes.keywords } },
            { occasions: { $in: attributes.occasion } }
        ]
    }).limit(5).toArray();
    
    // 3. Format response
    if (similarProducts.length > 0) {
        let response = `Aku temukan produk mirip di katalog kami! 😊\n\n`;
        
        similarProducts.forEach((p, i) => {
            response += `${i+1}️⃣ *${p.name}*\n`;
            response += `   💰 Rp ${p.price.toLocaleString()}\n`;
            response += `   🎨 ${p.colors.join(', ')}\n\n`;
        });
        
        response += `Mau lihat detail yang mana kak?`;
        return response;
    }
    
    return `Hmm, belum ada yang persis sama di katalog kami 😔

Tapi aku bisa carikan yang mirip stylenya!
Prefer warna apa kak?`;
}

OCR untuk Dokumen

javascript

async function extractTextFromImage(base64, mimeType, documentType) {
    const prompts = {
        ktp: `Extract data dari foto KTP ini:
{
  "nik": "16 digit",
  "nama": "nama lengkap",
  "tempat_lahir": "kota",
  "tanggal_lahir": "DD-MM-YYYY",
  "jenis_kelamin": "L/P",
  "alamat": "alamat lengkap",
  "rt_rw": "RT/RW",
  "kelurahan": "nama",
  "kecamatan": "nama",
  "agama": "agama",
  "status_perkawinan": "status",
  "pekerjaan": "pekerjaan",
  "kewarganegaraan": "WNI/WNA"
}`,
        
        receipt: `Extract data dari struk/receipt ini:
{
  "store_name": "nama toko",
  "date": "tanggal",
  "items": [{"name": "item", "qty": 1, "price": 0}],
  "subtotal": 0,
  "tax": 0,
  "total": 0,
  "payment_method": "cash/card/etc"
}`,
        
        invoice: `Extract data dari invoice ini:
{
  "invoice_number": "nomor",
  "date": "tanggal",
  "due_date": "jatuh tempo",
  "vendor": "nama vendor",
  "items": [{"description": "item", "qty": 1, "price": 0}],
  "subtotal": 0,
  "tax": 0,
  "total": 0
}`
    };
    
    const prompt = prompts[documentType] || 
        'Extract semua teks yang terlihat dari gambar ini.';
    
    const result = await analyzeImageBase64(base64, mimeType, prompt);
    
    return result;
}

Damage Assessment

javascript

async function assessDamage(base64, mimeType) {
    const prompt = `Analisis foto produk yang dilaporkan rusak/cacat.

Berikan assessment:
{
  "damage_type": "jenis kerusakan",
  "severity": "minor/moderate/severe",
  "description": "deskripsi detail kerusakan",
  "likely_cause": "kemungkinan penyebab",
  "is_manufacturing_defect": true/false,
  "is_shipping_damage": true/false,
  "recommendation": "refund/replace/repair/reject",
  "confidence": "high/medium/low",
  "notes": "catatan tambahan"
}

Pertimbangkan:
- Apakah kerusakan wajar terjadi saat pengiriman?
- Apakah terlihat seperti defect produksi?
- Apakah terlihat seperti kerusakan akibat pemakaian?`;

    const analysis = await analyzeImageBase64(base64, mimeType, prompt);
    const data = JSON.parse(analysis);
    
    // Auto-process based on assessment
    if (data.confidence === 'high') {
        if (data.recommendation === 'refund' || data.recommendation === 'replace') {
            return `Terima kasih sudah kirim fotonya kak 🙏

📋 Assessment:
- Jenis: ${data.damage_type}
- Tingkat: ${data.severity}
- Deskripsi: ${data.description}

✅ Kami setujui pengajuan ${data.recommendation === 'refund' ? 'refund' : 'tukar baru'}.

Langkah selanjutnya:
1. Kami akan kirim label retur
2. Kirim balik produknya
3. ${data.recommendation === 'refund' ? 'Refund diproses 3-5 hari' : 'Produk baru dikirim'}

Ada pertanyaan kak?`;
        }
    }
    
    return `Terima kasih fotonya kak!

Kami perlu review lebih lanjut oleh tim QC.
Estimasi: 1x24 jam.

Kami akan kabari hasilnya ya 🙏`;
}

Multiple Image Analysis

javascript

async function analyzeMultipleImages(images, context) {
    const content = [
        { type: 'text', text: context }
    ];
    
    for (const img of images) {
        content.push({
            type: 'image_url',
            image_url: {
                url: `data:${img.mimeType};base64,${img.base64}`,
                detail: 'low' // Use low for multiple images to save tokens
            }
        });
    }
    
    const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [{ role: 'user', content }],
        max_tokens: 2000
    });
    
    return response.choices[0].message.content;
}

// Usage: Compare before/after
async function compareBeforeAfter(beforeImg, afterImg) {
    return await analyzeMultipleImages(
        [beforeImg, afterImg],
        `Bandingkan kedua foto ini (before dan after).
        
Gambar 1: Kondisi sebelum
Gambar 2: Kondisi sesudah

Analisis:
1. Apa perbedaan yang terlihat?
2. Apakah ada perbaikan atau kerusakan?
3. Berikan rating perubahan 1-10`
    );
}

Cost Optimization

💰 VISION API PRICING:

GPT-4o Vision:
- Low detail: ~85 tokens per image
- High detail: 85-1700 tokens (depends on size)

TIPS HEMAT:
- Use 'low' detail untuk screening
- Resize image sebelum upload
- Cache hasil analysis
- Batch similar requests

EXAMPLE:
- 1000 images/day @ low detail
- ~85K tokens = ~$0.25/day

Best Practices

DO ✅

- Validate image before processing
- Use appropriate detail level
- Handle unclear images gracefully
- Confirm critical extractions
- Cache common analysis
- Compress images

DON'T ❌

- Process without validation
- Always use high detail
- Trust 100% tanpa verify
- Skip error handling
- Unlimited image size
- No rate limiting

FAQ

Accuracy OCR seberapa bagus?

GPT-4V: 90-95% untuk teks jelas. Kurang bagus untuk tulisan tangan atau blur.

Bisa detect fake screenshots?

Cukup bagus untuk yang obvious. Untuk yang sophisticated, perlu verification tambahan.


Kesimpulan

Vision AI = Bot yang lebih capable!

Text OnlyVision + Text
Limited inputRich input
Manual verifyAuto verify
No product searchVisual search

Setup Vision Bot →


Artikel Terkait