GitHub Webhook: インターネット上でWebhookイベントを受け取るための自分たちの「サーバー」をNodeJsで作る

私たちは、GitHub Webhookイベントを受け取るためのHTTP「サーバー」をNodeJsで書いています。サーバーをインターネット経由で公開するためにngrokプログラムを使用しています。最終的に、GitHubリポジトリを設定してそのリポジトリにWebhookをいくつか定義すると、公開されたNodeJsサーバーがGitHub Webhookの通知をどのように処理するかを見てみます。

GitHubは、リポジトリで発生するアクティビティを購読して受け取ります。これをWebhooksと言います。これが公式のドキュメントページです About webhooks

購読するには、GitHub Webhookのイベントから通知を処理する方法を理解する公開HTTPエンドポイントを持っている必要があります。私たちは、このエンドポイントを実装する「サーバー」アプリケーションをNodeJsで書きます。それは、受け取った通知をコンソールにログするだけのことをします。

「サーバー」を公開するために、GitHubngrokの使用を推奨しています。このアプリケーションはローカルホストのアプリケーションをインターネット上でアクセス可能にします。

目次

環境

この投稿では、Ubuntuバージョン22.10 kineticNodeJsバージョン18.7.0ngrokバージョン3.1.1を使用しています。

ただし、NodeJsngrokはWindows 10でも利用可能です。この投稿で議論されたすべての資料はWindows 10でも機能するはずですが、テストはしていませんが、Pythonを使ってWindows 10で類似のものをしたことがあります。

NodeJsの私たちの「サーバー」

主な目的は、フローを示すことです—すべてがどのように連携して機能するか:私たちはそれを最小限の機能的な一部に留めています。

GitHubでイベントを購読した後、そのイベントが発生するたびに、GitHubは**POST**通知をWebhookを設定するときに指定するPayload URLに送信します。この投稿の文脈では、Payload URLは、サーバー上で実装する単なるPOSTルートです。

Payload URLメソッドは非常にシンプルです:GitHubがそれに与えるものは何でもコンソールに印刷し、GitHubが通知を受け取ったと知るためにテキスト応答を送り返します。

デフォルトのルート(/)はGETで、単に_「Hello, World!」_メッセージを送り返すだけです。

私はコードを/home/behai/webwork/nodejsの下で実行しています。

/home/behai/webwork/nodejs/package.jsonの内容:

{
    "name": "Git Webhook",
    "version": "0.0.1",
    "dependencies": {
        "express": "latest",
        "body-parser": "latest"
    },
    "author": "Van Be Hai Nguyen",
    "description": "Learn Git Webhook Server"
}

私たちは、Express web frameworkとミドルウェアbody-parserの最新バージョンを使用しています。

パッケージをインストールするには、/home/behai/webwork/nodejs内で以下を実行します:

$ npm i
/home/behai/webwork/nodejs/webhook.jsの内容:
const express = require('express');
const bodyParser = require("body-parser")

const app = express();

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

app.get('/', function (req, res) {
    res.send("Hello, World!")
});

app.post('/git-webhook', function(req, res) {
    let data = req.body;
    console.log(data);
    res.send('Received!');
})

const port = 8008;

app.listen(port, function() {
    console.log( `App listening on port ${port}!` )
});
  • サーバーはポート8008でリッスンしています。
  • Payload URLのルートは/git-webhookです。つまり、localhost上の完全なURLはhttp://localhost:8008/git-webhookです。
  • Payload URLメソッドの応答はシンプルにReceived!です。
  • デフォルトのルートhttp://localhost:8008Hello, World!で応答します。

以下で実行します:

$ node webhook.js

Ubuntuマシンでは、コマンドラインでcurl http://localhost:8008とブラウザでhttp://localhost:8008からの応答はHello, World!になります。

Ubuntu 22.10 kinetic用ngrokのインストール

公式ページGetting Started with ngrokは、異なるオペレーティングシステムでのインストールプロセスを説明しています。この手順のステップ1はスキップしましたが、私はすでに自分のウェブサーバーのアプリケーションを持っていました。

ステップ2: ngrokエージェントのインストールでは、**「Linuxの場合、Aptを使用する」**の下に挙げられている長くて恐ろしそうなコマンドを実行しました。

そして、ステップ3: エージェントをngrokアカウントに接続するの下に記述されているすべての指示を完了しました。

ステップ4: ngrokの開始をよく読んでください。上述のサーバーが8008ポートでリッスンしており、まだ実行中であれば、ngrokを次のように開始します:

$ ngrok http 8008

画面は次のようになります:

https://53a0-58-109-142-244.au.ngrok.io/は、上記のサーバーの公開URLです:このURLを持つ人なら誰でも、私たちのプライベートネットワーク上で稼働しているサーバーにアクセスすることができます。

GitHub Payload URLは、次のようになります:https://53a0-58-109-142-244.au.ngrok.io/git-webhook

ngrokを無料版で実行しているため、ngrokを開始するたびに異なるURLになることに注意してください! これを覚えておいてくださいが、学習目的では問題にはなりません。

Windows 10マシンからPostmanを使ってhttps://53a0-58-109-142-244.au.ngrok.io/にリクエストします(ブラウザでも行えます)、期待通りの応答が得られます。

ngrokもリクエストを記録します:

ngrokは私たちの「サーバー」と上手く動作しているようです。これでGitHub Webhookを設定し、https://53a0-58-109-142-244.au.ngrok.io/git-webhookエンドポイントをテストする準備が整いました。

GitHub Webhookのセットアップと私たちのサーバーのテスト

WebhooksはそれぞれのGitHubリポジトリに固有です。この目的のためにlearn-gitという新しいリポジトリを作ります。

learn-gitが作成されたら、右上隅にあるSettingsをクリックし、左側のWebhooks、右上のAdd webhookボタンをクリックします。

Payload URLにはhttps://53a0-58-109-142-244.au.ngrok.io/git-webhookを指定します。Content typeではapplication/jsonを選択します:

他の設定はデフォルトのままにして、緑色のAdd webhookボタンをクリックします:

Which events would you like to trigger this webhook? の下ではデフォルトのJust the **push** event.を選択しています。つまり、このWebhookはこのリポジトリに何かをチェックインしたときのみ私たちのサーバーに通知します。

GitHubは、ピングイベントを私たちのサーバー(つまりPayload URLへ)に送信したと教えてくれます:

上の画面によると、私たちのサーバーは問題なくこのピングイベントを受け取ったはずで、確かに、それはいくつかのJSONデータを記録し、ngrok/git-webhookエンドポイントへの新しいPOSTリクエストを記録します:

この時点で、リポジトリはまだ空です。いくつかのチェックイン、つまりpushを行いましょう。Webhookがトリガーされるはずです。

D:\learn-gitにはいくつかのファイルがあります。リポジトリを初期化してチェックインしましょう。チェックインメッセージには「Initial checking should have two files.」(「check in」を意味しています 😂)と記載されています。

Webhookはトリガーされ、私たちのサーバーは通知データを記録し、上記のチェックインメッセージに一致していることに注意してください。またngrok/git-webhookエンドポイントへの別の新しいPOSTリクエストを記録します:

GitHub learn-gitリポジトリに戻り、Webhookエリアでpayload linkをクリックします:

Recent Deliveriesタブをクリックすると、上述のような2つのイベントがあります、pushping

pushイベントを選択し、Response 200タブをクリックすると、Bodyの下に私たちのNodeJsサーバーからの応答であるテキストReceived!が表示されるはずです:

RequestタブにはHeadersPayloadの2つのセクションがあります。私たちのサーバーに投稿されるデータはPayloadデータです:GitHub Webhookのドキュメントを読めば、私たちはこのデータの意味を理解し、正しく使うことができるでしょう。

https://github.com/behai-nguyen/learn-git.gitでファイルを選択し、直接編集してコミットします。これによってpushイベントがトリガーされるはずです。確かにそれは発生し、私たちのサーバーは通知を受け取っています。メッセージに一致していることに注意してください:

js1.jsを同期し、ローカルで編集し、適切にチェックインしましょう。同期するコマンド:

ローカルでjs1.jsに変更を加え、その後チェックインします。2つのメッセージ 「Test Webhook.」「Check in from local machine via command.」 に注目:

私たちのサーバーに期待通りの応答があります。そしてngrok/git-webhookエンドポイントへの4つのPOSTリクエストを記録します:

Recent Deliveriesタブ(前に説明したもの)は今や4つのエントリがあるはずです。

この投稿を通じて提示された画面キャプチャから、既存のWebhookのプロパティを変更できるのは明らかでしょう。Payload URLも含みます。

私たちのいわゆるサーバーは非常にシンプルなため、push以外の他のWebhookイベントでも幸せに機能します。Send me everything.をテストし、learn-gitリポジトリに問題を提起しましたが、サーバーはpushのために通知を記録します。この小さなサーバーは、異なるWebhookイベントのペイロードの構造を調べるのに適しています。GitHubのドキュメントにはこの情報が含まれているはずですが、個人的にはデータを視覚化することでこれらの文書を読むのが容易になります。

これでこの投稿を終わります。役に立つと思うことを願っています。読んでくれてありがとう、そしていつものように安全に過ごしてください。

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/behainguyen/github-webhook-our-own-server-in-nodejs-to-receive-webhook-events-over-the-internet-354d