# Panduan Penanganan Webhook Twilio

## Masalah: Document Parse Failure (Error 12100)

### Checklist Diagnosis
- [ ] Periksa view-source di browser
- [ ] Cek warning PHP "headers already sent"
- [ ] Periksa whitespace di config.php atau file included
- [ ] Periksa output XML di browser developer tools

### Template Solusi yang Terbukti Berhasil

```php
// 1. Kontrol Buffer di Awal File
while (ob_get_level()) {
    ob_end_clean();  // Bersihkan semua buffer yang ada
}
ob_start();  // Mulai buffer baru

// 2. Matikan Error Reporting
error_reporting(0);
ini_set('display_errors', 0);

// 3. Include Files
require_once 'includes/config.php';

// ... kode logika aplikasi ...

// 4. Sebelum Output XML
ob_clean();  // Bersihkan buffer
header('Content-Type: text/xml');

// 5. Bersihkan XML Output
$xml = $response->asXML();
$xml = preg_replace('/^\xEF\xBB\xBF/', '', $xml);  // Hapus BOM
$xml = preg_replace('/^\s+/', '', $xml);  // Hapus whitespace
echo $xml;
```

### Yang HARUS Dihindari
- ❌ Spasi setelah tag penutup PHP `?>`
- ❌ Deklarasi XML manual
- ❌ Echo sebelum output XML
- ❌ Mencampur HTML dengan output XML

### Best Practices
1. Selalu gunakan output buffering
2. Selalu bersihkan output sebelum mengirim XML
3. Pastikan header Content-Type: text/xml terkirim
4. Log semua error untuk debugging
5. Gunakan try-catch untuk penanganan error

### Tips Debugging
1. View-source di browser untuk melihat output mentah
2. Periksa error log PHP
3. Periksa log Twilio untuk detail error
4. Test webhook URL langsung di browser

### Contoh Implementasi Lengkap

```php
<?php
// Kontrol buffer
while (ob_get_level()) {
    ob_end_clean();
}
ob_start();

// Matikan error reporting
error_reporting(0);
ini_set('display_errors', 0);

require_once 'includes/config.php';

try {
    // Logika aplikasi
    $response = new Twilio\TwiML\VoiceResponse();
    $response->say('Hello World', ['language' => 'id-ID']);
    
    // Output XML
    ob_clean();
    header('Content-Type: text/xml');
    $xml = $response->asXML();
    $xml = preg_replace('/^\xEF\xBB\xBF/', '', $xml);
    $xml = preg_replace('/^\s+/', '', $xml);
    echo $xml;
    
} catch (Exception $e) {
    error_log("Webhook error: " . $e->getMessage());
    
    ob_clean();
    header('Content-Type: text/xml');
    $response = new Twilio\TwiML\VoiceResponse();
    $response->say('Maaf, terjadi kesalahan.', ['language' => 'id-ID']);
    echo $response->asXML();
}
```

### Referensi
- [Twilio Error 12100](https://www.twilio.com/docs/api/errors/12100)
- [TwiML Documentation](https://www.twilio.com/docs/voice/twiml) 