👨🏻🏫 Query GraphQL para enviar automaticamente os inscritos na newsletter do InstaWP para o Mailchimp
(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:
HasSubscribedToNewsletterMaybeCreateContactOnMailchimp
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 caixaemail: 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_optinestá 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_addressestatus
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!