« HE:labs
HE:labs

Recebendo webhooks usando Ultrahook

Postado por Thiago Borges em 03/10/2013

Durante uma integração com um sistema de pagamento, precisava saber quando o status do pagamento era alterado. Uma solução seria rodar um cron job pra ficar verificando este status. O processamento poderia demorar 2 segundos ou 2 dias, então, esta maneira não é tão eficiente. Com que frequência eu deveria checar esse status? Felizmente, alguns serviços enviam um ping avisando que o status do pagamento foi atualizado. E assim, quando eu quiser, posso tomar alguma providência. Nesse caso, a providência foi checar o status do pagamento na API de seu provedor e atualizar o valor no sistema. Esse ping é o webhook e é dele que falarei nesse post.

Webhook é uma excelente alternativa para ser notificado quando algum evento ocorre no serviço utilizado. Serviços como Github, Stripe, ActiveCampaign e Papertrail utilizam webhooks. No caso do Github, seu webhook envia um JSON com as informações do evento que acabou de acontecer. O template em Ruby, que gera essas informações no formato JSON, pode ser visto aqui.

Uma característica dos webhooks é que eles são enviados como POST, mas infelizmente é difícil receber essa notificação em ambiente de desenvolvimento, onde, mesmo que meu IP seja enviado para receber o callback do webhook, estaremos, geralmente, atrás de um roteador com firewall. Definir o meu IP no código fonte para receber a chamada pode dificultar muito quando estamos trabalhando em equipe, além de ser errado. Então, encontrei a solução para todos esses problemas: o Ultrahook.

Ultrahook é uma gem que cria um endpoint público do tipo: http://borges.projeto.ultrahook.com, onde projeto é o namespace e borges é definido quando executo o ultrahook da seguinte forma: ultrahook borges 3000.

Esta gem não expõe completamente seu servidor de desenvolvimento. Ela apenas redireciona as requisições do tipo POST para o seu servidor. Logo, ninguém conseguirá acessar seu sistema.

Como fazer para usá-la nos projetos, tendo o mínimo de overhead?

Registre-se gratuitamente no site do ultrahook e salve sua API key.

Adicione ao seu projeto a variável de ambiente contendo a chave do ultrahook:

export ULTRAHOOK_API_KEY=0pMcxt1yJrTjUBrGabXrezCRzGRjPsig

Essa chave é a mesma usada no exemplo do site oficial, então, não tem problema colocar aqui.

Altere a url do callback caso o projeto esteja em modo de desenvolvimento:

1 def charge(callback_uri)
2   callback_uri = "http://#{ENV['USER']}.projeto.ultrahook.com/callback" if Rails.env.development?
3   client.charge({
4     amount: 10.0,
5     callback_uri: callback_uri
6   })
7 end

Usar a variável de ambiente USER foi a melhor maneira que encontrei para evitar colisão com outros membros da equipe.

Adicione a gem ao seu Gemfile apenas no grupo development:

gem 'ultrahook', group: :development

Quando estiver esperando por uma resposta, execute o seguinte comando, onde 3000 é a porta padrão do servidor Rails:

ultrahook $USER 3000

Conclusão

Esta foi a maneira mais fácil de solucionar o meu problema. No caso do callback de pagamento, geralmente, a única informação que chega é o ID do pagamento que deve ser consultado em seguida.

Embora seja feita em Ruby, esta gem pode ser usada no desenvolvimento de qualquer sistema, precisando apenas de uma adaptação mínima da equipe. O resultado final é que em poucos passos e apenas um comando, uma tarefa que seria complexa se torna extremamente simples.

Você gostou dessa solução ou conhece alguma outra? Deixe seu comentário.

Links

Compartilhe

Sabia que nosso blog agora está no Medium? Confira Aqui!