11 de junio de 2026

Monta un agente de IA en WhatsApp para tu pyme (Laravel + OpenAI)

Foto de Marco Orta Marco Orta | 11 min de lectura
Compartir
Agente de IA respondiendo en WhatsApp conectado a un backend Laravel y la API de OpenAI

En LATAM el primer contacto con un negocio no pasa por su web ni por una llamada: pasa por WhatsApp. El problema es que ese mensaje suele llegar a las 11 de la noche, en domingo, o cuando estás con otro cliente — y un lead que no recibe respuesta en minutos se enfría. Un agente de IA en WhatsApp resuelve justo eso: responde al instante, califica al prospecto y, cuando hace falta, te pasa la conversación ya tibia.

En este tutorial vas a construir un chatbot con IA en WhatsApp usando la WhatsApp Cloud API, Laravel como cerebro y la API de OpenAI para entender y redactar las respuestas. No es un widget genérico: es un agente que conoce tu catálogo, recuerda el hilo de la conversación y se comporta con la personalidad de tu marca.

Si todavía no integraste OpenAI en Laravel, primero pásate por la guía para integrar la API de OpenAI en Laravel; aquí damos por hecho que el cliente PHP ya está instalado.

Por qué WhatsApp es el canal #1 de las pymes en LATAM

WhatsApp no es “un canal más”. En México, Colombia o Argentina es el canal: la gente pregunta precios, agenda citas y cierra compras por ahí antes de visitar tu sitio. Para una pyme eso tiene dos caras:

  • La oportunidad: tasas de apertura por encima del 90% y respuestas en segundos. Ningún email se le acerca.
  • El cuello de botella: alguien tiene que estar del otro lado. Y “alguien” rara vez está disponible 24/7.

En febrero de 2026 Meta empezó a desplegar Business AI nativo en más de 15 países de la región, lo que normalizó que un negocio sea atendido por un asistente automático. La barrera psicológica ya cayó: tus clientes esperan una respuesta inmediata, sea humana o no. La pregunta ya no es “¿conviene automatizar?”, sino “¿lo armo a medida o me quedo con una caja negra que no controlo?”.

Qué resuelve realmente un agente de IA

Antes de escribir una línea de código, conviene tener claro el trabajo que va a hacer el agente. Los tres que mueven la aguja en una pyme:

  1. Calificar leads. Pregunta lo justo (qué necesita, presupuesto, zona) y etiqueta al prospecto antes de que tú entres a la conversación.
  2. Responder lo repetitivo 24/7. Horarios, precios, disponibilidad, “¿hacen envíos?”. El 80% de los mensajes son las mismas 10 preguntas.
  3. Vender y agendar. Sugiere productos de tu catálogo, comparte un link de pago o reserva un espacio en tu agenda.

La clave es que un agente con IA no responde con un árbol de botones rígido: entiende lenguaje natural, mantiene el contexto (“¿y ese en color azul lo tienen?”) y sabe cuándo escalar a un humano. Eso es lo que lo separa de los chatbots de hace cinco años.

Arquitectura: WhatsApp Cloud API + Laravel + OpenAI

El flujo completo es más simple de lo que parece:

Cliente en WhatsApp
        │  (escribe un mensaje)
        ▼
WhatsApp Cloud API (Meta)
        │  webhook POST → tu servidor
        ▼
Laravel  ──►  recupera el historial de la conversación
        │     arma el prompt (sistema + catálogo + hilo)
        ▼
OpenAI (gpt-4o-mini)  ──►  redacta la respuesta
        │
        ▼
Laravel  ──►  envía la respuesta vía Graph API
        ▼
WhatsApp Cloud API  ──►  el cliente recibe el mensaje

Vas a usar dos endpoints de la Cloud API:

OperaciónMétodoPara qué
Verificación del webhookGET /webhookMeta valida que el endpoint es tuyo
Recepción de mensajesPOST /webhookMeta te avisa de cada mensaje entrante
Envío de respuestasPOST /{phone-number-id}/messagesTu backend contesta al cliente

Requisitos previos

  • Una cuenta de Meta Business con un número dado de alta en la WhatsApp Business Platform (Cloud API). El sandbox gratuito de pruebas sirve para todo este tutorial.
  • El Phone Number ID y un token de acceso (idealmente permanente, vía System User).
  • Un proyecto Laravel 11 o 12 funcional. Si vienes de una versión vieja, mira cómo actualizar Laravel 9 a Laravel 10.
  • PHP 8.2+ — si aún no lo tienes, revisa cómo instalar PHP en Windows.
  • El cliente de OpenAI instalado según la guía de integración de OpenAI en Laravel.
  • Una URL HTTPS pública para el webhook. En desarrollo, un túnel como ngrok o expose basta.

Paso 1: Variables de entorno

Nunca metas tokens en el código. Abre tu .env:

WHATSAPP_TOKEN=EAAG...tu-token-permanente
WHATSAPP_PHONE_NUMBER_ID=1234567890
WHATSAPP_VERIFY_TOKEN=un-string-secreto-que-tu-inventas
WHATSAPP_API_VERSION=v21.0

OPENAI_API_KEY=sk-tu-clave-de-openai

El WHATSAPP_VERIFY_TOKEN lo inventas tú: es la palabra clave que Meta te devolverá al registrar el webhook para confirmar que el endpoint es tuyo.

Centraliza la config en config/services.php:

// config/services.php

return [
    // ... otras configuraciones

    'whatsapp' => [
        'token' => env('WHATSAPP_TOKEN'),
        'phone_number_id' => env('WHATSAPP_PHONE_NUMBER_ID'),
        'verify_token' => env('WHATSAPP_VERIFY_TOKEN'),
        'version' => env('WHATSAPP_API_VERSION', 'v21.0'),
    ],

    'openai' => [
        'api_key' => env('OPENAI_API_KEY'),
    ],
];

Paso 2: Las rutas del webhook

Meta hace dos cosas contra el mismo endpoint: lo verifica una vez (GET) y luego te notifica cada mensaje (POST). En routes/web.php:

use App\Http\Controllers\WhatsAppWebhookController;
use Illuminate\Support\Facades\Route;

Route::get('/webhook/whatsapp', [WhatsAppWebhookController::class, 'verify']);
Route::post('/webhook/whatsapp', [WhatsAppWebhookController::class, 'handle']);

Importante: el webhook de WhatsApp llega sin token CSRF. En Laravel 11+ añade la ruta a las excepciones en bootstrap/app.php con $middleware->validateCsrfTokens(except: ['webhook/whatsapp']), o colócala en routes/api.php.

Paso 3: Verificar el webhook

Cuando registres la URL en el panel de Meta, este hará un GET con tres parámetros. Tu trabajo es devolver el hub.challenge solo si el verify_token coincide:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\WhatsAppAgent;

class WhatsAppWebhookController extends Controller
{
    public function verify(Request $request)
    {
        $mode = $request->query('hub_mode');
        $token = $request->query('hub_verify_token');
        $challenge = $request->query('hub_challenge');

        if ($mode === 'subscribe'
            && $token === config('services.whatsapp.verify_token')) {
            // Meta espera el challenge en texto plano, no JSON.
            return response($challenge, 200);
        }

        return response('Forbidden', 403);
    }
}

Paso 4: Recibir el mensaje y responder

Aquí está el corazón del agente. El POST trae una estructura anidada; extraemos el texto y el número del remitente, y respondemos rápido: Meta reintenta el webhook si tardas más de unos segundos, así que el trabajo pesado va a una cola.

public function handle(Request $request, WhatsAppAgent $agent)
{
    $entry = $request->input('entry.0.changes.0.value');
    $message = $entry['messages'][0] ?? null;

    // Status updates (entregado, leído) también llegan aquí: los ignoramos.
    if (! $message || ($message['type'] ?? null) !== 'text') {
        return response()->json(['status' => 'ignored']);
    }

    $from = $message['from'];                 // número del cliente
    $text = $message['text']['body'];         // lo que escribió

    // Procesamos en segundo plano para responderle a Meta de inmediato.
    ProcessIncomingMessage::dispatch($from, $text);

    return response()->json(['status' => 'received']);
}

Si las colas todavía te suenan lejanas, la guía de optimización de rendimiento en Laravel cubre cuándo y cómo mover trabajo a queues.

Paso 5: El cerebro del agente

Toda la lógica de IA vive en un service dedicado. Hace tres cosas: recupera el historial reciente, arma el prompt y llama a OpenAI.

<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use OpenAI;

class WhatsAppAgent
{
    public function reply(string $from, string $userText): string
    {
        // 1. Recuperamos el hilo de los últimos mensajes (memoria corta).
        $history = Cache::get("wa:history:{$from}", []);

        // 2. Construimos el prompt: persona + catálogo + conversación.
        $messages = array_merge(
            [['role' => 'system', 'content' => $this->systemPrompt()]],
            $history,
            [['role' => 'user', 'content' => $userText]],
        );

        // 3. Llamamos a OpenAI.
        $client = OpenAI::client(config('services.openai.api_key'));

        $result = $client->chat()->create([
            'model' => 'gpt-4o-mini',
            'temperature' => 0.4,
            'messages' => $messages,
        ]);

        $answer = $result->choices[0]->message->content;

        // 4. Guardamos el intercambio para la próxima vuelta (TTL 24 h).
        $history[] = ['role' => 'user', 'content' => $userText];
        $history[] = ['role' => 'assistant', 'content' => $answer];
        Cache::put("wa:history:{$from}", array_slice($history, -12), now()->addDay());

        return $answer;
    }

    private function systemPrompt(): string
    {
        return <<<PROMPT
        Eres el asistente de ventas de "Muebles Roble", una pyme mexicana.
        Tono: cercano, claro y breve (máximo 3 frases por respuesta).
        Tu objetivo: resolver dudas, sugerir productos y agendar visitas.
        Si te piden algo fuera de catálogo o un descuento especial, responde
        que un asesor humano lo confirmará y pide nombre y ciudad.
        Nunca inventes precios ni stock que no estén en el catálogo.
        PROMPT;
    }
}

Tres detalles que marcan la diferencia entre un bot decente y uno que vende:

  1. Memoria por conversación. Sin historial, el agente olvida lo que el cliente dijo hace dos mensajes. Aquí usamos Cache por simplicidad; en producción guárdalo en una tabla conversations para tener trazabilidad.
  2. temperature baja (0.3–0.5). En atención a clientes quieres respuestas consistentes, no creatividad.
  3. El system prompt es tu producto. Ahí defines la personalidad, los límites (“nunca inventes precios”) y cuándo escalar a un humano. Inviértele tiempo: es lo que el cliente percibe como “tu marca”.

Paso 6: Enviar la respuesta a WhatsApp

El job en cola une las piezas: pide la respuesta al agente y la manda por la Graph API.

<?php

namespace App\Jobs;

use App\Services\WhatsAppAgent;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\Http;

class ProcessIncomingMessage implements ShouldQueue
{
    use Dispatchable, Queueable;

    public function __construct(
        public string $from,
        public string $text,
    ) {}

    public function handle(WhatsAppAgent $agent): void
    {
        $answer = $agent->reply($this->from, $this->text);

        $config = config('services.whatsapp');

        Http::withToken($config['token'])
            ->post("https://graph.facebook.com/{$config['version']}/{$config['phone_number_id']}/messages", [
                'messaging_product' => 'whatsapp',
                'to' => $this->from,
                'type' => 'text',
                'text' => ['body' => $answer],
            ])
            ->throw();
    }
}

Con esto ya tienes el lazo completo: el cliente escribe, OpenAI redacta y tu número de WhatsApp responde. Pruébalo enviando un mensaje a tu número de prueba — deberías ver la respuesta en segundos.

Paso 7: Conectar tu catálogo y CRM

Un agente que solo “platica” no vende. El salto de calidad es darle acceso a datos reales. Dos enfoques según tu volumen:

  • Catálogo pequeño (decenas de productos): inyéctalo directo en el system prompt como una lista. Simple y suficiente para la mayoría de pymes.
  • Catálogo grande o stock que cambia: usa function calling. Defines una función buscar_producto y dejas que el modelo la invoque cuando la necesita, consultando tu base de datos en tiempo real.
$result = $client->chat()->create([
    'model' => 'gpt-4o-mini',
    'messages' => $messages,
    'tools' => [[
        'type' => 'function',
        'function' => [
            'name' => 'buscar_producto',
            'description' => 'Busca productos disponibles por nombre o categoría.',
            'parameters' => [
                'type' => 'object',
                'properties' => [
                    'query' => ['type' => 'string', 'description' => 'Texto a buscar'],
                ],
                'required' => ['query'],
            ],
        ],
    ]],
]);

// Si el modelo decide llamar a la función, consultamos la DB y
// le devolvemos el resultado para que redacte la respuesta final.

Este patrón —exponer tu lógica de negocio como herramientas que el modelo puede invocar— es exactamente la idea detrás de MCP. Si quieres llevarlo al siguiente nivel, mira cómo construir un agente de IA con Laravel y MCP, donde el modelo ejecuta acciones reales sobre tus sistemas con un estándar abierto.

Para registrar cada lead calificado en tu CRM, basta con persistir la conversación y disparar un evento cuando el agente detecte intención de compra.

Reglas de Meta que debes respetar (2026)

WhatsApp no es un canal de envío libre. Si las ignoras, te suspenden el número:

  • Ventana de 24 horas. Solo puedes responder con mensajes libres dentro de las 24 h posteriores al último mensaje del cliente. Fuera de esa ventana necesitas una plantilla aprobada por Meta.
  • Opt-in obligatorio. El usuario debe haber iniciado el contacto o aceptado recibir mensajes. Nada de listas compradas.
  • Calidad del número. Meta puntúa tu número según bloqueos y reportes. Un agente que spamea baja tu quality rating y limita cuántos mensajes puedes enviar al día.
  • Transparencia. En varios países es buena práctica (y a veces requisito) avisar que se trata de un asistente automatizado y ofrecer pasar a un humano.

Trata estas reglas como parte del diseño, no como un trámite final. Si manejas datos personales de los clientes, revisa también autenticación sin contraseña en Laravel para flujos de identidad modernos.

¿A medida o un SaaS de chatbots?

La pregunta inevitable. La respuesta honesta depende de qué tan estándar sea tu operación:

SaaS de chatbotsAgente a medida (este tutorial)
Puesta en marchaMinutosDías
Costo mensualFijo por agente/conversaciónSolo API de OpenAI + tu hosting
PersonalizaciónLimitada a lo que el panel permiteTotal (catálogo, CRM, lógica propia)
DatosEn el servidor del proveedorEn tu infraestructura
Lógica de negocioDifícil de integrarNativa con tu Laravel

Un SaaS es perfecto para validar la idea esta semana. Pero en cuanto necesitas que el agente conozca tu inventario, escriba en tu sistema y siga reglas que solo existen en tu negocio, el costo de pelearte con un panel cerrado supera al de construirlo a medida — y te quedas dueño de tus datos.

Preguntas frecuentes

¿Necesito la API oficial o puedo usar una librería no oficial? Usa siempre la WhatsApp Cloud API oficial. Las librerías que automatizan WhatsApp Web violan los términos de Meta y terminan con el número baneado. La Cloud API tiene una capa gratuita generosa para empezar.

¿Cuánto cuesta operar el agente? Dos costos: los mensajes de WhatsApp (Meta cobra por conversación según país, con un volumen gratuito mensual) y la API de OpenAI. Con gpt-4o-mini cada respuesta cuesta fracciones de centavo, así que para una pyme el grueso del gasto suele ser WhatsApp, no la IA.

¿El agente puede pasar la conversación a un humano? Sí, y debe poder. La práctica habitual es detectar intención (“quiero hablar con alguien”, o un lead caliente) y marcar la conversación para que un asesor la retome, silenciando al bot en ese hilo.

¿Funciona con otros modelos además de OpenAI? Sí. La arquitectura es la misma; solo cambias el cliente en el service. Puedes usar Claude, Gemini o un modelo open source autohospedado sin tocar el resto del flujo de WhatsApp.

Conclusión

Un agente de IA en WhatsApp deja de ser un lujo cuando entiendes que el primer mensaje de tu próximo cliente probablemente ya llegó y nadie lo respondió a tiempo. Con Laravel orquestando la Cloud API y OpenAI redactando, tienes un asistente que califica, responde y vende mientras tú haces otra cosa — y, a diferencia de un SaaS cerrado, conoce tu catálogo y vive en tu infraestructura.

Si quieres seguir construyendo:

¿Qué sería lo primero que dejarías que tu agente respondiera por ti en WhatsApp?

Compartir

Buscar

Etiquetas