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 (onullsi 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¶m[]=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
}
}