Blog

👨🏻‍🏫 Query GraphQL para enviar automaticamente os inscritos na newsletter do InstaWP para o Mailchimp

Leonardo Losoviz
Por Leonardo Losoviz ·

(Leia o post do blog 🚀 Enviando automaticamente os inscritos na newsletter do InstaWP para o Mailchimp para ver o contexto desta query.)

Esta query GraphQL captura o e-mail dos visitantes que marcaram a caixa "Subscribe to mailing list" no InstaWP (ao criar um novo site sandbox), e inscreve esse e-mail em uma lista do 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, você também pode registrar os inscritos no seu plugin de newsletter para WordPress (ex: Noptin ou outro).

Vamos ver como essa query GraphQL faz sua mágica.

Dividindo a query GraphQL em unidades independentes

Um documento GraphQL pode conter múltiplas operações (queries e mutations), mas apenas uma delas será executada. Indicamos qual delas usar por meio do parâmetro ?operationName=... no endpoint GraphQL; caso contrário, a última operação será executada.

Note que há 2 operações query no documento acima:

  1. HasSubscribedToNewsletter
  2. MaybeCreateContactOnMailchimp

A URL do webhook contém ?operationName=MaybeCreateContactOnMailchimp, portanto essa é a operação que será executada.

Graças à extensão Multiple Query Execution, MaybeCreateContactOnMailchimp executará primeiro HasSubscribedToNewsletter, conforme indicado pela diretiva @depends:

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

Além disso, MaybeCreateContactOnMailchimp será executada condicionalmente, somente se o valor da variável $subscribedToNewsletter for true:

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

$subscribedToNewsletter é uma variável dinâmica, exportada dentro da operação HasSubscribedToNewsletter:

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

Portanto, a operação MaybeCreateContactOnMailchimp só será executada quando o usuário tiver marcado a caixa "Subscribe to mailing list".

Verificando se o usuário marcou a caixa

A documentação do webhook do InstaWP indica que os dados do payload contêm os seguintes campos (entre outros):

  • marketing_optin: Indica se o usuário marcou a caixa
  • email: E-mail do visitante

A documentação apenas explica que o campo marketing_optin tem o valor NA quando a caixa não está marcada, então precisaremos trabalhar com isso.

Para descobrir se o usuário marcou a caixa, a lógica é:

  • Verificar se o campo marketing_optin está presente, e
  • Verificar que seu valor não é NA

Isso é calculado na operação HasSubscribedToNewsletter. Aqui ela está com comentários, explicando o que cada linha da query faz:

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")
}

Há várias coisas interessantes nessa query.

Campos Globais

Você notou os campos que começam com _? São eles:

  • _httpRequestHasParam
  • _httpRequestStringParam
  • _notEquals
  • _and

Esses são campos globais, que são campos disponíveis em todos os tipos no schema GraphQL. Os campos globais oferecem funcionalidade em vez de dados e, por convenção, começam com _.

Field to Input

Você notou essas variáveis que começam com $__? São elas:

  • $__subscriberOptIn
  • $__hasSubscriberOptIn
  • $__isNotSubscriberOptInNAValue

Essas são variáveis dinâmicas que contêm o valor de um campo definido antes delas dentro da mesma operação. Por exemplo, a variável $__subscriberOptIn contém o valor do campo subscriberOptIn declarado acima dela.

Essa é uma funcionalidade fornecida pela extensão Field to Input, que permite usar a saída de um campo como entrada em outro campo. É assim que podemos criar funcionalidades dentro da query GraphQL.

Na query, o campo isNotSubscriberOptInNAValue verifica que o valor do campo subscriberOptIn consultado anteriormente não é igual a "NA", e subscribedToNewsletter calcula uma operação AND envolvendo os valores dos campos hasSubscriberOptIn e isNotSubscriberOptInNAValue.

Conectando ao Mailchimp

A operação MaybeCreateContactOnMailchimp contém a lógica para extrair os dados do payload e chamar a API do Mailchimp para inscrever o e-mail na lista da newsletter.

Aqui está a operação com comentários, explicando o que cada linha faz:

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"
      }
    }
  })
}

Vamos explorar as funcionalidades usadas nessa query.

Variáveis de Ambiente

Precisamos fornecer nossas credenciais ao conectar à API do Mailchimp. No entanto, não queremos inseri-las diretamente na query GraphQL, pois elas podem vazar em algum lugar (ex: podem ser impressas em algum log).

Por isso usamos o campo global _env (fornecido pela extensão PHP Constants and Environment via Schema) para ler uma variável de ambiente ou constante PHP, junto com a diretiva @remove (fornecida pela extensão Field Response Removal) para evitar que as credenciais sejam impressas na resposta.

Agora podemos declarar nossas credenciais em wp-config.php:

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

Enviando a Requisição HTTP ao Mailchimp

O último elemento da lógica é o campo _sendJSONObjectItemHTTPRequest, que envia uma requisição HTTP para algum serviço.

Como queremos nos conectar à API do Mailchimp, o campo mailchimpListMembersJSONObject fornece os dados exigidos pelo endpoint da REST API do Mailchimp, conforme indicado na documentação para inscrever um membro em uma lista do Mailchimp:

  • Enviar uma requisição POST
  • O endpoint é https://{subdomain}.api.mailchimp.com/3.0/lists/{listCode}/members
  • O corpo deve incluir os campos email_address e status

Criando um webhook para interagir com qualquer API

A query GraphQL deste post encaminha dados do InstaWP para o Mailchimp.

Você pode aplicar a mesma ideia para qualquer combinação que precisar, extraindo os dados de algum serviço de origem (qualquer que seja), adaptando-os e enviando-os para algum serviço de destino (qualquer que seja).

Divirta-se!


Assine nossa newsletter

Fique por dentro de todas as atualizações do Gato GraphQL.