Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

Twilio を使った GitHub SMS 通知

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、GitHub リポジトリの更新を受け取る SMS 通知システムを Workers 上で構築します。リポジトリに新しいアクティビティがあると、Worker が Twilio でテキストメッセージを送信します。

次の内容を学びます。

  • Workers で Webhook を構築する
  • Workers を GitHub と Twilio に連携する
  • Wrangler で Worker の secrets を使う
リポジトリへ変更をプッシュしたあと、スマートフォンでテキストメッセージを受け取るアニメーション GIF

始める前に

すべてのチュートリアルは、Cloudflare Workers アカウント、C3、および Wrangler のセットアップが完了している前提です。セットアップは Get started ガイド で行います。

Worker プロジェクトを作成する

まず、コマンドラインで npm create cloudflare@latest を使い、Worker プロジェクトを作成します。

npm create cloudflare@latest -- github-twilio-notifications

セットアップでは、次のオプションを選びます。

  • What would you like to start with? では、Hello World example を選びます。
  • Which template would you like to use? では、Worker only を選びます。
  • Which language do you want to use? では、JavaScript を選びます。
  • Do you want to use git for version control? では、Yes を選びます。
  • Do you want to deploy your application? では、No を選びます(デプロイ前にいくつか変更します)。

アプリケーションがデプロイされた URL を控えておきます。GitHub Webhook の設定で使います。

cd github-twilio-notifications

新しい github-sms-notifications ディレクトリでは、src/index.js が Cloudflare Workers アプリケーションのエントリポイントです。このチュートリアルの大半は、このファイルを設定します。

このチュートリアルには、GitHub アカウントとリポジトリも必要です。どちらも未設定の場合は、新しい GitHub アカウントを作成 し、新しいリポジトリを作成 してから続けます。

まず、更新を Worker へ POST する Webhook をリポジトリに作成します。Worker 内で更新をパースします。最後に、Twilio へ POST リクエストを送り、テキストメッセージを送信します。

完成したコードは、この GitHub リポジトリ で確認できます。


GitHub を設定する

まず、リポジトリに更新があったときに Worker へ POST する GitHub Webhook を設定します。

  1. GitHub リポジトリの Settings > Webhooks > Add webhook を開きます。

  2. Payload URL に、最初のデプロイ時に控えた Worker URL の /webhook パスを設定します。

  3. Content type のドロップダウンで、application/json を選びます。

  4. Secret 欄に、任意のシークレットキーを入力します。

  5. Which events would you like to trigger this webhook?Let me select individual events を選びます。通知を受け取りたいイベント(Pull requestsPushesBranch or tag creation など)を選びます。

  6. Add webhook を選び、設定を完了します。

GitHub の Webhooks 設定ダッシュボードで Webhook を設定する手順

レスポンスをパースする

ローカル環境が整ったら、Worker でリポジトリの更新をパースします。

生成された index.js は、最初は次のようになっています。

export default {
	async fetch(request, env, ctx) {
		return new Response("Hello World!");
	},
};

Requestrequest.method プロパティで、アプリケーションへのリクエストが POST かどうかを確認します。POST でない場合は、エラーレスポンスを返します。

export default {
	async fetch(request, env, ctx) {
		if (request.method !== "POST") {
			return new Response("Please send a POST request!");
		}
	},
};

次に、正しいシークレットキーでリクエストが送られているかを検証します。GitHub は シークレットキーを使って各ペイロードにハッシュ署名 を付けます。checkSignature というヘルパー関数でリクエストを確認し、ハッシュが正しいことを保証します。そのあと、リクエストを JSON としてパースし、Webhook のデータを取得できます。

async fetch(request, env, ctx) {
  if(request.method !== 'POST') {
    return new Response('Please send a POST request!');
  }
  try {
    const rawBody = await request.text();

    if (!checkSignature(rawBody, request.headers, env.GITHUB_SECRET_TOKEN)) {
      return new Response("Wrong password, try again", {status: 403});
    }
  } catch (e) {
    return new Response(`Error:  ${e}`);
  }
},

checkSignature 関数は、Node.js の crypto ライブラリで既知のシークレットキーを使って受信ペイロードをハッシュし、リクエストのハッシュと一致することを確認します。GitHub は HMAC hexdigest を使い、SHA-256 形式でハッシュを計算します。この関数は、export の前、index.js の先頭に置きます。

import { createHmac, timingSafeEqual } from "node:crypto";
import { Buffer } from "node:buffer";

function checkSignature(text, headers, githubSecretToken) {
	const hmac = createHmac("sha256", githubSecretToken);
	hmac.update(text);
	const expectedSignature = hmac.digest("hex");
	const actualSignature = headers.get("x-hub-signature-256");

	const trusted = Buffer.from(`sha256=${expectedSignature}`, "ascii");
	const untrusted = Buffer.from(actualSignature, "ascii");

	return (
		trusted.byteLength == untrusted.byteLength &&
		timingSafeEqual(trusted, untrusted)
	);
}

これを動かすには、wrangler secret putGITHUB_SECRET_TOKEN を設定します。このトークンは、GitHub Webhook を設定したときに選んだシークレットです。

npx wrangler secret put GITHUB_SECRET_TOKEN

Wrangler ファイルに nodejs_compat フラグを追加します。

{
	"compatibility_flags": [
		"nodejs_compat"
	]
}
compatibility_flags = [ "nodejs_compat" ]

Twilio でテキストを送信する

Twilio を使い、リポジトリのアクティビティについてテキストメッセージを送ります。Twilio アカウントと、テキストメッセージを受信できる電話番号が必要です。Twilio のガイド を参照してセットアップします。(Twilio が初めての場合は、インタラクティブなゲーム でプラットフォームの使い方を学び、初心者向けの無料クレジットを受け取れます。)

次に、Twilio API エンドポイントへ POST リクエストを送るヘルパー関数を作り、テキストメッセージを送信します。このエンドポイントの詳細は Twilio のリファレンス を参照してください。

Twilio へのリクエストを扱う新しい関数 sendText() を作成します。

async function sendText(accountSid, authToken, message) {
	const endpoint = `https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Messages.json`;

	const encoded = new URLSearchParams({
		To: "%YOUR_PHONE_NUMBER%",
		From: "%YOUR_TWILIO_NUMBER%",
		Body: message,
	});

	const token = btoa(`${accountSid}:${authToken}`);

	const request = {
		body: encoded,
		method: "POST",
		headers: {
			Authorization: `Basic ${token}`,
			"Content-Type": "application/x-www-form-urlencoded",
		},
	};

	const response = await fetch(endpoint, request);
	const result = await response.json();

	return Response.json(result);
}

これを動かすには、ソースコードから ACCOUNT_SIDAUTH_TOKEN を隠す secrets を設定します。コマンドラインで wrangler secret put を使って設定できます。

npx wrangler secret put TWILIO_ACCOUNT_SID
npx wrangler secret put TWILIO_AUTH_TOKEN

先ほど作った sendText 関数でテキストメッセージを送るよう、githubWebhookHandler を変更します。

async fetch(request, env, ctx) {
  if(request.method !== 'POST') {
    return new Response('Please send a POST request!');
  }
  try {
    const rawBody = await request.text();
    if (!checkSignature(rawBody, request.headers, env.GITHUB_SECRET_TOKEN)) {
      return new Response('Wrong password, try again', {status: 403});
    }

    const action = request.headers.get('X-GitHub-Event');
    const json = JSON.parse(rawBody);
    const repoName = json.repository.full_name;
    const senderName = json.sender.login;

    return await sendText(
      env.TWILIO_ACCOUNT_SID,
      env.TWILIO_AUTH_TOKEN,
      `${senderName} completed ${action} onto your repo ${repoName}`
    );
  } catch (e) {
    return new Response(`Error:  ${e}`);
  }
};

npx wrangler deploy コマンドを実行し、Worker プロジェクトを再デプロイします。

npx wrangler deploy
リポジトリへプッシュしたあと、テキストを受け取る動画

これで、GitHub の Webhook 設定で選んだ更新をリポジトリに行うと、まもなくテキストが届きます。Git を使ったことがない場合は、リポジトリへのプッシュについて GIT Push and Pull Tutorial を参照してください。

完成したコードは GitHub で確認できます。

このチュートリアルを完了すると、Workers で Webhook を構築する方法、Workers を GitHub と Twilio に連携する方法、Wrangler で Worker の secrets を使う方法を学べます。

関連リソース

役に立ちましたか?