https://a.storyblok.com/f/270183/52613/393954b18e/greek-unicode-viber-messages-symfony.png

Envie mensagens no Viber em grego com Unicode usando o Symfony

Publicado em January 15, 2024

Tempo de leitura: 12 minutos

Adoro a natureza aleatória das coisas que a gente descobre no trabalho de Developer Advocacy. Essa descoberta em particular surgiu de uma conversa que tive na conferência We Are Developers, em Berlim, este ano. Acontece que as mensagens oficiais do governo grego são enviadas usando o Viber, o que representa uma participação significativa de 4,55% no mercado de mensagens móveis. Tive um momento de inspiração: a Vonage oferece suporte ao Viber na Messages API; então, por que não mostrar um exemplo de envio de uma mensagem Unicode usando PHP para um dispositivo Viber? E é exatamente isso, caro leitor, que vamos fazer, do zero.

Vamos usar o Framework Symfony para este tutorial, mas, em vez de seguir o processo de instalação descrito na documentação do Symfony, adotei uma abordagem um pouco diferente. Neal Brooks me ajudou criando este repositório que inicializa o framework completo com um único comando!

Introdução

Vamos direto ao ponto e iniciar o aplicativo primeiro. Como estamos usando o Docker para isso, você precisará ter o Docker instalado na sua plataforma primeiro, além de ter o controle de versão git instalado. Outra etapa necessária (que será mais relevante para usuários do Windows do que para ambientes Linux ou Mac) é garantir que o GNU Make esteja instalado.

Clone o seguinte repositório a partir da linha de comando:

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

Agora usamos make para compilar o aplicativo:

make create-webapp

O comando fará duas coisas:

  • Baixe e instale todas as dependências da versão mais recente do Symfony, que fica na app pasta (esse é o código-fonte da sua aplicação agora)

  • Inicialize o ambiente do Docker usando docker compose up o que iniciará o contêiner Symfony PHP, executando o PHP 8.2, o Postgres, o Node e o Nginx como servidor web.

Porque vamos estar super preguiçosos, também vamos usar um comando para abrir nosso aplicativo no navegador:

make open-web

Splash screen of Symfony applicationWelcome to Symfony!

Instale as dependências e configure

Já estamos no ar! Agora é hora de começar a desenvolver. A primeira coisa que vamos fazer é adicionar o SDK do Vonage para PHP como uma dependência do aplicativo Symfony, usando o Composer. Podemos usar o makefile para fazer isso dentro do contêiner PHP.

make composer require vonage/client-core

O que vamos fazer com o aplicativo é simular um webhook recebido por meio de uma rota exposta e, em seguida, enviar a mensagem contida nessa carga para um número pelo Viber. São necessárias algumas etapas para que isso funcione: primeiro, você precisará de uma Account na Vonage.

Em seguida, precisamos criar uma Application da Vonage com a funcionalidade de mensagens. Podemos fazer isso pelo Painel de Controle da Vonage:

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

Não se preocupe com os webhooks de Mensagens para URLs de entrada — não estamos interessados em receber nem callbacks de status nem mensagens de entrada para os fins deste artigo. Ao criar o aplicativo, você pode inserir URLs fictícias na configuração do webhook, já que esses são campos obrigatórios.

As peças mais importantes de que você vai precisar são:

  • Seu ID de inscrição

  • O private.key baixado do Generate public and private key botão neste painel e colocado na pasta raiz do Symfony (ou seja, app)

Depois de clicar em “Gerar Aplicativo”, precisamos poder obter nossa configuração usando o Config Builder do Symfony. Vamos configurá-los como parâmetros, pois essa é a forma mais simples de extrair os valores globais do aplicativo.

Crie um novo arquivo, vonage.yamle salve-o em app/config/packages. Dentro desse arquivo, vamos colocar nossas chaves:

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

Certifique-se de substituir o valor fictício que forneci para application_id pelo valor correto da Application da Vonage que você gerou pelo painel de controle. Com esses parâmetros definidos, você poderá acessar seus valores de qualquer lugar no Symfony usando o ParameterBag (mais detalhes sobre isso adiante).

Como usar o ambiente de testes do Messages

Enquanto o Painel de Controle estiver aberto, vamos configurar a conta que usaremos para acessar a plataforma Viber Business Messages. Em vez de passar pelo processo de criação de sua própria conta no Viber Business Messages, usaremos uma conta pré-configurada disponível para uso na Sandbox do Messages.

Antes de configurar o Sandbox, você precisará ter o aplicativo do Viber instalado no seu celular. Baixe o aplicativo e siga todo o processo.

O próximo passo é adicionar o número associado à sua conta do Viber à lista de permissões do Messages Sandbox. Para fazer isso, acesse a Messages Sandbox no Painel. Você pode acessá-lo pelo menu, em Solucionar problemas e aprender > Ferramentas para desenvolvedores > Messages Sandbox. Clique no link “Adicionar ao Sandbox” no cartão do Viber e siga as instruções fornecidas para incluir seu número na lista de permissões da conta do Viber no Sandbox. Como estamos usando a conta do Sandbox pré-configurada, a marca da Vonage aparecerá nas mensagens enviadas por essa conta.

Roteamento

Agora que a conta do Sandbox está configurada, em seguida vamos criar a rota no Symfony que acionará a mensagem. Faremos isso dentro do contêiner do Docker (desde que você esteja um nível acima do app diretório onde todo o código-fonte está localizado):

./app/bin/console make:controller

Aqui, você receberá uma solicitação para nomear seu controlador. Vamos chamá-lo de MessengerController. O console vai gerar o restante automaticamente para você; você pode ver isso no código que ele gera:

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',  
        ]);    
	}
}        

Você já pode acessar a nova rota pelo seu navegador:

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

Nossa rota vai funcionar mais como uma rota de API REST do que como uma rota de aplicativo web. Portanto, precisamos defini-la como um POST ponto de extremidade e fazer com que ela retorne algum JSON. Vamos atualizar o código para fazer isso:

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

Três coisas foram alteradas aqui para que houvesse uma resposta:

  • A anotação “Route” foi alterada para permitir POST apenas solicitações.

  • A anotação Route agora também especifica que apenas application/json podem ser enviadas para este endpoint

  • Agora retornamos um JsonResponse objeto.

Agora você pode tentar acessar o endpoint com uma ferramenta de teste de API, como Postman. Aqui, optei por usar o Insomnia:

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

OK, já temos um ciclo de vida de solicitação/resposta que funciona. Excelente. É hora de montar o resto do quebra-cabeça.

Você deve ter notado que estamos enviando uma message na carga JSON — e, como prometido, está em Unicode grego! Então, primeiro o código está extraindo essa string. Usando a Injeção de Dependências do Symfony, vamos adicionar o Request objeto ao método do controlador, o que nos dará acesso à solicitação completa:

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]);  
}

Agora, podemos extrair uma chave da carga útil da solicitação chamada 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]);  
}

Como usar o Vonage

Então, já temos nossa mensagem e a solicitação/resposta configuradas. É hora de integrar o Client SDK PHP da Vonage ao nosso controlador, com o cliente base configurado com as credenciais que definimos na configuração do Symfony. Usamos um objeto chamado ParameterBag para obter essas credenciais. Para ter acesso a essa classe, injete-a no construtor do controlador:

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

Agora você pode acessar isso usando $this->parameterBag. Vamos extrair o que precisamos:

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]);
}

Agora que temos os dois parâmetros necessários para nossas credenciais da Vonage, podemos usá-los como argumentos para criar um Vonage\Credentials\Keypair objeto e, posteriormente, passar esse objeto ao instanciar um novo objeto da 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]);
}

Um ponto importante a se observar aqui é que o Client está aceitando uma opção adicional, base_api_url. Isso substitui as configurações de URL base integradas ao SDK, permitindo que você utilize a sandbox da Messages API.

É hora de criar a mensagem no Viber. Você precisará usar um from número que aparece no Painel de Controle da Vonage. Você pode ver esse número se rolar a página para baixo na seção “Sandbox de Mensagens”:

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

Utilizamos esse número ao criar o ViberText objeto:

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

A última coisa a fazer é enviar a mensagem, mas seria preferível definir a chave JSON de retorno message_success seja precisa e segura. Então, aqui está o resultado final, na íntegra:

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);  
    }
}

Há alguns pontos a serem analisados no código final. Em primeiro lugar, a exigência de código defensivo significa que introduzimos um bloco try-catch. Mas, o que fazemos se houver uma falha, além de enviar false informar ao cliente que a operação falhou? Bem, podemos registrar a resposta de erro. Isso foi feito usando a Injeção de Dependências do Symfony para adicionar a Logger à classe do controlador por meio do construtor. Nesse caso, o Symfony já vem com a conhecida Monolog já configurado de fábrica, de modo que você pode usar o LoggerInterface aqui.

Envie o pedido no Insomina de novo e...

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

Mágico! Temos uma mensagem de localização em grego no Viber!

Conclusão

O uso do SDK PHP da Vonage foi projetado para tornar o tempo de desenvolvimento extremamente rápido e, aliado à agilidade de desenvolvimento oferecida pelo Symfony Framework, proporciona um conjunto poderoso de ferramentas à sua disposição. Se você estiver desenvolvendo algo e precisar de ajuda ou orientação, entre em contato conosco se cadastrando no nosso Slack da Comunidade.

Recursos adicionais

Envio de SMS a partir do PHP com failover: A Padaria Cupcake

Segurança de tipos bem feita — Hacking de arrays em PHP

Mãos à obra! Como limpar seu aplicativo PHP com o PHPStan

SDK do Vonage para PHP

Compartilhar:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor Sênior de Desenvolvimento em PHP

Sou ator formado, com uma dissertação sobre stand-up comedy, e comecei a me dedicar ao desenvolvimento em PHP por meio dos encontros da comunidade. Você pode me encontrar dando palestras e escrevendo sobre tecnologia, ou ouvindo e comprando discos curiosos da minha coleção de vinil.