7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SharePoint Webhook検証(2): Webhookレシーバーの設定

Last updated at Posted at 2023-02-26

はじめに

前回の記事 SharePoint Webhook検証(1): Webhook作成&通知フロー では、
SharePoint Webhookの仕組みおよび作成&通知フローを確認しました。
今回は、Webhookレシーバーの要件と実装について確認します。

Webhookの作成&通知フローのおさらい

  • Webhook作成フロー
  • Webhook通知フロー

Webhookレシーバー(Receiver)の役割

上のシーケンス図で示しているように、Webhookレシーバーは、SharePointとユーザ・管理者の間で仲介役を担います。
SharePointからの変更通知を、一旦Webhookレシーバーが受け取り、管理者に情報を渡すなど制御を行います。

Webhookレシーバーの要件

Webhookレシーバーは、以下二つの機能を持つ必要があります。

  • Webhook作成時の検証機能
    • SharePointからのリクエストからvalidationTokenの値を取得
    • validationTokenの値をレスポンスに含め、SharePointに返す
  • Webhook通知を受け取りハンドリング
    • SharePointからの更新通知を受信したら、レスポンスを返す
    • 受信イベントの内容を記録または管理者に渡す

Webhookレシーバーの実装

Webhookレシーバーの実装はいくつか方法が考えられます。

  • Microsoftチュートリアルでは、Visual Studio Web APIを使用しています

  • 本記事では、NGINX(エンジンエクス)を使用して、Webhookレシーバーを作成します

Wikipediaから、NGINXとは、

  • フリーかつオープンソースなWebサーバ
  • 処理性能・高い並行性・メモリ使用量の小ささに焦点を当てて開発された
  • HTTP, HTTPS, SMTP, POP3, IMAPのリバースプロキシの機能を持つ
  • ロードバランサ、HTTPキャッシュなどの機能も持つ

NGINXを用いてWebhookレシーバーを作成する手順

  • 必要なNGINX拡張モジュール

    • ngx_http_js_module.so
      • ロケーションと変数ハンドラーの実装にnjsスクリプト言語を使用するため必要
    • ngx_http_echo_module.so
      • リクエストのヘッダーとボディ情報をNGINXアクセスログに記録するため必要
  • Webhookレシーバーの処理を行うnjsスクリプト

webhook.js
import qs from 'querystring';

// リクエストheaderをJSON形式で取得
function stringify_headers(r) {
    return JSON.stringify(r.headersIn);
}

// リクエストから検証トークンを取得
function get_validation_token(r) {
    var token = r.args["validationToken"];
    return token ? token : '';
}

export default { stringify_headers, get_validation_token };
  • nginx.confにWebhookレシーバーに必要な設定を追加
nginx.conf
... ...
# 動的モジュールをロード
load_module modules/ngx_http_echo_module.so;
load_module modules/ngx_http_js_module.so;
... ...
http {
    js_import webhook.js;
    js_set $headers_json webhook.stringify_headers;
    js_set $validation_token webhook.get_validation_token;

    # アクセスログにリクエストのヘッダーとボディを記録
    log_format ltsv escape=none 'request_method:$request_method\t'
                            'uri:$request_uri\t'
                            'status:$status\t'
                            'request_header:$headers_json\t'
                            'request_body:$request_body';
    access_log /var/log/nginx/access.log ltsv;
    ... ...
    server {
       location /sharepoint-webhook {
            # SharePointからのWebhook作成リクエストの場合、検証トークンが含まれる
            if ( $validation_token ) {
                return 200 $validation_token;
            }
            # SharePointからのWebhook通知リクエストの場合、ヘッダーとボディをログに記録
            echo_read_request_body;
            echo $request_body;
        }

Webhook作成の動作確認

  • Graph APIを使用して、Subscription作成リクエストを送る
POST https://graph.microsoft.com/v1.0/subscriptions
ボディ:
{
  "changeType": "updated",
  "notificationUrl": "https://test.net/sharepoint-webhook",
  "resource": "/sites/test.sharepoint.com,zzzzzz/drives/b!xxxxxxxx/root",
  "expirationDateTime": "2023-06-01T18:23:45.9356913Z",
  "clientState": "yyyyyyyyyyyyy"
}
  • SharePointからのNGINXへ検証リクエストが届く

NGINXのアクセスログ

request_method:POST
uri:/sharepoint-webhook?validationToken=Validation%3a+Testing+client+application+reachability+for+subscription+Request-Id%3a+yyyyyyyy
status:200
request_header:{
  "Accept":"text/plain",
  "Content-Type":"text/plain; charset=utf-8",
  "Host":"test.net",
  "Content-Length":"0",
  "Connection":"Keep-Alive"
}
request_body:
  • NGINXからSharePointへ検証トークンを含めたレスポンスを返却
{
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#subscriptions/$entity",
    "id": "aaaaaaaaaaaaaaaaaaa",
    "resource": "/sites/test.sharepoint.com,zzzzzz/drives/b!xxxxxxxx/root",
    "applicationId": "bbbbbbbbbb",
    "changeType": "updated",
    "clientState": "yyyyyyyyyyyyy",
    "notificationUrl": "https://test.net/sharepoint-webhook",
    "notificationQueryOptions": null,
    "lifecycleNotificationUrl": null,
    "expirationDateTime": "2023-06-01T18:23:45.9356913Z",
    "creatorId": "cccccccccccccccccccccc",
    "includeResourceData": null,
    "latestSupportedTlsVersion": "v1_2",
    "encryptionCertificate": null,
    "encryptionCertificateId": null,
    "notificationUrlAppId": null
}

Webhook通知の動作確認

  • SharePoint上でWebhook対象のドキュメントに対して、コピーなどの操作を行う

  • SharePointから変更通知がNGINXに届く

NGINXのアクセスログ

request_method:POST
uri:/sharepoint-webhook
status:200
request_header:{
  "Content-Type":"application/json; charset=utf-8",
  "Host":"test.net",
  "Content-Length":"xxx",
  "Connection":"Keep-Alive"
}
request_body:{
  "value":[{
    "subscriptionId":"xxxxxxxxxxxxxxx",
    "clientState":"yyyyyyyyyyyyy",
    "resource":"/sites/test.sharepoint.com,zzzzzz/drives/b!xxxxxxx/root",
    "tenantId":"kkkkkkkkkkkkkk",
    "resourceData":null,
    "subscriptionExpirationDateTime":"2023-06-01T18:23:45.9356913+00:00",
    "changeType":"updated"}]
}

おわりに

SharePointのWebhookレシーバーについて検証してみました。
SharePointドキュメントに対して、予期せぬ追加・変更が行われた場合など、
Webhookを用いて、ほぼリアルタイムで監視できるようになりそうです。

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?