# Lidar com entregas de webhook

Saiba como escrever código para ouvir e responder a entregas de webhooks.

## Introdução

Ao criar um webhook, você especifica uma URL e se inscreve para tipos de eventos. Quando ocorrer um evento ao qual o webhook está inscrito, GitHub enviará uma solicitação HTTP com dados sobre o evento para a URL especificada. Se o seu servidor estiver configurado para ouvir entregas de webhooks nesse URL, ele poderá agir quando receber um.

Este artigo descreve como escrever código para permitir que seu servidor ouça e responda a entregas de webhooks. Você testará seu código usando seu computador ou codespace como um servidor local.

## Instalação

Para testar o webhook localmente, você pode usar uma URL de proxy para webhooks para encaminhar webhooks de GitHub para o seu computador ou codespace. Este artigo usa o smee.io para fornecer um URL de proxy de webhook e encaminhar webhooks.

### Obtenha uma URL de proxy de webhook

1. No navegador, navegue até <https://smee.io/>.
2. Clique em **Iniciar um novo canal**.
3. Copie a URL completa em "URL de Proxy de Webhook". Você usará esse URL nas etapas de configuração a seguir.

### Encaminhar webhooks

1. Se você ainda não tiver o [smee-client](https://www.npmjs.com/package/smee-client) instalado, execute o seguinte comando no seu terminal:

   ```shell copy
   npm install --global smee-client
   ```

2. Para receber webhooks encaminhados de smee.io, execute o seguinte comando em seu terminal. Substitua `WEBHOOK_PROXY_URL` pela URL do proxy de webhook obtida anteriormente.

   ```shell copy
   smee --url WEBHOOK_PROXY_URL --path /webhook --port 3000
   ```

   Você deverá ver uma saída semelhante a esta, em que `WEBHOOK_PROXY_URL` é a URL de proxy de webhook:

   ```shell copy
   Forwarding WEBHOOK_PROXY_URL to http://127.0.0.1:3000/webhook
   Connected WEBHOOK_PROXY_URL
   ```

   Observe que o caminho é `/webhook` e a porta é `3000`. Você usará esses valores posteriormente quando escrever o código para lidar com entregas de webhooks.

3. Deixe ele ativo enquanto você testa seu webhook. Quando quiser interromper o encaminhamento de webhooks, pressione <kbd>Ctrl</kbd>+<kbd>C</kbd> .

### Criar um webhook

1. Crie um webhook com as seguintes configurações. Para saber mais, confira [Criação de webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/creating-webhooks).

   * Para o URL, use o URL do proxy do webhook que você usou anteriormente.
   * Se tiver a opção de escolher o tipo de conteúdo, use JSON.

## Escrever código para lidar com entregas de webhooks

Para lidar com entregas de webhooks, você precisa escrever um código que faça o seguinte:

* Inicialize seu servidor para escutar as solicitações ao URL do webhook
* Leia os cabeçalhos e o corpo HTTP da solicitação
* Realize a ação desejada em resposta à solicitação

Você pode usar qualquer linguagem de programação que possa ser executada no seu servidor.

Os exemplos a seguir imprimem uma mensagem quando uma entrega de webhook é recebida. No entanto, você pode modificar o código para executar outra ação, como fazer uma solicitação à GitHub API ou enviar uma mensagem do Slack.

* [Exemplo do Ruby](#ruby-example)
* [Exemplo do JavaScript](#javascript-example)

### Exemplo do Ruby

Este exemplo usa uma gem do Ruby, o Sinatra, para definir rotas e lidar com solicitações HTTP. Para obter mais informações, confira [o LEIAME do Sinatra](https://github.com/sinatra/sinatra#readme).

#### Exemplo com Ruby: Instalar dependências

Para usar este exemplo, você deve instalar a gem Sinatra no seu projeto Ruby. Por exemplo, faça isso com o [Bundler](https://bundler.io/):

1. Caso ainda não tenha o Bundler instalado, execute o seguinte comando no terminal:

   ```shell copy
   gem install bundler
   ```

2. Caso ainda não tenha um Gemfile para seu aplicativo, execute o seguinte comando no terminal:

   ```shell copy
   bundle init
   ```

3. Caso ainda não tenha um Gemfile.lock para seu aplicativo, execute o seguinte comando no terminal:

   ```shell copy
   bundle install
   ```

4. Instale a gem Sinatra executando o seguinte comando em seu terminal:

   ```shell copy
   bundle add sinatra
   ```

#### Exemplo com Ruby: Escrever o código

Crie um arquivo Ruby com o seguinte conteúdo. Modifique o código para lidar com os tipos de eventos aos quais o webhook está inscrito, bem como o `ping` evento que GitHub envia quando você cria um webhook. Este exemplo lida com os eventos `issues` e `ping`.

```ruby copy annotate
# These are the dependencies for this code. You installed the `sinatra` gem earlier. For more information, see [Ruby example: Install dependencies](#ruby-example-install-dependencies). The `json` library is a standard Ruby library, so you don't need to install it.
require 'sinatra'
require 'json'

# The `/webhook` route matches the path that you specified for the smee.io forwarding. For more information, see [Forward webhooks](#forward-webhooks).
#
# Once you deploy your code to a server and update your webhook URL, you should change this to match the path portion of the URL for your webhook.
post '/webhook' do

  # Respond to indicate that the delivery was successfully received.
  # Your server should respond with a 2XX response within 30 seconds of receiving a webhook delivery. If your server takes longer than that to respond, then GitHub terminates the connection and considers the delivery a failure.
  status 202

  # Check the `X-GitHub-Event` header to learn what event type was sent.
  # Sinatra changes `X-GitHub-Event` to `HTTP_X_GITHUB_EVENT`.
  github_event = request.env['HTTP_X_GITHUB_EVENT']

  # You should add logic to handle each event type that your webhook is subscribed to.
  # For example, this code handles the `issues` and `ping` events.
  #
  # If any events have an `action` field, you should also add logic to handle each action that you are interested in.
  # For example, this code handles the `opened` and `closed` actions for the `issue` event.
  #
  # For more information about the data that you can expect for each event type, see [AUTOTITLE](/webhooks/webhook-events-and-payloads).
  if github_event == "issues"
    data = JSON.parse(request.body.read)
    action = data['action']
    if action == "opened"
      puts "An issue was opened with this title: #{data['issue']['title']}"
    elsif action == "closed"
      puts "An issue was closed by #{data['issue']['user']['login']}"
    else
      puts "Unhandled action for the issue event: #{action}"
    end
  elsif github_event == "ping"
    puts "GitHub sent the ping event"
  else
    puts "Unhandled event: #{github_event}"
  end
end
```

#### Exemplo com Ruby: Testar o código

Para testar seu webhook, você pode usar seu computador ou codespace para atuar como um servidor local. Se tiver problemas com essas etapas, consulte [Solução de problemas](#troubleshooting).

1. Certifique-se de que esteja encaminhando webhooks. Se não estiver mais encaminhando webhooks, siga as etapas em [Encaminhar webhooks](#forward-webhooks) novamente.

2. Em uma janela de terminal separada, execute o seguinte comando para iniciar um servidor local em seu computador ou codespace. Substitua `FILE_PATH` pelo caminho para o arquivo em que o código da seção anterior está armazenado. Observe que `PORT=3000` corresponde à porta que você especificou para o encaminhamento do webhook na etapa anterior.

   ```shell copy
   PORT=3000 ruby FILE_NAME
   ```

   Você deverá ver um resultado que indica algo como "Sinatra has taken the stage on 3000".

3. Acione seu webhook. Por exemplo, se você criou um webhook de repositório que está inscrito no evento `issues`, abra um problema em seu repositório. Você também pode reenviar uma entrega anterior de webhook. Para saber mais, confira [Entregar webhooks novamente](/pt/enterprise-server@3.22/webhooks/testing-and-troubleshooting-webhooks/redelivering-webhooks).

4. Navegue até a sua URL de webhook proxy no smee.io. Você deverá ver um evento correspondente ao que você acionou ou reenviou. Isso indica que GitHub enviou com êxito uma entrega de webhook para a URL de carga especificada.

5. Na janela do terminal em que `smee --url WEBHOOK_PROXY_URL --path /webhook --port 3000` foi executado, você deverá ver algo como `POST http://127.0.0.1:3000/webhook - 202`. Isso indica que o smee encaminhou com êxito seu webhook ao servidor local.

6. Na janela do terminal em que `PORT=3000 ruby FILE_NAME` foi executado, você deverá ver uma mensagem correspondente ao evento que foi enviado. Por exemplo, se você usar o código de exemplo acima e reenviar o evento `ping`, deverá ver "GitHub enviou o evento ping". Você também pode ver algumas outras linhas que o Sinatra imprime automaticamente.

7. Em ambas as janelas de terminal, pressione <kbd>Ctrl</kbd>+<kbd>C</kbd> para interromper o servidor local e parar de escutar os webhooks encaminhados.

Agora que o código já foi testado localmente, você pode fazer alterações para usar o webhook em produção. Para saber mais, confira as [Próximas etapas](#next-steps). Se teve problemas para testar o código, tente as etapas em [Solução de problemas](#troubleshooting).

### Exemplo do JavaScript

Este exemplo usa o Node.js e a biblioteca Express para definir rotas e lidar com solicitações HTTP. Para obter mais informações, confira: [expressjs.com](https://expressjs.com).

Para ver um exemplo usando o SDK Octokit.js de GitHub, consulte [Criando um aplicativo GitHub que responde a eventos de webhook](/pt/enterprise-server@3.22/apps/creating-github-apps/writing-code-for-a-github-app/building-a-github-app-that-responds-to-webhook-events).

Este exemplo exige que seu computador ou codespace execute o Node.js versão 12 ou superior e o npm versão 6.12.0 ou superior. Para obter mais informações, confira [Node.js](https://nodejs.org).

#### Exemplo com JavaScript: instalar dependências

Para usar este exemplo, você deve instalar a biblioteca `express` em seu projeto Node.js. Por exemplo:

```shell copy
npm install express
```

#### Exemplo de JavaScript: escrever o código

Crie um arquivo JavaScript com os conteúdos a seguir: Modifique o código para lidar com os tipos de eventos aos quais o webhook está inscrito, bem como o `ping` evento que GitHub envia quando você cria um webhook. Este exemplo lida com os eventos `issues` e `ping`.

```javascript copy annotate
// You installed the `express` library earlier. For more information, see [JavaScript example: Install dependencies](#javascript-example-install-dependencies).
const express = require('express');

// This initializes a new Express application.
const app = express();

// This defines a POST route at the `/webhook` path. This path matches the path that you specified for the smee.io forwarding. For more information, see [Forward webhooks](#forward-webhooks).
//
// Once you deploy your code to a server and update your webhook URL, you should change this to match the path portion of the URL for your webhook.
app.post('/webhook', express.json({type: 'application/json'}), (request, response) => {

  // Respond to indicate that the delivery was successfully received.
  // Your server should respond with a 2XX response within 30 seconds of receiving a webhook delivery. If your server takes longer than that to respond, then GitHub terminates the connection and considers the delivery a failure.
  response.status(202).send('Accepted');

  // Check the `x-github-event` header to learn what event type was sent.
  const githubEvent = request.headers['x-github-event'];

  // You should add logic to handle each event type that your webhook is subscribed to.
  // For example, this code handles the `issues` and `ping` events.
  //
  // If any events have an `action` field, you should also add logic to handle each action that you are interested in.
  // For example, this code handles the `opened` and `closed` actions for the `issue` event.
  //
  // For more information about the data that you can expect for each event type, see [AUTOTITLE](/webhooks/webhook-events-and-payloads).
  if (githubEvent === 'issues') {
    const data = request.body;
    const action = data.action;
    if (action === 'opened') {
      console.log(`An issue was opened with this title: ${data.issue.title}`);
    } else if (action === 'closed') {
      console.log(`An issue was closed by ${data.issue.user.login}`);
    } else {
      console.log(`Unhandled action for the issue event: ${action}`);
    }
  } else if (githubEvent === 'ping') {
    console.log('GitHub sent the ping event');
  } else {
    console.log(`Unhandled event: ${githubEvent}`);
  }
});

// This defines the port where your server should listen.
// 3000 matches the port that you specified for webhook forwarding. For more information, see [Forward webhooks](#forward-webhooks).
//
// Once you deploy your code to a server, you should change this to match the port where your server is listening.
const port = 3000;

// This starts the server and tells it to listen at the specified port.
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
```

#### Exemplo de JavaScript: testar o código

Para testar seu webhook, você pode usar seu computador ou codespace para atuar como um servidor local. Se tiver problemas com essas etapas, consulte [Solução de problemas](#troubleshooting).

1. Certifique-se de que esteja encaminhando webhooks. Se não estiver mais encaminhando webhooks, siga as etapas em [Encaminhar webhooks](#forward-webhooks) novamente.

2. Em uma janela de terminal separada, execute o seguinte comando para iniciar um servidor local em seu computador ou codespace. Substitua `FILE_PATH` pelo caminho para o arquivo em que o código da seção anterior está armazenado.

   ```shell copy
   node FILE_NAME
   ```

   Você deve ver a saída que diz `Server is running on port 3000`.

3. Acione seu webhook. Por exemplo, se você criou um webhook de repositório que está inscrito no evento `issues`, abra um problema em seu repositório. Você também pode reenviar uma entrega anterior de webhook. Para saber mais, confira [Entregar webhooks novamente](/pt/enterprise-server@3.22/webhooks/testing-and-troubleshooting-webhooks/redelivering-webhooks).

4. Navegue até a sua URL de webhook proxy no smee.io. Você deverá ver um evento correspondente ao que você acionou ou reenviou. Isso indica que GitHub enviou com êxito uma entrega de webhook para a URL de carga especificada.

5. Na janela do terminal em que `smee --url WEBHOOK_PROXY_URL --path /webhook --port 3000` foi executado, você deverá ver algo como `POST http://127.0.0.1:3000/webhook - 202`. Isso indica que o smee encaminhou com êxito seu webhook ao servidor local.

6. Na janela do terminal em que `node FILE_NAME` foi executado, você deverá ver uma mensagem correspondente ao evento que foi enviado. Por exemplo, se você usar o código de exemplo acima e reenviar o evento `ping`, deverá ver "GitHub enviou o evento ping".

7. Em ambas as janelas de terminal, pressione <kbd>Ctrl</kbd>+<kbd>C</kbd> para interromper o servidor local e parar de escutar os webhooks encaminhados.

Agora que o código já foi testado localmente, você pode fazer alterações para usar o webhook em produção. Para saber mais, confira as [Próximas etapas](#next-steps). Se teve problemas para testar o código, tente as etapas em [Solução de problemas](#troubleshooting).

## Solução de problemas

Se não obtiver os resultados esperados descritos nas etapas de teste, tente o seguinte:

* Certifique-se de que seu webhook esteja usando a URL do proxy do webhook (URL do Smee.io). Para obter mais informações sobre o URL do proxy do webhook, confira [Obter um URL do proxy do webhook](#get-a-webhook-proxy-url). Para obter mais informações sobre suas configurações de webhook, confira [Criação de webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/creating-webhooks).
* Se puder escolher qual tipo de conteúdo usar, certifique-se de que seu webhook use o tipo de conteúdo JSON. Para obter mais informações sobre suas configurações de webhook, confira [Criação de webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/creating-webhooks).
* Certifique-se de que o cliente smee e o servidor local estejam em execução. Você terá esses processos em execução em duas janelas de terminal separadas.
* Certifique-se de que o servidor esteja escutando a mesma porta para a qual o smee.io está encaminhando webhooks. Muitos dos exemplos neste artigo usam a porta 3000.
* Certifique-se de que o caminho para o qual smee.io esteja encaminhando webhooks corresponda a uma rota definida em seu código. Os exemplos neste artigo usam o caminho `/webhooks`.
* Verifique se há mensagens de erros nas janelas de terminal em que você está executando o cliente smee e o servidor local.
* Verifique em GitHub se uma entrega de webhook foi disparada. Para saber mais, confira [Visualizar entregas do webhook](/pt/enterprise-server@3.22/webhooks/testing-and-troubleshooting-webhooks/viewing-webhook-deliveries).
* Confira o URL do proxy webhook em smee.io. Você deverá ver um evento correspondente ao que você acionou ou reenviou. Isso indica que GitHub enviou com êxito uma entrega de webhook para a URL de carga especificada.

## Próximas etapas

Este artigo demonstrou como escrever código para lidar com entregas de webhooks. Ele também mostrou como testar seu código usando seu computador ou codespace como servidor local e encaminhando entregas de webhook de GitHub para seu servidor local por meio do smee.io. Quando terminar de testar seu código, talvez você queira modificá-lo e implantá-lo em um servidor.

### Modificar o código

Este artigo apresentou exemplos básicos que imprimem uma mensagem quando uma entrega de webhook é recebida. Talvez você queira modificar o código para executar outra ação. Por exemplo, você pode modificar o código para:

* Fazer uma solicitação GitHub à API
* Enviar uma mensagem no Slack
* Eventos de log
* Atualizar uma ferramenta externa de gerenciamento de projetos

### Verifique se a entrega é de GitHub

No seu código que processa entregas de webhook, você deve validar que a entrega veio de GitHub antes de continuar processando-a. Para saber mais, confira [Validação de entregas de webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/validating-webhook-deliveries).

### Implantar seu código em um servidor

Este artigo demonstrou como usar seu computador ou codespace como um servidor enquanto você desenvolve seu código. Quando o código estiver pronto para uso em produção, você deverá implantá-lo em um servidor dedicado.

Ao fazer isso, talvez seja necessário atualizar seu código para refletir o host e a porta em que o servidor está escutando.

### Atualizar a URL do webhook

Depois de configurar um servidor para receber tráfego de webhook de GitHub, atualize a URL nas configurações do seu webhook. Talvez seja necessário atualizar a rota que seu código usa para que ela corresponda à parte do caminho da nova URL. Por exemplo, se a nova URL do webhook for `https://example.com/github-webhooks`, você deverá alterar a rota nesses exemplos de `/webhooks` para `/github-webhooks`.

Você não deve usar o smee.io para encaminhar seus webhooks na produção.

### Seguir as práticas recomendadas

Você deve procurar seguir as práticas recomendadas com seus webhooks. Para saber mais, confira [Melhores práticas para usar webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/best-practices-for-using-webhooks).

## Leitura adicional

* [Criando um aplicativo GitHub que responde a eventos de webhook](/pt/enterprise-server@3.22/apps/creating-github-apps/writing-code-for-a-github-app/building-a-github-app-that-responds-to-webhook-events)
* [Melhores práticas para usar webhooks](/pt/enterprise-server@3.22/webhooks/using-webhooks/best-practices-for-using-webhooks)