Blog

👨🏻‍🏫 Consulta GraphQL para enviar automáticamente los suscriptores del newsletter de InstaWP a Mailchimp

Leonardo Losoviz
Por Leonardo Losoviz ·

(Lee la entrada de blog 🚀 Enviando automáticamente los suscriptores del newsletter de InstaWP a Mailchimp para ver el contexto de esta consulta.)

Esta consulta GraphQL captura el email de los visitantes que marcaron la casilla "Subscribe to mailing list" en InstaWP (al crear un nuevo sandbox), y suscribe ese email a una lista de Mailchimp:

query HasSubscribedToNewsletter {
  hasSubscriberOptIn: _httpRequestHasParam(name: "marketing_optin")
  subscriberOptIn: _httpRequestStringParam(name: "marketing_optin")
  isNotSubscriberOptInNAValue: _notEquals(value1: $__subscriberOptIn, value2: "NA")
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    @export(as: "subscribedToNewsletter")
}
 
query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  subscriberEmail: _httpRequestStringParam(name: "email")
  
  mailchimpUsername: _env(name: "MAILCHIMP_API_CREDENTIALS_USERNAME")
    @remove
  mailchimpPassword: _env(name: "MAILCHIMP_API_CREDENTIALS_PASSWORD")
    @remove
  
  mailchimpListMembersJSONObject: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://us7.api.mailchimp.com/3.0/lists/{listCode}/members",
    method: POST,
    options: {
      auth: {
        username: $__mailchimpUsername,
        password: $__mailchimpPassword
      },
      json: {
        email_address: $__subscriberEmail,
        status: "subscribed"
      }
    }
  })
}

Alternativamente, también puedes registrar a los suscriptores en tu plugin de newsletter de WordPress (ej: Noptin u otro).

Veamos cómo esta consulta GraphQL hace su magia.

Dividir la consulta GraphQL en unidades independientes

Un documento GraphQL puede contener múltiples operaciones (queries y mutations), pero solo una de ellas se ejecutará. Indicamos cuál a través del parámetro ?operationName=... en el endpoint de GraphQL; de lo contrario, se ejecutará la última operación.

Fíjate que hay 2 operaciones query en el documento de arriba:

  1. HasSubscribedToNewsletter
  2. MaybeCreateContactOnMailchimp

La URL del webhook contiene ?operationName=MaybeCreateContactOnMailchimp, así que esa es la operación que se ejecutará.

Gracias a la extensión Ejecución de múltiples consultas, MaybeCreateContactOnMailchimp ejecutará primero HasSubscribedToNewsletter, como se indica vía la directiva @depends:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   # ...
{
  #
}

Además, MaybeCreateContactOnMailchimp se ejecutará condicionalmente, solo si el valor de la variable $subscribedToNewsletter es true:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  #
}

$subscribedToNewsletter es una variable dinámica, exportada dentro de la operación HasSubscribedToNewsletter:

query HasSubscribedToNewsletter {
  # ...
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    @export(as: "subscribedToNewsletter")
}

Por lo tanto, la operación MaybeCreateContactOnMailchimp solo se ejecutará cuando el usuario haya marcado la casilla "Subscribe to mailing list".

Calculando si el usuario marcó la casilla

La documentación del webhook de InstaWP indica que los datos del payload contienen los siguientes campos (entre otros):

  • marketing_optin: Indica si el usuario marcó la casilla
  • email: Email del visitante

La documentación solo explica que el campo marketing_optin tiene el valor NA cuando la casilla no está marcada, así que tendremos que trabajar con eso.

Para averiguar si el usuario marcó la casilla, la lógica es:

  • Comprobar si el campo marketing_optin está presente, y
  • Comprobar que su valor no sea NA

Esto se calcula en la operación HasSubscribedToNewsletter. Aquí está con comentarios, explicando qué hace cada línea de la consulta:

query HasSubscribedToNewsletter {
 
  # Check if field `marketing_optin` is present
  hasSubscriberOptIn: _httpRequestHasParam(name: "marketing_optin")
 
  # Get the value of field `marketing_optin`
  subscriberOptIn: _httpRequestStringParam(name: "marketing_optin")
 
  # Check if the value of the field is not "NA"
  isNotSubscriberOptInNAValue: _notEquals(value1: $__subscriberOptIn, value2: "NA")
 
  # Perform an AND operation: field present && value != "NA"
  subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
    
    # Export the result under dynamic variable $subscribedToNewsletter
    @export(as: "subscribedToNewsletter")
}

Hay varias cosas interesantes en esta consulta.

Global Fields

¿Has notado los campos que empiezan con _? Concretamente:

  • _httpRequestHasParam
  • _httpRequestStringParam
  • _notEquals
  • _and

Estos son campos globales, que son campos disponibles bajo todos los tipos en el esquema GraphQL. Los campos globales ofrecen funcionalidad en lugar de datos, y por convención empiezan con _.

Field to Input

¿Has notado esas variables que empiezan con $__? Concretamente:

  • $__subscriberOptIn
  • $__hasSubscriberOptIn
  • $__isNotSubscriberOptInNAValue

Estas son variables dinámicas que contienen el valor de un campo definido antes de ellas dentro de la misma operación. Por ejemplo, la variable $__subscriberOptIn contiene el valor del campo subscriberOptIn declarado encima de ella.

Esta es una característica proporcionada por la extensión Field To Input, que permite usar la salida de un campo como entrada en otro campo. Así es como podemos crear funcionalidad dentro de la consulta GraphQL.

En la consulta, el campo isNotSubscriberOptInNAValue comprueba que el valor del campo previamente consultado subscriberOptIn no sea igual a "NA", y subscribedToNewsletter calcula una operación AND que involucra los valores de los campos hasSubscriberOptIn e isNotSubscriberOptInNAValue.

Conectando a Mailchimp

La operación MaybeCreateContactOnMailchimp contiene la lógica para extraer los datos del payload, y llamar a la API de Mailchimp para inscribir el email en la lista de newsletter.

Aquí está la operación con comentarios, explicando qué hace cada línea:

query MaybeCreateContactOnMailchimp
   @depends(on: "HasSubscribedToNewsletter")
   @include(if: $subscribedToNewsletter)
{
  # Extract form field `email` from the body of the request
  subscriberEmail: _httpRequestStringParam(name: "email")
  
  # Obtain Mailchimp credentials, defined in wp-config.php
  mailchimpUsername: _env(name: "MAILCHIMP_API_CREDENTIALS_USERNAME")
    # Do not print the credentials in the response
    @remove
  mailchimpPassword: _env(name: "MAILCHIMP_API_CREDENTIALS_PASSWORD")
    @remove
  
  # Connect to Mailchimp to add a new member to the list
  mailchimpListMembersJSONObject: _sendJSONObjectItemHTTPRequest(input: {
    url: "https://us7.api.mailchimp.com/3.0/lists/{listCode}/members",
    method: POST,
    options: {
      # Provide credentials to connect to the API
      auth: {
        username: $__mailchimpUsername,
        password: $__mailchimpPassword
      },
      # Provide form data
      json: {
        email_address: $__subscriberEmail,
        status: "subscribed"
      }
    }
  })
}

Exploremos las características usadas en esta consulta.

Variables de entorno

Necesitamos proporcionar nuestras credenciales al conectarnos a la API de Mailchimp. Sin embargo, no queremos introducirlas directamente en la consulta GraphQL, ya que podrían filtrarse en algún lugar (ej: podrían imprimirse en algún log).

Por eso usamos el campo global _env (proporcionado por la extensión Constantes PHP y Variables de Entorno via Schema) para leer una variable de entorno o constante PHP, junto con la directiva @remove (proporcionada por la extensión Eliminación de la Respuesta de un Campo) para evitar imprimir las credenciales en la respuesta.

Ahora, podemos declarar nuestras credenciales en wp-config.php:

define( 'MAILCHIMP_API_CREDENTIALS_USERNAME', '{ username }' );
define( 'MAILCHIMP_API_CREDENTIALS_PASSWORD', '{ password }' );

Enviando la petición HTTP a Mailchimp

La última pieza de la lógica es el campo _sendJSONObjectItemHTTPRequest, que envía una petición HTTP a algún servicio.

Como queremos conectarnos a la API de Mailchimp, el campo mailchimpListMembersJSONObject proporciona los datos requeridos por el endpoint de la REST API de Mailchimp, como se indica en la documentación para suscribir un miembro a una lista de Mailchimp:

  • Enviar una petición POST
  • El endpoint es https://{subdomain}.api.mailchimp.com/3.0/lists/{listCode}/members
  • El cuerpo debe incluir los campos email_address y status

Crear un webhook para interactuar con cualquier API

La consulta GraphQL de este post reenvía datos desde InstaWP a Mailchimp.

Puedes aplicar la misma idea para cualquier combinación que necesites, extrayendo los datos desde algún servicio origen (sea cual sea), adaptándolos, y enviándolos a algún servicio destino (sea cual sea).

¡Diviértete!


Suscríbete a nuestra newsletter

Mantente al tanto de todas las novedades de Gato GraphQL.