Tutorial do schema
Tutorial do schemaLição 18: Interagindo com serviços externos via webhooks

Lição 18: Interagindo com serviços externos via webhooks

Um webhook é uma função de callback baseada em HTTP que um serviço externo chama para notificar sobre algum evento, passando junto um payload de dados. Os webhooks permitem que diferentes aplicações web e serviços se comuniquem entre si.

Alguns exemplos de serviços que invocam webhooks incluem:

  • GitHub, quando um commit é enviado para um repositório
  • Dropbox, quando um documento é atualizado
  • WooCommerce, quando um pedido é adicionado
  • Microsoft Teams, para receber mensagens em texto formatado e publicar em canais públicos
  • ConvertKit, quando um assinante é ativado

Com o Gato GraphQL, podemos criar Persisted Queries que atuam como webhooks:

  • Como a Persisted Query é exposta sob sua própria URL, ela pode ser usada como destino do webhook
  • Cada Persisted Query pode lidar exclusivamente com um webhook específico

Nesta lição do tutorial, criaremos uma Persisted Query para interagir com o ConvertKit.

Consultando a documentação do webhook

O primeiro passo é ler a documentação do site e entender quais dados são enviados via payload.

Analisando os webhooks no ConvertKit, os eventos relacionados a assinantes enviam uma requisição POST para nossa URL com um payload JSON como este:

{
  "subscriber": {
    "id": 1,
    "first_name": "John",
    "email_address": "John@example.com",
    "state": "active",
    "created_at": "2018-02-15T19:40:24.913Z",
    "fields": {
      "My Custom Field": "Value"
    }
  }
}

Extraindo os dados do payload

Como a requisição é enviada via POST, precisamos extrair os dados do corpo da requisição HTTP (o que é suportado pela extensão HTTP Request via Schema).

Se a requisição HTTP for executada via GET, a Persisted Query pode diretamente obter os itens de dados dos parâmetros da URL.

Esta query GraphQL recupera o corpo da requisição e o converte em um objeto JSON. Em seguida, extrai os itens "subscriber.first_name" e "subscriber.email_address" do objeto JSON e os exporta como variáveis dinâmicas:

query ExtractPayloadData {
  body: _httpRequestBody
  bodyJSONObject: _strDecodeJSONObject(string: $__body)
 
  subscriberFirstName: _objectProperty(
    object: $__bodyJSONObject,
    by: { path: "subscriber.first_name" }
  )
    @export(as: "subscriberFirstName")
  
  subscriberEmail: _objectProperty(
    object: $__bodyJSONObject,
    by: { path: "subscriber.email_address" }
  )
    @export(as: "subscriberEmail")
}

A extensão HTTP Request via Schema nos permite recuperar todos os dados da requisição HTTP atual, por meio dos seguintes campos:

  • _httpRequestBody: Corpo da requisição HTTP
  • _httpRequestClientHost: Host do cliente
  • _httpRequestClientIP: Endereço IP do cliente (ou null se o servidor não estiver configurado corretamente)
  • _httpRequestCookie: Valor do cookie da requisição
  • _httpRequestCookies: Cookies da requisição
  • _httpRequestDomain: Domínio da URL solicitada
  • _httpRequestFullURL: URL solicitada (incluindo os parâmetros de query)
  • _httpRequestHasCookie: A requisição contém um determinado cookie?
  • _httpRequestHasHeader: A requisição contém um determinado header?
  • _httpRequestHasParam: A requisição contém um determinado parâmetro?
  • _httpRequestHeader: Valor do header da requisição
  • _httpRequestHeaders: Headers da requisição
  • _httpRequestHost: Host da URL solicitada
  • _httpRequestMethod: Método da requisição
  • _httpRequestStringParam: Valor de um parâmetro (passado via POST ou GET) do tipo ?param=value
  • _httpRequestStringListParam: Valor de um parâmetro (passado via POST ou GET) do tipo ?param[]=value1&param[]=value2
  • _httpRequestParams: Parâmetros passados via POST ou via a query da URL
  • _httpRequestProtocol: Protocolo da requisição
  • _httpRequestQuery: String dos parâmetros de query
  • _httpRequestReferer: Referer da requisição
  • _httpRequestRequestTime: Timestamp do início da requisição
  • _httpRequestScheme: Esquema da URL solicitada
  • _httpRequestServerIP: Endereço IP do servidor
  • _httpRequestURL: URL solicitada (sem os parâmetros de query)
  • _httpRequestURLPath: Caminho absoluto (começando com "/") da URL solicitada
  • _httpRequestUserAgent: User agent

Executando uma ação com os dados

Assim que extraímos os dados do payload, podemos executar alguma ação com eles.

Esta query GraphQL lida com o evento subscriber.subscriber_unsubscribe, para enviar um e-mail à pessoa que cancelou a assinatura, solicitando um feedback.

query CreateEmailMessage
  @depends(on: "ExtractPayloadData")
{
  emailMessageTemplate: _strConvertMarkdownToHTML(
    text: """
 
Hey {$subscriberFirstName}, it's sad to let you go!
 
Please be welcome to complete [this form](https://forms.gle/FpXNromWAsZYC1zB8) and let us know if there is anything we can do better.
 
Thanks. Hope to see you back!
 
    """
  )
  emailMessage: _strReplaceMultiple(
    search: ["{$subscriberFirstName}"],
    replaceWith: [$subscriberFirstName],
    in: $__emailMessageTemplate
  )
    @export(as: "emailMessage")
}
 
mutation SendEmail @depends(on: "CreateEmailMessage") {
  _sendEmail(
    input: {
      to: $subscriberEmail
      subject: "Would you like to give us feedback on how we can improve?"
      messageAs: {
        html: $emailMessage
      }
    }
  ) {
    status
  }
}