スキーマチュートリアル
スキーマチュートリアルレッスン18:Webhookを通じた外部サービスとの連携

レッスン18:Webhookを通じた外部サービスとの連携

WebhookとはHTTPベースのコールバック関数であり、外部サービスが何らかのイベントを通知するために呼び出し、データのペイロードとともに送信します。Webhookにより、異なるウェブアプリやサービスが互いに通信できるようになります。

Webhookを呼び出すサービスの例としては、以下が挙げられます:

  • GitHub:リポジトリにコミットがプッシュされたとき
  • Dropbox:ドキュメントが更新されたとき
  • WooCommerce:注文が追加されたとき
  • Microsoft Teams:リッチテキストメッセージを受信してパブリックチャンネルに投稿するとき
  • ConvertKit:サブスクライバーが有効化されたとき

Gato GraphQLを使えば、Webhookとして機能するPersisted Queryを作成できます:

  • Persisted QueryはそれぞれのURLで公開されているため、Webhookのターゲットとして使用できます
  • 各Persisted Queryは、特定のWebhookのみを専門的に処理できます

このチュートリアルレッスンでは、ConvertKitと連携するためのPersisted Queryを作成します。

Webhookのドキュメントを確認する

最初のステップは、そのウェブサイトのドキュメントを読み、ペイロードを通じてどのようなデータが送信されるかを理解することです。

ConvertKitのWebhookを分析すると、サブスクライバー関連のイベントは以下のようなJSONペイロードとともにPOSTリクエストをURLに送信します:

{
  "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クエリはリクエストのボディを取得して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&param[]=value2形式のパラメータ値(POSTまたはGET経由)
  • _httpRequestParams: POSTまたはURLクエリ経由で渡されたパラメータ
  • _httpRequestProtocol: リクエストのプロトコル
  • _httpRequestQuery: クエリパラメータの文字列
  • _httpRequestReferer: リクエストのリファラー
  • _httpRequestRequestTime: リクエスト開始時のタイムスタンプ
  • _httpRequestScheme: リクエストされたURLのスキーム
  • _httpRequestServerIP: サーバーのIPアドレス
  • _httpRequestURL: リクエストされたURL(クエリパラメータなし)
  • _httpRequestURLPath: リクエストされたURLの絶対パス(「/」から始まる)
  • _httpRequestUserAgent: ユーザーエージェント

データを使ってアクションを実行する

ペイロードからデータを抽出したら、そのデータを使って何らかのアクションを実行できます。

このGraphQLクエリは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
  }
}