Crear un Chatbot de WhatsApp con PHP, Mezzio y Twilio

July 07, 2021
Redactado por
Revisado por
Diane Phan
Twilion

Un Chatbot es una aplicación de software con la que una persona puede tener una conversación, ya sea por escrito o por voz. Dicho esto, su capacidad de tener una conversación suele variar bastante. Por ejemplo, algunos bots de chat solo pueden responder un conjunto limitado de preguntas específicas (a veces en orden fijo). Sin embargo, otros utilizan una combinación de inteligencia artificial (IA) y aprendizaje automático (ML) para interactuar casi como lo haría un ser humano.

En este tutorial, le mostraré cómo crear un pequeño y sencillo Chatbot con la API de Twilio para WhatsApp, el marco de Mezzio para PHP y la API del clima con el fin de obtener el pronóstico meteorológico actual para cualquier ciudad del mundo.

¿Cómo funcionará el Chatbot?

Antes de entrar y escribir el código, veamos rápidamente una descripción general de cómo funcionará el Chatbot. En esencia, la lógica del proyecto es la siguiente:

  1. Un usuario enviará un mensaje de WhatsApp a un número de teléfono de Twilio que contiene solo el nombre de una ciudad, como Brisbane, Tokio o San Diego.
  2. Twilio enviará este mensaje a nuestro Chatbot, el cual consulta la API del clima para el informe del clima actual de esa ciudad.
  3. Si la información del clima está disponible, el Chatbot enviará un mensaje de WhatsApp con un formato agradable, a través de Twilio, de vuelta al usuario. De lo contrario, hará saber al usuario que no se pudo recuperar ningún dato del clima.

El mensaje de WhatsApp que se envía de vuelta al usuario se asemejará al siguiente ejemplo. Tenga en cuenta que contiene el nombre de la ciudad, la región/el estado y el país, junto con la temperatura actual, la sensación térmica, el nivel de humedad y la velocidad y la dirección del viento. He intentado escribirlo casi como de forma humana.

In Brisbane (Queensland, Australia), today, it's 25 degrees celsius, but feels like 21, with a humidity of 42 percent. The wind is currently blowing at 12 km p/h from the SSE.

Hay más información sobre cómo funcionará el Chatbot, pero lo trataremos más adelante, a medida que avancemos en el código.

Requisitos del tutorial

Para seguir este tutorial, necesita los siguientes componentes:

  • PHP 7.4.
  • Una cuenta de Twilio gratuita. Si es nuevo en Twilio haga clic aquí para crear una cuenta gratuita ahora y reciba un crédito de USD 10 cuando se actualice a una cuenta paga.
  • Composer instalado globalmente.
  • ngrok. Usaremos esta práctica útil para conectar la aplicación PHP que se ejecuta en su sistema a una URL pública a la que Twilio pueda conectarse. Esto es necesario para la versión de desarrollo del Chatbot, ya que es probable que su computadora se encuentre detrás de un router o firewall, por lo que no es posible acceder directamente a ella a través de Internet. Si no tiene instalado ngrok, puede descargar una copia para Windows y utilizar los administradores de paquete de MacOS o Linux.
  • Un teléfono inteligente con un número de teléfono activo y la aplicación WhatsApp instalada.

Configurar el sandbox de Twilio para WhatsApp

Antes de comenzar a crear la aplicación, primero debe configurar el Sandbox de Twilio para WhastApp. El sandbox simplifica el proceso de desarrollo y de prueba de su aplicación. Una vez que se complete la aplicación, puede solicitar acceso de producción a su número de teléfono de Twilio, lo cual requiere aprobación mediante WhatsApp.

Desde su Consola de Twilio, haga clic en “Programmable Messaging” (Mensajería programable), luego haga clic en “Try it Out” (Probar) y finalmente haga clic en “Try WhatsApp” (Probar WhatsApp). Luego, estará en el Sandbox de Twilio para WhatsApp, donde verá el número del sandbox asignado a su cuenta y un código para entrar.

Twilio Sandbox

Con el fin de habilitar el sandbox para WhatsApp en su teléfono inteligente, envíe un mensaje de WhatsApp con el código asignado, que comienza con la palabra “entrar”, seguido de una frase de dos palabras generada aleatoriamente, al número asignado a su cuenta.

Poco después, debe recibir una respuesta de Twilio, la cual indica que su número de teléfono celular está conectado al sandbox y puede comenzar a enviar y recibir mensajes.

NOTA: Este paso debe repetirse para cualquier teléfono adicional que desee conectar a su sandbox.

Cree el Chatbot PHP

Inicie la aplicación

Ahora que tenemos configurado el Sandbox para WhatsApp y nuestra clave de API del clima, vamos a entrar y crear el Chatbot. Lo primero que debemos hacer es iniciar el núcleo de la aplicación. Lo haremos utilizando Mezzio Skeleton. Me encanta usarlo porque ahorra mucho tiempo y esfuerzo.

Ejecute los siguientes comandos en su terminal. Estos crearán una aplicación base en un nuevo directorio llamado whatsapp-weather-chatbot y se modificará.

composer create-project mezzio/mezzio-skeleton whatsapp-weather-chatbot
cd whatsapp-weather-chatbot

El proceso de arranque hará cinco preguntas. Las he enumerado a continuación, junto con mis respuestas recomendadas.

Pregunta

Respuesta recomendada

¿Qué tipo de instalación desea?

3 (Modular)

¿Qué contenedor desea utilizar para la inyección de dependencias?

2 (laminas-servicemanager)        

¿Qué enrutador desea utilizar?

2 (FastRoute)

¿Qué motor de plantilla desea utilizar?

n

¿Qué controlador de errores desea utilizar durante el desarrollo?

1 (Whoops)

Seleccione el archivo de configuración en el que desea inyectar “Laminas\Validator\ConfigProvider”:

Enter

¿Desea recordar esta opción para otros paquetes del mismo tipo? (S/n)

Y

NOTA: Si desea obtener más información sobre Mezzio, consulte Mezzio Essentials.

Instale las dependencias necesarias

Ahora que la aplicación base está lista, debemos instalar las dos dependencias necesarias:

  • SDK PHP de Twilio: Para que podamos comunicarnos con Twilio.
  • PHP dotenv: Para que podamos cargar credenciales desde el entorno y no almacenarlas en código.

Ejecute el siguiente comando para instalarlas:

composer require twilio/sdk vlucas/phpdotenv

Registre y cargue las variables de entorno

Lo siguiente que debemos hacer es registrar nuestra única variable de entorno, que es la clave de API del clima. Para hacerlo, cree un archivo con el nombre .env en el directorio raíz de la aplicación. En ese caso, pegue el código que aparece a continuación

WEATHERAPI_API_KEY=<Your WeatherAPI API Key>

A continuación, inicie sesión en la API del clima y haga clic en “My Account”  (Mi cuenta) en la esquina superior derecha. En My Account Dashboard (Panel de control de mi cuenta), seleccione y copie la clave de API, la encontrará junto a “API Key:” (Clave de API) y péguela en .env en lugar de <Your WeatherAPI API Key>.

NOTA: Tenga cuidado de no seleccionar también el texto en verde (“LIVE”) (VIVO) junto a la tecla. Yo mismo lo hice la primera vez por error.

Con .env actualizado, habilite PHP dotenv en el proyecto para que se lea .env y cargue la clave API del clima incluida en el archivo $_ENV superglobal de PHP. Para hacerlo, vaya a public/index.php y agregue el código que aparece a continuación después de require 'vendor/autoload.php';.

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->safeLoad();

Escriba la lógica del Chatbot

Con todo ya configurado, prestemos atención a la lógica del Chatbot. No la he incluido directamente en el tutorial, ya que es algo larga y preferiría avanzar paso a paso. De esa manera, puede concentrarse en cada parte.

Sin embargo, antes de hacerlo, reemplace el código en src/App/src/Handler/HomePageHandler.php por el código en GitHub. Luego, vamos al paso a p

En la parte superior del método HomePageHandler’s handle, se encuentra el código que aparece a continuación.

$body = $request->getParsedBody()['Body'];
$response = new MessagingResponse();
$weatherData = $this->getWeatherData($body);

Comienza por recuperar el cuerpo de la solicitud POST, que tiene el contenido del $_POST superglobal. Twilio enviará una solicitud con un elemento (Body) que contiene el mensaje de WhatsApp que envió el usuario. Por lo tanto, se inicializa una nueva variable ($body) con el valor del elemento “Body” (Cuerpo).

Luego, inicializa un objeto MessagingResponse ($response) que usaremos en el método. Los objetos MessagingResponse simplifican el proceso de generación de los mensajes de TwiML. Si no está familiarizado con TwiML (Twilio Markup Language):

Se trata de un conjunto de instrucciones que puede utilizar para decirle a Twilio lo que debe hacer cuando recibe una llamada entrante, un SMS o un fax.

Como verá más adelante, es un superconjunto de XML. Utilizamos TwiML para decirle a Twilio que envíe un mensaje de WhatsApp al usuario.

Luego, se llama a un pequeño método de utilidad getWeatherData. Este método consulta la API del clima para los datos de la ciudad y su clima que el usuario envió en su mensaje de WhatsApp. Separé esta funcionalidad en un método de utilidad solo para que sea un poco más fácil enfocarse en ella.

private function getWeatherData(string $city): object
{
    $queryString = http_build_query([
        'key' => $_ENV['WEATHERAPI_API_KEY'],
        'q' => $city,
    ]);
    $requestUri = sprintf(
        '%s?%s',
        'https://api.weatherapi.com/v1/current.json',
        $queryString
    );

    $fh = fopen($requestUri, 'rb');
    $weatherData = json_decode(stream_get_contents($fh));
    fclose($fh);

    return $weatherData;
}

El método se utiliza http_build_query para crear la cadena de consulta de la solicitud ($queryString). Solo hemos pasado dos argumentos al método, ya que la API del clima solo tiene dos argumentos obligatorios:

  • key: Esta es su clave de API. Estamos recuperando esto del superglobal de PHP $_ENV, que inició PHP dotenv.
  • q: Esta es la ciudad para la cual desea recibir los datos del clima.

El URI de solicitud ($requestUri) se inicializa después de que se crea la cadena de consulta. Esto nos permite realizar una solicitud a la API del clima mediante el contenedor de transmisión HTTP/S de PHP (a través de una combinación de llamadas a fopen y stream_get_contents).

Las respuestas, tanto correctas como de error, están en formato JSON. Por ello, se utiliza json_decode para crear un objeto PHP a partir de la respuesta ($weatherData), que se devuelve del método.

NOTA: Si no está muy familiarizado con las transmisiones de PHP, especialmente su contenedor de transmisión HTTP/S, consulte este artículo sobre las formas de realizar solicitudes HTTP en PHP.

A continuación, puede ver un ejemplo de una respuesta correcta. Contiene todos los detalles que probablemente esperaría ver, incluida la temperatura tanto en Celsius como en Fahrenheit, las condiciones meteorológicas generales, la velocidad del viento en kilómetros y millas por hora, la dirección del viento, la presión atmosférica, el nivel de humedad, la cobertura de nubes y la visibilidad:

{
  "location": {
    "name": "London",
    "region": "City of London, Greater London",
    "country": "United Kingdom",
    "lat": 51.52,
    "lon": -0.11,
    "tz_id": "Europe/London",
    "localtime_epoch": 1624971055,
    "localtime": "2021-06-29 13:50"
  },
  "current": {
    "last_updated_epoch": 1624970700,
    "last_updated": "2021-06-29 13:45",
    "temp_c": 17,
    "temp_f": 62.6,
    "is_day": 1,
    "condition": {
      "text": "Overcast",
      "icon": "//cdn.weatherapi.com/weather/64x64/day/122.png",
      "code": 1009
    },
    "wind_mph": 6.9,
    "wind_kph": 11.2,
    "wind_degree": 360,
    "wind_dir": "N",
    "pressure_mb": 1015,
    "pressure_in": 30.4,
    "precip_mm": 0.3,
    "precip_in": 0.01,
    "humidity": 72,
    "cloud": 100,
    "feelslike_c": 17,
    "feelslike_f": 62.6,
    "vis_km": 10,
    "vis_miles": 6,
    "uv": 4,
    "gust_mph": 7.8,
    "gust_kph": 12.6
  }
}

Y el siguiente ejemplo muestra lo que se envía de vuelta para una solicitud fallida, como cuando la ciudad no se puede identificar o los datos meteorológicos para esa ciudad no están disponibles.

{
    "error": {
        "code": 1006,
        "message": "No matching location found."
    }
}

Independientemente de la respuesta recibida, el Chatbot primero comprueba si la respuesta fue fallida. Si es así, llama al método $response's message a fin de establecer el cuerpo del mensaje, iniciándolo para el mensaje de error que se devolvió desde la API del clima.

A continuación, se utiliza XmlResponse para enviar una respuesta XML completa con un encabezado de tipo de contenido application/xml; charset=utf-8 y TwiML generado como el cuerpo de respuesta.

if (property_exists($weatherData, 'error')) {
    return new XmlResponse(
        (string)$response->message($weatherData->error->message)
    );
}

Sin embargo, si la respuesta fue correcta, se genera un mensaje TwiML que utiliza sprintf para componer la cadena, extrayendo los detalles relevantes de los datos meteorológicos devueltos.

$responseString = <<<EOF
In %s (%s, %s), today, it's %d degrees celsius, but feels like %d, with a humidity of %d percent. The wind is currently %d km/h from the %s.
EOF;
$response->message(
    sprintf(
        $responseString,
        $weatherData->location->name,
        $weatherData->location->region,
        $weatherData->location->country,
        $weatherData->current->temp_c,
        $weatherData->current->feelslike_c,
        $weatherData->current->humidity,
        $weatherData->current->wind_kph,
        $weatherData->current->wind_dir
    )
);

return new XmlResponse((string)$response);

A continuación, se muestra un ejemplo de cómo será el mensaje devuelto.

In Brisbane (Queensland, Australia), today, it's 25 degrees celsius, but feels like 21, with a humidity of 42 percent. The wind is currently blowing at 12 km p/h from the SSE.

Inicie el Chatbot

Es hora de iniciar el Chatbot. Inicie la aplicación escuchando en el host local, en el puerto 8080. Para simplificar este proceso, utilizaremos un script del Composer definido en composer.json mediante el comando que se muestra a continuación:

composer serve

En una ventana independiente, inicie ngrok ejecutando el comando que aparece a continuación.

ngrok http 8080

NOTA: Recomiendo una ventana independiente, ya que puede ver qué están haciendo ambos procesos, lo cual es útil si tiene que realizar alguna depuración.

ngrok running

Después de que se inicie ngrok, copie la URL de reenvío https. Esta es la URL pública que utiliza ngrok para redirigir las solicitudes a nuestro servicio. Vuelva a la Consola de Twilio, haga clic en Programmable Messaging (Mensajería programable) y, a continuación, seleccione Settings (Configuración). Busque la configuración de Sandbox para WhatsApp en la barra lateral.

Sandbox configuration

Pegue la URL en el campo When a message comes in (Cuando entre un mensaje) y establezca el método de solicitud en “HTTP Post”. A continuación, haga clic en el botón azul “Save” (Guardar) en la parte inferior de la página para que los cambios sean permanentes.

¡Pruebe el Chatbot!

Ahora, podemos probar nuestro Chatbot. Abra WhatsApp en su teléfono y envíe un mensaje a su número de Twilio con el nombre de la ciudad para la que desea obtener el informe del clima. A continuación, debería ver una respuesta similar a la que aparece en WhatsApp.

Whatsapp sandbox

Crear un Chatbot de WhatsApp con PHP, Mezzio y Twilio

Las empresas y organizaciones de todos los tamaños utilizan cada vez más los bots de chat para agilizar las ventas, el marketing y apoya las interacciones con los clientes existentes y potenciales, ya que pueden ser una forma rápida y eficiente de empezar la conversación antes de que un humano tenga que involucrarse.

Si desea profundizar en lo que es posible al crear un Chatbot, consulte estos artículos:

Me encantaría ver el Chatbot que va a construir.

Matthew Setter es un redactor de PHP en el equipo Twilio Voices y (naturalmente) un desarrollador de PHP. También es autor de Mezzio Essentials y Docker Essentials. Cuando no está escribiendo código PHP, está escribiendo grandes artículos de PHP aquí en Twilio. Puede encontrarlo en msetter@twilio.com; también es @settermjd en Twitter y GitHub.

Este artículo ha sido traducido del original "Build a WhatsApp Chatbot with PHP, Mezzio, and Twilio". Mientras continuamos con los procesos de traducción, nos encantaría recibir sus comentarios en help@twilio.com - Buenas contribuciones pueden generar regalos de Twilio.