👨🏻🏫 自动将 InstaWP 新闻订阅者发送到 Mailchimp 的 GraphQL Query
(请阅读博客文章 🚀 自动将 InstaWP 新闻订阅者发送到 Mailchimp,了解此 Query 的背景。)
这个 GraphQL query 会捕获在 InstaWP 中创建新沙盒站点时勾选了「Subscribe to mailing list」复选框的访客的电子邮件地址,并将其订阅到 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"
}
}
})
}此外,您也可以将订阅者注册到您的 WordPress 新闻插件(例如:Noptin 或其他插件)中。
让我们来看看这个 GraphQL query 是如何发挥作用的。
将 GraphQL Query 拆分为独立单元
一个 GraphQL 文档可以包含多个操作(query 和 mutation),但每次只执行其中一个。我们通过 GraphQL 端点上的 ?operationName=... 参数来指定执行哪个;若未指定,则执行最后一个操作。
请注意,上面的文档中有 2 个 query 操作:
HasSubscribedToNewsletterMaybeCreateContactOnMailchimp
Webhook URL 中包含 ?operationName=MaybeCreateContactOnMailchimp,因此该操作将被执行。
得益于 Multiple Query Execution 扩展,MaybeCreateContactOnMailchimp 会首先执行 HasSubscribedToNewsletter,如 @depends 指令所示:
query MaybeCreateContactOnMailchimp
@depends(on: "HasSubscribedToNewsletter")
# ...
{
#
}此外,MaybeCreateContactOnMailchimp 是条件性执行的,仅当变量 $subscribedToNewsletter 的值为 true 时才执行:
query MaybeCreateContactOnMailchimp
@depends(on: "HasSubscribedToNewsletter")
@include(if: $subscribedToNewsletter)
{
#
}$subscribedToNewsletter 是一个动态变量,在 HasSubscribedToNewsletter 操作中导出:
query HasSubscribedToNewsletter {
# ...
subscribedToNewsletter: _and(values: [$__hasSubscriberOptIn, $__isNotSubscriberOptInNAValue])
@export(as: "subscribedToNewsletter")
}因此,MaybeCreateContactOnMailchimp 操作仅在用户勾选了「Subscribe to mailing list」复选框时才会执行。
判断用户是否勾选了复选框
InstaWP 的 Webhook 文档 说明负载数据包含以下字段(以及其他字段):
marketing_optin:表示用户是否勾选了复选框email:访客的电子邮件地址
文档仅说明当复选框未被勾选时,字段 marketing_optin 的值为 NA,因此我们需要据此进行处理。
判断用户是否勾选复选框的逻辑如下:
- 检查字段
marketing_optin是否存在,以及 - 检查其值不为
NA
这一逻辑在 HasSubscribedToNewsletter 操作中完成。以下是带注释的版本,解释 query 中每一行的作用:
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")
}这个 query 中有几个有趣的地方。
全局字段
您是否注意到以 _ 开头的字段?具体如下:
_httpRequestHasParam_httpRequestStringParam_notEquals_and
这些是全局字段,即在 GraphQL schema 的所有类型下都可用的字段。全局字段提供的是功能而非数据,按惯例以 _ 开头。
Field to Input
您是否注意到以 $__ 开头的变量?具体如下:
$__subscriberOptIn$__hasSubscriberOptIn$__isNotSubscriberOptInNAValue
这些是动态变量,包含同一操作中在其之前定义的字段的值。例如,变量 $__subscriberOptIn 包含在其上方声明的字段 subscriberOptIn 的值。
这是由 Field to Input 扩展提供的功能,允许将一个字段的输出作为另一个字段的输入使用。这就是我们能在 GraphQL query 中创建功能逻辑的方式。
在这个 query 中,字段 isNotSubscriberOptInNAValue 检查前面查询的字段 subscriberOptIn 的值是否不等于 "NA",而 subscribedToNewsletter 则对字段 hasSubscriberOptIn 和 isNotSubscriberOptInNAValue 的值执行 AND 运算。
连接到 Mailchimp
MaybeCreateContactOnMailchimp 操作包含提取负载数据并调用 Mailchimp API 将电子邮件添加到新闻列表的逻辑。
以下是带注释的操作,解释每一行的作用:
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"
}
}
})
}让我们来探讨这个 query 中使用的功能。
环境变量
连接 Mailchimp API 时,我们需要提供凭据。但是,我们不希望将凭据直接写入 GraphQL query,因为它们可能在某处泄露(例如:可能被打印到某个日志中)。
因此,我们使用全局字段 _env(由 PHP Constants and Environment via Schema 扩展提供)来读取环境变量或 PHP 常量,并结合 @remove 指令(由 Field Response Removal 扩展提供)来避免在响应中打印凭据。
这样,我们就可以在 wp-config.php 中声明凭据:
define( 'MAILCHIMP_API_CREDENTIALS_USERNAME', '{ username }' );
define( 'MAILCHIMP_API_CREDENTIALS_PASSWORD', '{ password }' );向 Mailchimp 发送 HTTP 请求
逻辑的最后一块是字段 _sendJSONObjectItemHTTPRequest,它向某个服务发送 HTTP 请求。
由于我们需要连接到 Mailchimp API,字段 mailchimpListMembersJSONObject 提供了 Mailchimp REST API 端点所需的数据,如将成员订阅到 Mailchimp 列表的文档所示:
- 发送
POST请求 - 端点为
https://{subdomain}.api.mailchimp.com/3.0/lists/{listCode}/members - 请求体必须包含字段
email_address和status
创建与任意 API 交互的 Webhook
本文中的 GraphQL query 将数据从 InstaWP 转发到 Mailchimp。
您可以将同样的思路应用于任何您需要的组合:从某个源服务(无论是哪种)提取数据,对其进行适配,然后发送到某个目标服务(无论是哪种)。
祝您使用愉快!