Tutorial del esquema
Tutorial del esquemaLección 18: Interactuando con servicios externos mediante webhooks

Lección 18: Interactuando con servicios externos mediante webhooks

Un webhook es una función de callback basada en HTTP que un servicio externo llama para notificar de algún evento, pasando un payload de datos junto con él. Los webhooks permiten a diferentes webapps y servicios comunicarse entre sí.

Algunos ejemplos de servicios que invocan webhooks incluyen:

  • GitHub, cuando se hace push de un commit a un repositorio
  • Dropbox, cuando se actualiza un documento
  • WooCommerce, cuando se añade un pedido
  • Microsoft Teams, para recibir mensajes de texto enriquecido y publicar en canales públicos
  • ConvertKit, cuando se activa un suscriptor

Con Gato GraphQL, podemos crear Persisted Queries que actúan como webhooks:

  • Como la Persisted Query se expone bajo su propia URL, puede usarse como el destino del webhook
  • Cada Persisted Query puede tratar exclusivamente con algún webhook específico

En esta lección del tutorial, crearemos una Persisted Query para interactuar con ConvertKit.

Examinando la documentación del webhook

El primer paso es leer la documentación del sitio web, y entender qué datos se envían mediante el payload.

Analizando los webhooks en ConvertKit, los eventos relacionados con suscriptores envían una petición POST a nuestra URL con un 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"
    }
  }
}

Extrayendo los datos del payload

Como la petición se envía mediante POST, debemos extraer los datos del cuerpo de la petición HTTP (que está soportado mediante la extensión HTTP Request via Schema).

Si la petición HTTP se ejecuta mediante GET, entonces la Persisted Query puede directamente obtener los elementos de datos de los parámetros URL.

Esta consulta GraphQL recupera el cuerpo de la petición y lo convierte a un objeto JSON. Luego extrae los elementos "subscriber.first_name" y "subscriber.email_address" del objeto JSON, y los exporta como variables 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")
}

La extensión HTTP Request via Schema nos permite recuperar todos los datos de la petición HTTP actual, mediante los siguientes campos:

  • _httpRequestBody: Cuerpo de la petición HTTP
  • _httpRequestClientHost: Host del cliente
  • _httpRequestClientIP: Dirección IP del cliente (o null si el servidor no está configurado correctamente)
  • _httpRequestCookie: Valor de cookie de la petición
  • _httpRequestCookies: Cookies de la petición
  • _httpRequestDomain: Dominio de la URL solicitada
  • _httpRequestFullURL: URL solicitada (incluyendo los parámetros de query)
  • _httpRequestHasCookie: ¿Contiene la petición una determinada cookie?
  • _httpRequestHasHeader: ¿Contiene la petición una determinada cabecera?
  • _httpRequestHasParam: ¿Contiene la petición un determinado parámetro?
  • _httpRequestHeader: Valor de cabecera de la petición
  • _httpRequestHeaders: Cabeceras de la petición
  • _httpRequestHost: Host de la URL solicitada
  • _httpRequestMethod: Método de la petición
  • _httpRequestStringParam: Valor de un parámetro (pasado mediante POST o GET) del tipo ?param=value
  • _httpRequestStringListParam: Valor de un parámetro (pasado mediante POST o GET) del tipo ?param[]=value1&param[]=value2
  • _httpRequestParams: Parámetros pasados ya sea mediante POST o mediante la URL query
  • _httpRequestProtocol: Protocolo de la petición
  • _httpRequestQuery: String de parámetros de query
  • _httpRequestReferer: Referer de la petición
  • _httpRequestRequestTime: Timestamp del inicio de la petición
  • _httpRequestScheme: Esquema de la URL solicitada
  • _httpRequestServerIP: Dirección IP del servidor
  • _httpRequestURL: URL solicitada (sin parámetros de query)
  • _httpRequestURLPath: Ruta absoluta (empezando con "/") de la URL solicitada
  • _httpRequestUserAgent: User agent

Ejecutando alguna acción con los datos

Una vez extraídos los datos del payload, podemos ejecutar alguna acción con ellos.

Esta consulta GraphQL trata con el evento subscriber.subscriber_unsubscribe, para enviar un email a la persona que se dio de baja, pidiéndole 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
  }
}