Schema 教程第18课:通过 Webhook 与外部服务交互
第18课:通过 Webhook 与外部服务交互
Webhook 是一种基于 HTTP 的回调函数,外部服务通过调用它来通知某个事件,并随之传递一个数据载荷(payload)。Webhook 使不同的 Web 应用和服务能够相互通信。
调用 Webhook 的服务示例包括:
- GitHub:当仓库有提交被推送时
- Dropbox:当文档被更新时
- WooCommerce:当有新订单添加时
- Microsoft Teams:接收富文本消息并发布到公共频道时
- ConvertKit:当订阅者被激活时
使用 Gato GraphQL,我们可以创建充当 Webhook 的 Persisted Query:
- 由于 Persisted Query 在其独立 URL 下公开,因此可以用作 Webhook 的目标地址
- 每个 Persisted Query 可以专门处理某个特定的 Webhook
在本教程课程中,我们将创建一个 Persisted Query 来与 ConvertKit 进行交互。
查阅 Webhook 文档
第一步是阅读该网站的文档,了解通过载荷发送的数据内容。
分析 ConvertKit 中的 Webhook,与订阅者相关的事件会向我们的 URL 发送一个 POST 请求,并携带如下 JSON 载荷:
{
"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"
}
}
}从载荷中提取数据
由于请求通过 POST 发送,我们必须从 HTTP 请求的正文中提取数据(这由 HTTP Request via Schema 扩展提供支持)。
如果 HTTP 请求通过 GET 执行,则 Persisted Query 可以直接从 URL 参数中获取数据项。
此 GraphQL query 获取请求的正文并将其转换为 JSON 对象。然后从 JSON 对象中提取 "subscriber.first_name" 和 "subscriber.email_address" 两项,并将它们导出为动态变量:
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")
}HTTP Request via Schema 扩展允许我们通过以下字段获取当前 HTTP 请求的所有数据:
_httpRequestBody:HTTP 请求的正文_httpRequestClientHost:客户端主机_httpRequestClientIP:客户端 IP 地址(若服务器未正确配置则为null)_httpRequestCookie:请求的 Cookie 值_httpRequestCookies:请求的所有 Cookie_httpRequestDomain:请求 URL 的域名_httpRequestFullURL:请求的 URL(含查询参数)_httpRequestHasCookie:请求是否包含特定 Cookie?_httpRequestHasHeader:请求是否包含特定请求头?_httpRequestHasParam:请求是否包含特定参数?_httpRequestHeader:请求头的值_httpRequestHeaders:请求的所有请求头_httpRequestHost:请求 URL 的主机_httpRequestMethod:请求方法_httpRequestStringParam:?param=value形式的参数值(通过 POST 或 GET 传递)_httpRequestStringListParam:?param[]=value1¶m[]=value2形式的参数值(通过 POST 或 GET 传递)_httpRequestParams:通过 POST 或 URL 查询传递的参数_httpRequestProtocol:请求协议_httpRequestQuery:查询参数字符串_httpRequestReferer:请求来源页(Referer)_httpRequestRequestTime:请求开始时的时间戳_httpRequestScheme:请求 URL 的协议方案_httpRequestServerIP:服务器 IP 地址_httpRequestURL:请求的 URL(不含查询参数)_httpRequestURLPath:请求 URL 的绝对路径(以"/"开头)_httpRequestUserAgent:用户代理
使用数据执行操作
从载荷中提取数据后,我们可以使用这些数据执行某些操作。
此 GraphQL query 处理 subscriber.subscriber_unsubscribe 事件,向取消订阅的用户发送电子邮件以征求反馈。
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
}
}Prev