Drupal Advent Calendar 2023 の2日目です。
システム連携で「Webhook」はよく使われる手段だと思うのですが、Drupal界隈ではWebhook関連の記事を見かけたことがないなとふと気づきました。
本記事では「Drupalが送信する側」であることを前提に、DrupalでWebhookを実現するにはどんな選択肢があるのか、それぞれの方法の特徴を考察していきたいと思います。
DrupalでWebhookが使えると何が嬉しいのか
例えば、「Drupalで新しいコンテンツが作成された」ようなイベントをトリガーに、
- 外部システムにコンテンツを同期する
- Slackに通知する
といったことが実現できるように、主に外部システムとの連携で役立ちます。
Webhookを使用しなくても、DrupalコアのJSON:APIを一定の頻度でポーリングすれば同じようなことができますが、APIのポーリングは、イベントの頻度が低ければ低いほど非効率なんですよね。いつイベントがトリガーになるか分からないけどリアルタイムで拾いたい時はWebhook欲しいなと思います。逆にイベントの頻度が高ければポーリングで過不足ないのかなと思ったりします。
DrupalでWebhookを利用するには
前提として、Drupalコアにはそのような機能は存在しません。Google先生に聞いたところ、2つの方法が出てきました。
- Zapierを使用する前提 -> Zapierで用意されたDrupalインテグレーションを使用する
- コントリビュートモジュールで実現する -> Webhooksモジュールを使用する
パターン1: Zapierで用意されたDrupalインテグレーションを使用する
Zapierには様々なサービスがトリガーやアクションとして利用できるのですが、任意のDrupalサイトと接続するためのインテグレーションが用意されていました。
ZapierでDrupalインテグレーションを使用する
Drupal側の設定
- Drupalサイトに管理者としてログインします。管理メニューの Extend に移動して、「JSON:API」と「HTTP Basic Authentication」にチェックを入れてモジュールを有効化します。Zapierとの連携をする上で必要なモジュールになります。
- 余力があれば、Zapier用のユーザーアカウントを作成しておきます。ユーザー権限はなんでも良いです。
Zapier側の設定
- Zapierにログインして、左側の [Create Zap] をクリックします。
- 画面上の [1. Trigger] をクリックします。
- 検索窓に「drupal」と入力して、一覧に出てきた [Drupal] をクリックします。
- 右側に設定項目が表示されます。まずは「App & event」の設定です。「Event」に [New Content] と指定して、[Continue] をクリックします。
- 次に「Account」の設定です。「Connect Drupal」の横にある [Sign in] をクリックします。
- 接続したいDrupalサイトのURLと、ユーザー名&パスワードを入力して [Yes, Continue to Drupal] をクリックします。接続に成功するとウィンドウが自動的に閉じます。
- 次に「Trigger」の設定です。「Contenttype」に [Article] を指定して、[Continue] をクリックします。
- 最後に「Test」で接続テストを行います。[Test trigger] をクリックすると、Drupalとの接続確認が行われ、既存のコンテンツをいくつか取得してZapierでどんな値が扱えるのかを確認できます。[Continue with selected record] をクリックします。これでTriggerの設定は完了です。
- 左側の画面の [2. Action] をクリックします。イベントが発火した時に何を実行したいかなので、今回は分かりやすく「Gmail」を選択してメールを送るようにしたいと思います。
- 「App & event」項目で、「Event」に [Send Email] を選択して [Continue] をクリックします。
- 「Account」項目で、接続したいGmailアカウントと接続設定を行います。[Continue] で次に進みます。
- 「Action」項目で、「To」に送信先メールアドレスを指定します。「Subject」にメール件名を入力します。「Boby」にメール本文を入力します。最後に [Continue] をクリックします。
- 「Test」で [Test Step] をクリックして、実際にメールが送信されるか確認します。
- 最後に [Publish] をクリックして、作成したZapが動くようにします。
Webhookを動かしてみる
- Drupalサイトでコンテンツを作成して公開します。
- 約15分後にメール通知が届きました。
- Zapierのダッシュボードにある「Zap history」からも実行された形跡を確認できました。
所感
- イベントの対象が限定的: Zapierの設定で、トリガーイベントとして選択できるのが「New content」のみでした。このコンテンツはいわゆるノードなので、タクソノミータームやユーザーなどは対象外です。またCRUD操作のうち、可能なのはCreateのみでUpdateやDeleteといったイベントはトリガーしてくれないので、使用場面が限定的になるように感じました。
- Webhook・・・?: Drupalサイトのapache logを確認すると、JSON:APIを定期的にポーリングしているだけのように見えます。それはそのはずで、前述の通りDrupalコアにWebhookのようなイベントが発火した時に送信する仕組みは提供されていないので、APIをポーリングする以外に方法が無いのです。
パターン1の方法は、実務的に片手落ち感があることが分かりました。またZapier以外のWebhookレシーバーを使用する場合には利用できません。
パターン2: Webhooksモジュールを使用する
Webhooksモジュールは、Googleで「Webhooks Drupal」で検索した時に一番上に出てくるコントリビュートモジュールです。
※2番目の検索結果に出てくるWebhookモジュールはDrupal 7バージョンのみに対応しているものなので、Drupal 10では利用できません。
Webhooksモジュールの概要
モジュールのプロジェクトページを眺めて得られる情報として、利用数は多くないのと、alpha版しか出ていないのは少し気になりますが、Drupal 10対応していることと、直近もコードが更新されているのでアクティブなプロジェクトであることが伺えます。
Drupalのイベントに対してWebhookを送信することと、Drupal側で外部のWebhookを受信することの両方が可能だと説明されています。
Webhooksモジュールを使用する
WebhookレシーバーとしてZapierを使いたいところですが、Zapierでは任意のWebhookを受け取るにはプランアップ(=課金)をしないといけないので、今回は無料で利用できるpipedreamというサービスを利用します。
pipedream側の設定
- プロジェクトが1つもない場合、まず初めに右上の [New project] をクリックして適当なプロジェクトを作成します。プロジェクトが無いとワークフローが作成できません。
- 右上の [New workflow] をクリックしてワークフローを1つ作成します。設定項目が色々ありますが、全てデフォルトのままで問題無しです。
- トリガーを設定する画面が表示されるので、[New HTTP / Webhook Requests] をクリックします。
- 次の画面は全てデフォルトのまま、[Save and continue] をクリックします。
- トリガーの設定が完了するとURLが発行されます。Drupalでイベントが発火したら、DrupalがこのURLにリクエストを送信してくれます。このURLは後ほどDrupal側の設定で利用するのでコピーしておきます。
- 画面の下にある [+] をクリックして、イベントが発火した後に何を実行するかを設定します。今回はWebhooksモジュールの挙動がわかれば十分なので、[Run custom code] をクリックします。
- エラーが起こらなければ内容はなんでも良いです。これで設定は以上になるので右上の [Deploy] をクリックします。
Drupal側の設定
- Composerでモジュールをインストールします。
$ composer require 'drupal/webhooks:^3.0@alpha'
- 「Webhooks」モジュールを有効化します。
「Webhook」というモジュールも同梱されていますが、これは「Webhook」というコンテンツエンティティが提供されるもので、今回の調査では不要です。
$ drush pm:enable webhooks
- 管理メニューの Configuration > Web services > Webhooks (URL: /admin/config/services/webhook)に移動して、[Add Webhook] をクリックします。
- 以下の各項目を入力します。
- 他はそのままにして [Save] をクリックします。これで設定完了。
Webhookを動かしてみる
- Drupalサイトでコンテンツを作成して公開します。
- pipedream側の管理画面にアクセスして、対象のワークフローが実行されたことを確認します。下画像の赤枠部分をクリックすると、右側のウィンドウに実行内容が詳細に表示されます。
- ワークフローの各タスクにある[Exports]タブのbodyを開くと、Drupalからどんな値を渡されたのかを確認できます。手順1で作成した「This is Test article」という記事の情報が渡っていることが分かります。
- Drupal側のログも確認してみます。管理メニューの Reports > Recent log messages に移動します。ログ一覧に「Webhook Dispatched. ...」というログがありますが、Webhookが送信されたことがログからも確認できました。
所感
- 様々なイベントに対応: Drupalのコンテンツエンティティに対するCRUD操作をイベントとして発火させることができるようです。
- ドキュメントがない: WebhooksモジュールのReadme.mdにはインストール方法しか書いてありませんでした。難しい設定は特にないので困ることはないのですが、同梱されているWebhook(マシン名: webhook)モジュールがどんな時に役立つのかは謎のままです。
- 安定版がない&利用数が少ない: 2011年に公開されているので、古株の部類にはなるとは思うのですが。
Webhooksモジュールは管理画面もきちんと用意されており、特につまづくポイントもなく直感的に操作できました。サブエンティティタイプなどでイベントの絞り込みができるような機能があると良いように感じましたが、現状のままでも機能面では過不足はないです。だからこそ利用数は伸びてほしい代物だと感じました。
まとめ
DrupalでWebhookを利用する方法をまとめてみました。Drupalにおいて、システム連携は頻繁に発生するシーンであることから、Webhookを利用することは有益な選択肢の1つです。今回紹介した2つの方法にはそれぞれ一長一短があり、DrupalでWebhookを取り扱うことがマイナーであることを強く感じました。今後事例が増えることを期待しています。