https://d226lax1qjow5r.cloudfront.net/blog/blogposts/send-greek-unicode-viber-messages-with-symfony/greek-unicode-viber-messages-symfony.png

Enviar mensajes Viber Unicode griego con Symfony

Publicado el January 15, 2024

Tiempo de lectura: 12 minutos

Me encanta la naturaleza aleatoria de las cosas que descubres en la Defensa del Desarrollador. Este hallazgo en concreto surgió de una conversación que mantuve en la Conferencia We Are Developers de Berlín este año. Resulta que los mensajes oficiales del Gobierno griego se envían a través de ViberAccount, que representa una cuota significativa del 4,55% del mercado de mensajería móvil. Se me iluminó la bombilla: Vonage admite Viber en la Messages APIasí que ¿por qué no mostrar un ejemplo de envío de un mensaje Unicode usando PHP a un dispositivo Viber? Y eso, lector, es exactamente lo que vamos a hacer, totalmente desde cero.

Vamos a utilizar el Framework Symfony para este tutorial, pero en lugar de seguir el proceso de instalación descrito en los documentos de Symfony, he tomado un enfoque ligeramente diferente. Neal Brooks me ayudó creando este repositorio que arrancará un framework completo con un solo comando.

Primeros pasos

Pongámonos manos a la obra y arranquemos primero la aplicación. Como estamos usando Docker para esto, necesitarás tener Docker instalado para tu plataforma primeroy tendrás que tener git version control instalado. Otro paso necesario (que será más relevante para los usuarios de Windows que para los entornos Linux o Mac) es asegurarse de que GNU Make está instalado.

Clone el siguiente repositorio desde su línea de comandos:

git clone https://github.com/nealio82/symfony-starter-kit

Ahora usamos make para crear la aplicación:

make create-webapp

El comando hará dos cosas:

  • Descarga e instala todas las dependencias de la última versión de Symfony, que se encuentra en la carpeta app (ahora es el código fuente de tu aplicación)

  • Arranca el entorno Docker usando docker compose up que traerá el contenedor Symfony PHP ejecutando PHP8.2, Postgres, Node, y Nginx como la elección del servidor web.

Porque vamos a ser super perezoso, también vamos a utilizar un comando para abrir nuestra aplicación en el navegador:

make open-web

Splash screen of Symfony applicationWelcome to Symfony!

Instalar las dependencias y configurar

¡Ya estamos! Ahora a empezar a desarrollar. Lo primero que haremos es agregar el Vonage PHP SDK como dependencia de la aplicación Symfony, usando Composer. Podemos usar el makefile para hacer esto dentro del contenedor PHP.

make composer require vonage/client-core

Lo que vamos a hacer con la aplicación es burlarse de un webhook entrante a través de una ruta expuesta, a continuación, enviar el mensaje dentro de esa carga útil a un número a través de Viber. Hay un par de pasos necesarios para que esto funcione: en primer lugar, usted necesitará un Account de Vonage.

A continuación, debemos crear una aplicación de Vonage con capacidad para mensajes. Podemos hacerlo a través de Vonage Dashboard :

Screenshot of application creation in the Vonage DashboardCreating an Application in the Vonage Dashboard

No te preocupes por los webhooks de Mensajes para las URLs de Entrada - no estamos interesados en obtener ni devoluciones de llamada de estado ni mensajes de Entrada para los propósitos de este artículo. Al crear la aplicación, puedes poner URLs ficticias en la configuración del webhook, ya que son campos obligatorios.

Las piezas más importantes que necesitarás son:

  • ID de su solicitud

  • El sitio private.key descargado desde el botón Generate public and private key de este tablero, y se colocan en la carpeta raíz de Symfony (es decir app)

Después de haber pulsado 'Generar aplicación', necesitamos la capacidad de obtener nuestra configuración utilizando el Config Builder de Symfony. Los configuraremos como parámetros, ya que es la forma más sencilla de obtener los valores globales de la aplicación.

Crea un nuevo archivo, vonage.yamly colóquelo en app/config/packages. Dentro de este archivo, pondremos nuestras claves:

parameters:  
  application_id: '99996908-65ec-XxXx-a640-f5f4a999a3b9'  
  private_key_path: '%kernel.project_dir%/private.key'

Asegúrate de reemplazar el valor ficticio que proporcioné para application_id con el valor correcto de la aplicación de Vonage que generaste a través del panel de control. Una vez definidos estos parámetros, podrás acceder a sus valores desde cualquier parte de Symfony utilizando la función ParameterBag (más sobre esto más adelante).

Uso del Sandbox de Mensajes

Mientras tenemos el Panel abierto, configuraremos la Account que vamos a utilizar para usar la plataforma Viber Business Messages. En lugar de pasar por el proceso de configuración de su propia cuenta de Viber Business Messages, utilizaremos una cuenta preaprovisionada disponible para su uso en el entorno de pruebas de Mensajes Sandbox.

Antes de configurar Sandbox, necesitará tener la aplicación aplicación Viber instalada en su teléfono. Descarga la aplicación y sigue el proceso completo.

El siguiente paso es permitir el número asociado a su Account de Viber para el Sandbox de Mensajes. Para ello, vaya a Buzón de Mensajes en el Panel de control. Puede navegar hasta allí utilizando el menú a través de Solucionar problemas y aprender > Herramientas de desarrollador > Buzón de arena de mensajes. Haga clic en el enlace "Añadir a Sandbox" en la tarjeta de Viber, y siga las instrucciones que se dan allí para permitir la lista de su número para la cuenta de Sandbox Viber. Como estamos usando la cuenta del entorno de pruebas preaprovisionada, la marca Vonage estará presente en los mensajes de esa cuenta.

Enrutamiento

Ahora que la cuenta Sandbox está configurada, vamos a crear la ruta en Symfony que activará el mensaje. Vamos a hacer esto dentro del contenedor Docker (esto es siempre y cuando estés un nivel por encima del directorio app directorio donde se encuentra todo el código fuente):

./app/bin/console make:controller

Aquí se te pedirá que nombres tu controlador. Llamémoslo MessengerController. La consola hará el resto por ti, puedes verlo en el código que genera:

namespace App\Controller;  
  
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;  
use Symfony\Component\HttpFoundation\Response;  
use Symfony\Component\Routing\Annotation\Route;  
  
class MessengerController extends AbstractController  
{  
    #[Route('/messenger', name: 'app_messenger')]  
    public function index(): Response  
    {  
        return $this->render('messenger/index.html.twig', [  
            'controller_name' => 'MessengerController',  
        ]);    
	}
}        

Ya puedes acceder a la nueva ruta desde tu navegador:

Screenshot of the default Symfony contoller template pageSymfony's default controller template

Nuestra ruta se va a comportar más como una ruta API REST que como una ruta de aplicación web. Por lo tanto, tenemos que especificarlo como un POST y hacer que devuelva JSON. Vamos a actualizar el código para hacer eso:

#[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')] 
public function index(): Response  
{ 
    return new JsonResponse(['message_success' => true]);  
}

Aquí han cambiado tres cosas para obtener una respuesta:

  • La anotación Route ha cambiado, para permitir POST únicamente.

  • La anotación Route también especifica ahora que sólo application/json pueden enviarse a este punto final

  • Ahora devolvemos un JsonResponse objeto.

Ahora puede intentar acceder al punto final con una herramienta de prueba de API como Postman. En este caso, he optado por utilizar Insomnia:

Screenshot of Insomina sending a POST requestUsing Insomnia to test our Application

Bien, tenemos un ciclo de vida petición/respuesta que funciona. Excelente. Es hora de armar el resto del rompecabezas.

Te habrás dado cuenta de que estamos enviando un message en la carga JSON y, como prometimos, ¡está en griego Unicode! Así que lo primero que tenemos que hacer es extraer esa cadena. Usando la inyección de dependencias de Symfony, vamos a añadir el objeto Request en el método del controlador, lo que nos dará acceso a toda la petición:

use Symfony\Component\HttpFoundation\Request;

#[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')] 
public function index(Request $request): Response  
{ 
    return new JsonResponse(['message_success' => true]);  
}

Ahora, podemos extraer una clave de la carga útil de la solicitud llamada message:

use Symfony\Component\HttpFoundation\Request;

#[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')] 
public function index(Request $request): Response  
{ 
	$message = $request->getPayload()->get('message');
	
    return new JsonResponse(['message_success' => true]);  
}

Usar Vonage

Ya tenemos el mensaje y la solicitud/respuesta configurados. Es hora de incluir el PHP SDK de Vonage en nuestro controlador, configurando el cliente base con las credenciales que establecimos en la configuración de Symfony. Usamos un objeto llamado ParameterBag para sacar estas credenciales. Para acceder a esta clase, inyéctala en el constructor del controlador:

public function __construct(  
    protected ParameterBagInterface $parameterBag,  
) {}

Ahora puede acceder mediante $this->parameterBag. Saquemos lo que necesitamos:

use Symfony\Component\HttpFoundation\Request;

#[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')] 
public function index(Request $request): Response  
{ 
	$message = $request->getPayload()->get('message');

	$privateKey = file_get_contents($this->parameterBag->get('private_key_path'));
	$applicationId = $this->parameterBag->get('application_id');
	
    return new JsonResponse(['message_success' => true]);
}

Ahora que tenemos los dos parámetros necesarios para nuestras credenciales de Vonage, podemos utilizarlos como argumentos para crear un objeto Vonage\Credentials\Keypair y, posteriormente, pasar ese objeto al instanciar un nuevo Vonage Client:

use Symfony\Component\HttpFoundation\Request;

#[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')] 
public function index(Request $request): Response  
{ 
	$message = $request->getPayload()->get('message');

	$privateKey = file_get_contents($this->parameterBag->get('private_key_path'));
	$applicationId = $this->parameterBag->get('application_id');
	
	$vonageCredentials = new Client\Credentials\Keypair($privateKey, $applicationId);  
  
	$client = new Client(  
		$vonageCredentials,  
		[
			'base_api_url' => 'https://messages-sandbox.nexmo.com'  
	    ]  
	);
	
    return new JsonResponse(['message_success' => true]);
}

Un paso importante a tener en cuenta aquí es que el Client está tomando una opción adicional, base_api_url. Esto anula la configuración de la URL base incorporada en el SDK, y lo hace para que pueda utilizar el sandbox de Messages API.

Es hora de crear el mensaje de Viber. Deberás usar un from número que se te muestra en el panel de Vonage. Puedes ver este número si te desplazas hacia abajo en la página Messages Sandbox:

Screenshot of the Messages Sandbox documentationYou can see the correct 'from' field here

Este número se utiliza al crear el objeto ViberText objeto:

$messageText = 'Καλώς ήρθατε στο Vonage στα Ελληνικά!'
$vonageMessage = new ViberText('44999999999', '22353', $messageText);

Lo último que hay que hacer es enviar el mensaje, pero sería preferible hacer que la clave JSON de retorno message_success sea precisa y defensiva. Por lo tanto, aquí está el resultado final, en su totalidad:

namespace App\Controller;  
  
use Psr\Log\LoggerInterface;  
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;  
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;  
use Symfony\Component\HttpFoundation\JsonResponse;  
use Symfony\Component\HttpFoundation\Request;  
use Symfony\Component\HttpFoundation\Response;  
use Symfony\Component\Routing\Annotation\Route;  
use Vonage\Client;  
use Vonage\Messages\Channel\Viber\ViberText;  
  
class MessengerController extends AbstractController  
{  
    public function __construct(  
        protected ParameterBagInterface $parameterBag,  
        protected LoggerInterface $logger  
    ) {}  
  
    #[Route('/messenger', name: 'app_messenger', methods: ['POST'], format: 'json')]  
    public function index(Request $request): Response  
    {  
        $messageText = $request->getPayload()->get('message');  
        $responseData = ['message_success' => false];  
  
		$privateKey = file_get_contents($this->parameterBag->get('private_key_path'));
		$applicationId = $this->parameterBag->get('application_id');
	
		$vonageCredentials = new Client\Credentials\Keypair($privateKey, $applicationId);  
  
		$client = new Client(  
			$vonageCredentials,  
			[
				'base_api_url' => 'https://messages-sandbox.nexmo.com'  
		    ]  
		);
        
        $vonageMessage = new ViberText('44999999999', '22353', $messageText);  
  
        try {  
            $client->messages()->send($vonageMessage);  
            $responseData['message_success'] = true;  
        } catch (\Exception $exception) {  
            $this->logger->error($exception->getMessage());  
        }
        
        return new JsonResponse($responseData);  
    }
}

Hay un par de cosas que repasar con el código final. En primer lugar, el requisito de código defensivo significa que hemos introducido un bloque try-catch. Pero, ¿qué hacemos si falla aparte de enviar false para que el cliente sepa que el resultado ha fallado? Bueno, podemos registrar la respuesta de error. Esto se ha hecho utilizando la inyección de dependencias de Symfony para añadir el bloque Logger a la clase controladora a través del constructor. En este caso, Symfony viene con el conocido Monolog configurado out of the box por lo que podemos el LoggerInterface aquí.

Vuelve a hacer la petición en Insomina y...

Screenshot of a Viber app on a mobile device showing the Greek messageGreek Viber Messages!

¡Mágico! ¡Tenemos un mensaje en griego en Viber!

Conclusión

El uso del SDK PHP de Vonage está diseñado para que el tiempo de desarrollo sea superrápido y, junto con el rápido tiempo de desarrollo que ofrece Symfony Framework, se obtiene un poderoso conjunto de herramientas en tus manos. Si estás creando algo y necesitas ayuda u orientación, avísanos registrándote en nuestra Comunidad Slack.

Recursos adicionales

Envío de SMS desde PHP con Failover: La pastelería Cupcake

Seguridad Tipográfica Bien Hecha - PHP Array Hacking

¡Limpiar! Limpieza de Aplicaciones PHP con PHPStan

SDK PHP de Vonage

Compartir:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor senior de desarrollo PHP

Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.