Hướng dẫn schema
Hướng dẫn schemaBài 18: Tương tác với dịch vụ bên ngoài qua webhook

Bài 18: Tương tác với dịch vụ bên ngoài qua webhook

Webhook là một hàm callback dựa trên HTTP mà một dịch vụ bên ngoài gọi để thông báo về một sự kiện, kèm theo một payload dữ liệu. Webhook cho phép các ứng dụng web và dịch vụ khác nhau giao tiếp với nhau.

Một số ví dụ về các dịch vụ gọi webhook bao gồm:

  • GitHub, khi một commit được đẩy vào repository
  • Dropbox, khi một tài liệu được cập nhật
  • WooCommerce, khi một đơn hàng được thêm vào
  • Microsoft Teams, để nhận tin nhắn văn bản định dạng phong phú và đăng lên các kênh công khai
  • ConvertKit, khi một người đăng ký được kích hoạt

Với Gato GraphQL, chúng ta có thể tạo Persisted Queries hoạt động như webhook:

  • Vì Persisted Query được hiển thị dưới URL riêng của nó, nó có thể được sử dụng làm đích cho webhook
  • Mỗi Persisted Query có thể xử lý riêng một webhook cụ thể

Trong bài học hướng dẫn này, chúng ta sẽ tạo một Persisted Query để tương tác với ConvertKit.

Xem tài liệu webhook

Bước đầu tiên là đọc tài liệu của trang web và hiểu dữ liệu nào được gửi qua payload.

Phân tích webhook trong ConvertKit, các sự kiện liên quan đến người đăng ký sẽ gửi yêu cầu POST đến URL của chúng ta với một payload JSON như sau:

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

Trích xuất dữ liệu từ payload

Vì yêu cầu được gửi qua POST, chúng ta phải trích xuất dữ liệu từ phần thân của yêu cầu HTTP (được hỗ trợ qua tiện ích mở rộng HTTP Request via Schema).

Nếu yêu cầu HTTP được thực hiện qua GET, thì Persisted Query có thể trực tiếp lấy các mục dữ liệu từ các tham số URL.

GraphQL query này lấy phần thân của yêu cầu và chuyển đổi nó thành một đối tượng JSON. Sau đó nó trích xuất các mục "subscriber.first_name""subscriber.email_address" từ đối tượng JSON, và xuất chúng dưới dạng các biến động:

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

Tiện ích mở rộng HTTP Request via Schema cho phép chúng ta lấy tất cả dữ liệu yêu cầu HTTP hiện tại, thông qua các trường sau:

  • _httpRequestBody: Phần thân của yêu cầu HTTP
  • _httpRequestClientHost: Host của client
  • _httpRequestClientIP: Địa chỉ IP của client (hoặc null nếu máy chủ không được cấu hình đúng)
  • _httpRequestCookie: Giá trị cookie của yêu cầu
  • _httpRequestCookies: Cookie của yêu cầu
  • _httpRequestDomain: Tên miền của URL được yêu cầu
  • _httpRequestFullURL: URL được yêu cầu (bao gồm các tham số query)
  • _httpRequestHasCookie: Yêu cầu có chứa một cookie nhất định không?
  • _httpRequestHasHeader: Yêu cầu có chứa một header nhất định không?
  • _httpRequestHasParam: Yêu cầu có chứa một tham số nhất định không?
  • _httpRequestHeader: Giá trị header của yêu cầu
  • _httpRequestHeaders: Các header của yêu cầu
  • _httpRequestHost: Host của URL được yêu cầu
  • _httpRequestMethod: Phương thức yêu cầu
  • _httpRequestStringParam: Giá trị của một tham số (được truyền qua POST hoặc GET) kiểu ?param=value
  • _httpRequestStringListParam: Giá trị của một tham số (được truyền qua POST hoặc GET) kiểu ?param[]=value1&param[]=value2
  • _httpRequestParams: Các tham số được truyền qua POST hoặc qua query URL
  • _httpRequestProtocol: Giao thức của yêu cầu
  • _httpRequestQuery: Chuỗi tham số query
  • _httpRequestReferer: Referer của yêu cầu
  • _httpRequestRequestTime: Dấu thời gian bắt đầu yêu cầu
  • _httpRequestScheme: Scheme của URL được yêu cầu
  • _httpRequestServerIP: Địa chỉ IP của máy chủ
  • _httpRequestURL: URL được yêu cầu (không có tham số query)
  • _httpRequestURLPath: Đường dẫn tuyệt đối (bắt đầu bằng "/") của URL được yêu cầu
  • _httpRequestUserAgent: User agent

Thực hiện một hành động với dữ liệu

Sau khi trích xuất dữ liệu từ payload, chúng ta có thể thực hiện một hành động với nó.

GraphQL query này xử lý sự kiện subscriber.subscriber_unsubscribe, để gửi email đến người đã hủy đăng ký, yêu cầu phản hồi.

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