Autodesk University Japan など、すでにいくつかのセミナーでお話していますが、今日は WebHooks API の考え方について触れておきたいと思います。
Windows 上で動作するオートデスク デスクトップ製品用にアドイン(アドオン、プラグイン)アプリケーションを開発されている方は、Windows のメッセージ フック をご存知かと思います。Windows アプリケーション上でユーザがおこなった操作に対するイベントを フック、つまり、引っかけて、イベントを取得(通知を取得)、次のアクションへつなげる仕組みです。AutoCAD の場合には、ユーザのマウス操作によって動きまわるクロス ヘア カーソルについて、カーソルが動くたび通知を得て、作図領域のワールド座標を取得したり、メインウィンドウの ☒ ボタンがクリックされたときに通知を得て、AutoCAD がシャットダウンしないよう処理する際などに利用されてきました。
メッセージ フックは、アプリケーション上で発生したイベントを通知するのが主な役割です。この際、取得したいイベント/メッセージを登録したアプリケーションは、通知を受け取るためにコールバック関数を登録します。該当するイベントが発生した場合には、Windows システムや AutoCAD のようなホスト アプリケーションが、登録されているコールバック関数を呼び出す仕組みです。この場合、アプリケーションの実行モジュール自体に通知が送られる(アプリケーション内に定義したコールバック関数が呼び出される)ので、比較的容易にメッセージ フックを利用することが出来ます。
Web やクラウド開発の世界でも「フック」は一般的で、単に Webhook、Web フック、と言っても通用します。この場合、特定の Web サービスやクラウド上でユーザがおこなった操作に対するイベントを ックして(引っかけて)イベントを取得、アプリケーションへ通知して次のアクションへつなげる仕組みを提供します。
Forge の場合も同様です。Forge Webhooks API では、オートデスクのクラウド サービスや Forge Platform API で発生したイベントを Forge アプリケーションに通知してくれます。2018年12月現在、次のイベントが Webhooks API で通知を得ることが出来ます。
- Data Management Webhook
A360/Fusion 360 Team/BIM 360 Docs ストレージ上で発生したイベント(ファイルの追加、変更、削除、移動、複写、フォルダの追加、変更、削除、移動、複写)の通知 - Model Derivative Webhook
Model Derivative API を使ったファイル変換の過程と完了の通知 - Revit Cloud Worksharing Webhook
Revit ワークシェアリングを使ったモデルのパブリッシュと同期を通知 - Fusion Lifecycle Webhook
Fusion Lifecycle を使ったアイテムの作成、クローン、リリース、アップデート、ロック、ロック解除を通知
それでは、通知はどのように受ければいいのでしょう?
Forge の場合、Webhook を利用するのは Web アプリケーションと考えるのが自然です。Forge アプリケーションは Web サーバー実装として用意されているため、Windows メッセージ フックの通知を受信するコールバック関数の代わりに、Forge サーバーが呼び出すことが出来るコールバック URL を登録することになります。
Web サーバー上にコールバック URL を設定するとは、どういった事を意味するのでしょう?
コールバック URL の実装には、ルーティング と呼ばれる手法を用いて、外部から呼び出すことが可能な URL を作成、公開することになります。つまり、新しい endpoint を作成します。実際の実装方法は、Web サーバーがどの Web ホスティング テクノロジを利用しているかに依存します。Node.js を利用している Web サーバーでも、利用するパッケージ(ミドルウェア)によって実装方法が変わります。例えば、Node.js でよく利用されている Express パッケージを使った ルーティング では、下記のような実装 となります。
Model Derivative Webhook で変換終了の通知を得るため、https://www.myapp.co.jp という URL からアクセス可能な Web サ ーバー上に https://www.myapp.co.jp/callback という endpoint を作成すると同時に、その endpont を Forge サーバーが認識するよう、コールバック URL を登録する必要があります。
var express = require('express'); var router = express.Router();
oAuth2TwoLegged.authenticate().then(function (credentials) { var data = JSON.stringify(credentials); var token = JSON.parse(data).access_token; // Create Webhooks uri = "https://developer.api.autodesk.com/webhooks/v1/systems/derivative/events/extraction.finished/hooks"; var payLoad = { "callbackUrl": "https://www.myapp.co.jp/callback", "scope": { "workflow": WEBHOOK_TENANT } }; request.post({ url: uri, headers: { 'content-type': 'application/json', 'authorization': 'Bearer ' + token, }, body: JSON.stringify(payLoad) }, function (error, webhookres, body) { var data = JSON.stringify(webhookres); if (JSON.parse(data).statusCode == 201) { var headers = JSON.parse(data).headers; data = JSON.stringify(headers); WEBHOOK_LOCATION = JSON.parse(data).location; console.log("**** Webhooks for translation finish was created at " + WEBHOOK_LOCATION); } else { console.log("Error : " + JSON.parse(body).detail); } res.send(JSON.stringify(webhookres)); }); }, defaultHandleError);
実際のコールバック実装は次のようになるはずです。
router.post("/callback", function (req, res) { console.log("**** Webhooks callback to notify translation finish was invoked !!"); oAuth2TwoLegged.authenticate().then(function (credentials) { var data = JSON.stringify(credentials); var token = JSON.parse(data).access_token; if (WEBHOOK_LOCATION != "") { var uri = WEBHOOK_LOCATION; request.delete({ url: uri, headers: { 'content-type': 'application/json', 'Authorization': 'Bearer ' + token, } }, function (error, res, body) { console.log("**** Webhooks for translation finish at " + WEBHOOK_LOCATION + " was deleted"); WEBHOOK_LOCATION = ""; }); } }, defaultHandleError); });
こういった部分が Forge の性格をよく表しています。デスクトップ製品のアドイン開発では出てこない考え方なので、少し難解に感じる方も多いようです。似たような機能の実装でも Forge/Web 開発の世界では、おもむきが大きく異なります。
機会を改めて、Webhooks のローカル開発環境でのデバッグについてご紹介したいと思います。
By Toshiaki Isezaki
コメント