
Compartilhar:
Software Developer who loves building awesome tools and products. I currently work with Laravel, PHP and Vue.
Notificação de incidentes com o PagerDuty e a Vonage
Tempo de leitura: 8 minutos
Aviso sobre descontinuação de produto A partir de 31 de agosto de 2025, a Dispatch API será encerrada para novos usuários, embora o produto continue a receber suporte para os usuários existentes. Se você pretende desenvolver um aplicativo de mensagens com funcionalidade de failover, saiba que essa funcionalidade agora é suportada diretamente na Messages API.
Para obter informações gerais sobre o recurso de failover de mensagens, consulte este guia. Para obter orientações sobre a migração da Dispatch API para a Messages API Failover, consulte este guia.
Caso tenha mais alguma dúvida sobre a descontinuação deste produto, por favor, entre em contato conosco no Slack da Comunidade Vonage.
Introdução
O PagerDuty é um sistema de gerenciamento de relatórios de incidentes que oferece notificações e escalações automáticas para ajudar as equipes de engenharia a detectar e resolver problemas à medida que eles surgem em sua infraestrutura. Nesta postagem, veremos como podemos usar o Vonage para alertar os membros de uma equipe de engenharia sempre que ocorrer um incidente em qualquer parte de sua infraestrutura.
Usando a Dispatch API do Vonage, que oferece uma opção de failover automático, enviaremos primeiro as notificações pelo Facebook Messenger como meio principal e, em seguida, por SMS como opção alternativa.
Requisitos técnicos
Para acompanhar, você precisará do seguinte:
PHP versão 7.1 ou superior
Laravel 5.8
Ngrok que permite expor seu servidor web local à internet. Para saber mais sobre como configurar seu ambiente local com o Ngrok, você pode consultar a documentação aqui.
A Facebook Account
A PagerDuty Account
Configuração
Para poder usar a Dispatch API, precisamos realizar algumas ações em nossa conta da Vonage. Acesse o painel da Vonage e, na seção “Mensagens e Dispatch”, crie um novo aplicativo de mensagens.
new message app in dashboard
\
A URL de status é o endpoint do webhook para o qual a Vonage enviará uma solicitação POST sempre que enviarmos notificações por SMS. Isso nos permitirá determinar a atualização do status do SMS enviado, ou seja, se foi entregue, rejeitado ou enviado. Como usaremos o Ngrok, a URL de status deve ser algo como isto
qc43v7.ngrok.io/webhooks/status.A URL de entrada é o endpoint para o qual a Vonage enviará uma solicitação sempre que forem recebidas mensagens de entrada e deve ter um formato semelhante a este
qc43v7.ngrok.io/webhooks/inbound-messageEm seguida, gere um par de chaves pública e privada. Isso fará com que o arquivo da chave privada também seja baixado automaticamente. Anote esse arquivo, pois precisaremos dele em breve.
Crie o aplicativo e anote o ID do aplicativo. Em seguida, será solicitado que você associe números e contas externas a esse aplicativo. Isso é totalmente opcional; portanto, você pode simplesmente aceitar as configurações padrão e criar o aplicativo.
Configurando o PagerDuty
Acesse PagerDuty e crie um Account, caso ainda não tenha um. Também precisaremos criar um Serviço. Um Serviço no PagerDuty representa qualquer coisa em relação à qual gostaríamos de abrir incidentes. Pode ser um aplicativo, um componente ou até mesmo uma equipe. Assim, sempre que ocorrer um novo incidente nesse Serviço, queremos enviar notificações via webhook para um endpoint específico em nosso aplicativo.
No seu painel do PagerDuty, acesse Configuração -> Serviços e crie um novo serviço.
pager duty dashboard
Como vamos utilizar nossa própria integração personalizada, selecione “Usar nossa API diretamente” como tipo de integração e, em seguida, selecione Events API V2 e preencha todos os outros detalhes necessários. Você pode ler mais sobre como criar um serviço no PagerDuty aqui.
Em seguida, depois de criar o serviço com sucesso, na guia “Integrações”, selecione “Nova extensão” e, em seguida, defina o tipo como Generic V2 webhook. A seção de detalhes consistirá no endpoint em nosso aplicativo onde queremos receber notificações do PagerDuty e deve ser algo como qc43v7.ngrok.io/webhooks/incident
pager duty
Configurando o Laravel
Usaremos o Composer para instalar um novo projeto Laravel. Na linha de comando, crie um novo projeto Laravel usando o seguinte comando:
Rotas e controlador
Edite o routes/web.php com o seguinte código:
<?php
Route::post('/webhooks/inbound-message', 'WebhookController@inboundMessage');
Route::post('/webhooks/status', 'WebhookController@status');
Route::post('/webhooks/incident', 'WebhookController@report');O ataque de falsificação de solicitação entre sites (CSRF) é um tipo de ataque malicioso no qual comandos não autorizados são executados em nome de um usuário autenticado. Para evitar tais ataques, o Laravel gera automaticamente um Csrf token para cada usuário autenticado, o que ajuda a validar se o usuário autenticado é realmente quem está fazendo a solicitação à aplicação. No entanto, como essas solicitações virão de fora da aplicação e confiamos na fonte, precisamos desativar Csrf a validação para essas rotas. O VerifyCsrfToken middleware é usado para validar todos os tokens. Felizmente, o middleware aceita um except array que contém uma lista de todas as rotas nas quais a verificação de CSRF deve ser desativada.
Edite o app\Http\Middleware\VerifyCsrfToken.php arquivo com o seguinte código:
protected $except = [
'/webhooks/*'
];Em seguida, execute o comando a seguir para criar um controlador:
php artisan make:controller WebhookController Isso vai gerar um WebhookController.php arquivo para nós no app\Http\Controllers diretório. Edite o arquivo com o seguinte código:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Jobs\ReportIncident;
class WebhookController extends Controller
{
public function inboundMessage(Request $request)
{
return Log::debug('Inbound Message', $request->all());
}
public function status(Request $request)
{
return Log::debug('Status', $request->all());
}
public function report(Request $request)
{
Log::debug('Incident', $request->all());
dispatch(new ReportIncident());
return response('Webhook received');
}
}Para o inboundMessage() e status() métodos, simplesmente registramos os dados da solicitação da Vonage no arquivo de log fornecido pelo Laravel. O report() método aciona um ReportIncident tarefa que criaremos em breve. Essa tarefa é responsável por acionar notificações por SMS usando um wrapper personalizado em torno da API da Vonage.
Como vincular o Facebook ao seu Account da Vonage
Para conseguir enviar mensagens com sucesso do Vonage para o Facebook, você precisará primeiro vincular uma página do Facebook associada à sua conta do Facebook à sua conta do Vonage. Você pode saber como fazer isso aqui.
Quando terminar a vinculação, envie uma mensagem do seu Account do Facebook para a página do Facebook. Como se trata de uma mensagem recebida, a Vonage enviará uma solicitação contendo os detalhes da mensagem para o /webhooks/inbound-message ponto de extremidade que criamos anteriormente. Verifique seu arquivo de logs e você deverá ver uma entrada semelhante à seguinte:
Inbound Message{
"message_uuid":"0a2088d2-e028-4aa0-aa4a-ae11a6f82fb0",
"to":{
"id":"1923256201474167",
"type":"messenger"
},
"from":{
"id":"23037543461244470",
"type":"messenger"
},
"timestamp":"2019-08-06T21:56:16.887Z",
"direction":"inbound",
"message":{
"content":{
"type":"text",
"text":"Hello"
}
}
}O ID do remetente no Facebook é o to.id, enquanto o ID do destinatário é o from.id. Anote esses detalhes, pois precisaremos deles em breve.
Criação de um wrapper personalizado
Como a Dispatch API ainda está em fase beta no momento da redação deste tutorial, a biblioteca PHP da Vonage ainda não oferece suporte a ela. Por isso, usaremos um wrapper personalizado para interagir com a API da Nexmo. Para começar, precisamos primeiro gerar um Json Web Token (JWT), que usaremos para nos autenticar na API.
Usando o CLI da Vonage, execute o seguinte comando:
vonage jwt --key_file=./private.key --app_id=VONAGE_APPLICATION_ID./private.key é o caminho para o arquivo da chave privada que foi gerado para você quando criou o aplicativo Messages and Dispatch, enquanto o app_id é o ID do aplicativo que anotamos anteriormente. Em seguida, copie o resultado desse comando.
Variáveis de ambiente e de configuração
Adicione o JWT que você acabou de gerar aos .env, os detalhes do Messenger que anotamos anteriormente e os números de telefone que serão usados para enviar e receber notificações por SMS.
VONAGE_JWT = xxxx
FB_SENDER_ID = xxxx
FB_RECIPIENT_ID = xxxx
SMS_FROM = xxxx
SMS_TO = xxxxA seguir, vamos referenciar as variáveis de ambiente que acabamos de definir por meio do nosso arquivo de configuração. Acesse o config diretório e, no arquivo services.php arquivo, adicione um novo Vonage array.
'vonage' => [
'jwt' => env('VONAGE_JWT'),
'fb_sender_id' => env('FB_SENDER_ID'),
'fb_recipient_id' => env('FB_RECIPIENT_ID'),
'sms_from' => env('SMS_FROM'),
'sms_to' => env('SMS_TO')
] Instalando a dependência
A única dependência que nosso projeto terá é a biblioteca GuzzleHTTP , que usaremos para fazer chamadas de API. Execute o seguinte comando para instalar a biblioteca:
composer require guzzlehttp/guzzle Criação do Wrapper
No app diretório, crie um Vonage.php arquivo e adicione o seguinte código a ele:
<?php
namespace App;
use GuzzleHttp\Client;
class Vonage
{
protected $client;
public function __construct()
{
$this->client = $this->setUpClient();
}
protected function setUpClient()
{
$authBearer = 'Bearer ' . config('services.vonage.jwt');
return new Client([
'base_uri' => 'https://api.nexmo.com',
'headers' => [
'Authorization' => $authBearer,
'Content-Type' => 'application/json',
'Accept' => 'application/json'
]
]);
}
public function dispatch()
{
$response = $this->client->request('POST', '/v0.1/dispatch', [
'json' => [
'template' => 'failover',
'workflow' => [
[
'from' => [ 'type' => 'messenger','id' => config('services.vonage.fb_recipient_id')],
'to' => ['type' => 'messenger', 'id' => config('services.vonage.fb_sender_id')],
'message' => [
'content' => [
'type' => 'text',
'text' => 'An incident just occurred',
]
],
'failover' =>[
'expiry_time' => 15,
'condition_status' => 'read',
]
],
[
'from' => ['type' => 'sms','number' => config('services.vonage.sms_from')],
'to' => ['type' => 'sms','number' => config('services.vonage.sms_to')],
'message' => [
'content' => [
'type' => 'text',
'text' => 'An incident just occurred',
]
]
]
]
]
]);
return json_decode($response->getBody());
}
}Nesse dispatch() método, definimos um modelo de failover e um fluxo de trabalho. Sempre que ocorrer um incidente via PagerDuty, receberemos uma notificação sobre o incidente no Facebook Messenger. Se a notificação não for lida em até 15 segundos, a condição de failover é acionada e uma notificação por SMS é enviada como alternativa.
Criação do trabalho
Execute o seguinte comando no terminal para criar uma nova classe de tarefa:
php artisan make:job ReportIncidentEdite o app\Http\Jobs\ReportIncident arquivo com o seguinte código:
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Vonage;
class ReportIncident implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
}
/**
* Execute the job.
*
* @return void
*/
public function handle(Voange $vonage)
{
$vonage->dispatch();
}
}O handle() método recebe o wrapper personalizado da Vonage que criamos anteriormente como uma dependência e, em seguida, chamamos o método dispatch na classe.
Reunindo tudo isso
Chegou a hora de finalmente testar o que temos desenvolvido até agora. Acesse seu painel do PagerDuty e crie um novo incidente.
incidents screenshot
Isso acionará o envio de uma notificação via webhook para o endpoint que adicionamos anteriormente à nossa conta do PagerDuty, que, por sua vez, enviará uma mensagem para a página do Facebook que vinculamos anteriormente à nossa conta da Vonage. Supondo que tudo tenha corrido bem, você deve verificar seu arquivo de log, pois a Vonage deve ter enviado uma atualização sobre o status da mensagem que acabamos de enviar.
{
"message_uuid":"c1bcf89b-c16e-427f-a4b7-15816327832f",
"to":{
"id":"1923256201474167",
"type":"messenger"
},
"from":{
"id":"23037543461244470",
"type":"messenger"
},
"timestamp":"2019-08-08T01:53:07.922Z",
"status":"read",
"_links":{
"dispatch":{
"href":"v0.1/dispatch/15756412-30d6-4664-8a1e-abcd029ea7a4",
"dispatch_uuid":"15756412-30d6-4664-8a1e-abcd029ea7a4"
}
}
},
{
"template":"failover",
"status":"completed",
"timestamp":"2019-08-08T01:53:07.959Z",
"usage":{
"price":"0.003",
"currency":"EUR"
},
"dispatch_uuid":"15756412-30d6-4664-8a1e-abcd029ea7a4",
"_links":{
"messages":[
{
"message_uuid":"c1bcf89b-c16e-427f-a4b7-15816327832f",
"href":"v0.1/messages/c1bcf89b-c16e-427f-a4b7-15816327832f",
"channel":"messenger",
"usage":{
"price":"0.001",
"currency":"EUR"
},
"status":"read"
}
]
}
}A partir dos registros acima, recebemos primeiro uma atualização de status informando que a mensagem foi lida e, em seguida, outra atualização de status informando que o fluxo de trabalho de envio foi concluído. Como a mensagem foi lida em 15 segundos, a condição de failover foi atendida; consequentemente, a notificação por SMS nunca foi acionada.
Para verificar se a notificação por SMS será enviada caso a condição de failover não seja atendida, você pode repetir o mesmo processo, mas, desta vez, não leia a notificação do Facebook Messenger. Você perceberá que, desta vez, a notificação por SMS será acionada.
Conclusão
Neste tutorial, vimos como podemos criar uma integração personalizada entre o PagerDuty e o Vonage para garantir um sistema de alerta de contingência resiliente em caso de emergência. Você pode encontrar um link para o repositório do GitHub aqui.