# Voz e imágenes

## Audios (Whisper)

### Cómo llega un audio
Twilio webhook recibe los siguientes params POST:
- `NumMedia`: cantidad (>0 si hay adjuntos)
- `MediaUrl0`, `MediaUrl1`, ...: URLs de Twilio para descargar
- `MediaContentType0`, ...: tipo MIME (audio/ogg típicamente, a veces audio/mp4)

### Descarga + transcripción

```php
// 1. Descargar el audio (requiere auth Twilio)
function descargarMedia(string $url, string $sid, string $token): ?string {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERPWD        => "$sid:$token",
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_FOLLOWLOCATION => true,
    ]);
    return curl_exec($ch) ?: null;
}

// 2. Mandar a Whisper
function transcribirAudio(string $bin, string $contentType, string $openaiKey): ?string {
    $ext = '.ogg';
    if (strpos($contentType, 'mp4')  !== false) $ext = '.mp4';
    if (strpos($contentType, 'mpeg') !== false) $ext = '.mp3';

    $tmp = tempnam(sys_get_temp_dir(), 'aud_') . $ext;
    file_put_contents($tmp, $bin);

    $ch = curl_init('https://api.openai.com/v1/audio/transcriptions');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $openaiKey],
        CURLOPT_POSTFIELDS     => [
            'file'     => new CURLFile($tmp, $contentType, basename($tmp)),
            'model'    => 'whisper-1',
            'language' => 'es',
        ],
    ]);
    $resp = curl_exec($ch);
    unlink($tmp);
    $j = json_decode($resp, true);
    return $j['text'] ?? null;
}
```

### Uso en el flujo
1. Detectar `NumMedia > 0` y `MediaContentType0` empieza con `audio/`.
2. Descargar binario.
3. Transcribir.
4. Setear `$body = $transcripcion` y seguir el flujo normal del agente.

### Costos
- Whisper: $0.006 USD/min de audio.
- Audios de WhatsApp típicos: 5-30 segundos → ~$0.0005 - $0.003 USD por mensaje.

### Caveats
- Si el cliente habla en castellano con jerga (lunfardo, marcas con pronunciación rara) → Whisper a veces transcribe mal. El system prompt puede pedirle a Claude que "interprete términos posiblemente mal transcritos como nombres de productos".
- WhatsApp manda audios en `audio/ogg` codec Opus. Whisper lo acepta nativamente.

## Imágenes (Claude vision)

### Cómo llega una imagen
Mismo flujo que audio pero `MediaContentType0` empieza con `image/` (jpeg, png, webp).

### Cómo se le pasa a Claude

Claude API soporta imágenes multimodales en el campo `content` del mensaje user:

```json
{
  "role": "user",
  "content": [
    {
      "type": "image",
      "source": {
        "type": "base64",
        "media_type": "image/jpeg",
        "data": "<base64>"
      }
    },
    {
      "type": "text",
      "text": "Texto opcional que acompaña la imagen"
    }
  ]
}
```

### Uso en el flujo

```php
// 1. Detectar imagen
if ($contentType_starts_with('image/')) {
    $imgBin = descargarMedia($url, $sid, $token);
    $imgBase64 = base64_encode($imgBin);
    $imgMediaType = $contentType;
}

// 2. Inyectarla en el primer mensaje del cliente en el historial
if ($imgBase64 && $msgs[$last]['role'] === 'user') {
    $msgs[$last]['content'] = [
        ['type' => 'image', 'source' => [
            'type'       => 'base64',
            'media_type' => $imgMediaType,
            'data'       => $imgBase64,
        ]],
        ['type' => 'text', 'text' => $textoOriginal ?: 'Mirá esta foto y decime qué producto es.'],
    ];
}
```

### Casos típicos
- Cliente manda foto de un producto → agente identifica marca/modelo → busca en catálogo → cotiza.
- Cliente manda foto de comprobante de pago → agente lee monto y CBU → confirma al cobrador.
- Cliente manda foto de daño → agente clasifica gravedad y deriva.

### Costos
- Claude Sonnet 4 con imagen: ~$0.01 por imagen procesada (depende del tamaño/tokens).
- Si la imagen es muy grande (>3 MB) conviene resizear antes de pasarla.

### Tips
- En el system prompt agregar: *"Si el cliente manda una foto, intentá identificar el producto/objeto. Si no es claro, pedile detalles (marca, medida)."*
- Si el modelo no reconoce nada, mandar fallback: "No pude identificar el producto. ¿Me podés decir la marca y medida?"
- Las imágenes consumen muchos tokens de input — limitar tamaño con resize si tu plan tiene cap.

## Ventajas comerciales

- **Voz**: clientes pyme/mayores prefieren mandar audios, lo aceptan los hacés más amigable.
- **Imágenes**: reducir back-and-forth de "qué producto", "qué marca", "qué medida".
- Para vender el servicio: ambos features son "WOW factor" para el dueño del comercio que ve el demo.
