チュートリアル:Github Atlas Triggers、関数、値を使用したサーバーレス コントリビューション トラッカーの構築
項目一覧
- 前提条件
- 新しいアプリを作成する
- 新しいGithubコントリビューターをようこそ
- エンドポイントを作成する
- エンドポイント関数の認証設定を更新する
- Github Webhook へのエンドポイントの接続
- Githubアクセス トークンを取得する
- トークンを値として保存
- Github APIクライアントのインストール
- エンドポイント ロジックの記述
- エンドポイントをテストする
- 週次コミュニティ レポートの生成
- レポートを生成するリポジトリを指定する
- レポートを生成する関数の作成
- 週ごとのレポートの生成と保存
- レポート通知の送信
- レポートトリガーをテストする
- 次のステップ
- 構築を続ける
- ドキュメントを調べる
- フィードバックを送る
- コミュニティに参加する
完了までの推定時間: 30 分
このチュートリアルでは、 Atlas App Servicesを使用して、 Githubリポジトリを監視し、コントリビューションを追跡するサーバーレス アプリケーションを構築します。
ビルドするApp Services Appには、いくつかの機能があります。
MongoDB Atlas コレクションでプロジェクトに貢献したユーザーを追跡します。
プルリクエストを開くか、問題をファイルするときに、新しいコンフィギュレーションを呼び出すコメントを残す。
リポジトリへの貢献を要約する週次レポートを生成して送信します。
このチュートリアルを完了すると、次のタスクを実行する方法がわかります。
アプリのロジックを取り扱うサーバーレス関数を記述して実行します。
API キーなどの静的データを値に保存してアクセスします。
API を介して外部サービスに接続する
前提条件
このチュートリアルを開始する前に、以下のものが必要です。
Githubリポジトリ。 ビルドするアプリは、このリポジトリへの貢献を追跡します。 新しいリポジトリを作成できます このチュートリアルでは、 または 、管理者アクセス権を持つ既存のリポジトリを使用します。
MongoDB Atlas クラスター。 まだクラスターがない場合は、 MongoDB Atlas に登録して無料のクラスターを作成してください 。
また、このチュートリアルでは配置案ワークフローを使用していないことにも注意してください。 配置案は、単一のユニットとして配置または破棄できるアプリ変更のコレクションです。 配置案を無効にしていない限り、変更を配置案に保存してから、手動で配置する必要がある場合があります。
新しいアプリを作成する
まず、App Services でアプリケーションを作成する必要があります。
アプリを作成するには
上部のナビゲーションで、 [ App Servicesをクリックします。
[Create a New App] をクリックします。
アプリ
github-tracker-tutorial
と名付けます。クラスターを選択して、新しいアプリにリンクします。
[Create App Service] をクリックします。
新しいGithubコントリビューターをようこそ
Githubリポジトリ Webhook を使用してアプリを リポジトリに接続しますGithub 。Webhook は、新しいコミットやプル リクエストなどの何らかのイベントがリポジトリで発生するたびに、アプリに通知します。 各イベントはサーバーレス関数を実行し、応答して何も実行できます。
このチュートリアルでは、 を使用しますGithubREST API リポジトリで最初のプルリクエストまたは発行を開くたびに、コンフィギュレーションサーバーにようこそメッセージを送信します。
エンドポイントを作成する
Webhook は、アプリが管理する URL にイベントに関するリクエストを送信することで機能します。 アプリ内で、Webhook リクエストを受信して処理するには、一意の URL でカスタム エンドポイントを公開する必要があります。
エンドポイントを作成するには、次の手順に従います。
左側のナビゲーション メニューで、[ HTTPS Endpoints ] をクリックします。
[Add An Endpoint] をクリックします。
エンドポイント ルート
/greetNewContributors
と名付けます。Operation Typeの下で、エンドポイント コールバック URL をコピーします。 後でGithub Webhook を設定する際に必要になります。
HTTP メソッドはPOSTに設定したままにします。
認可にはRequire a Secretを選択します。
Enter a new secret name and click Create to create a new secret. 次に、シークレット値として
tutorial
を入力します。 これには、すべての受信リクエストでリクエスト URL にクエリ パラメータsecret=tutorial
が含まれている必要があります。エンドポイント用に新しいAtlas Functionを作成し、
endpoints/greetNewContributors
と名付けます。ここでは、他の作業をせずに着信呼び出しにのみ応答する基本的なハンドラーを設定します。 次のコードを 関数本体にコピーします。
exports = async function greetNewContributors(request, response) { return response .setStatusCode(200) .setBody("Successfully received a GitHub webhook event") } Saveをクリックしてエンドポイントを配置します。
エンドポイント関数の認証設定を更新する
アプリでエンドポイントを作成したので、 Github Webhook が受け入れられるように、エンドポイントの関数の認証設定を変更する必要があります。
関数の認証設定を更新するには:
左側のナビゲーション メニューで、[ Functions ] をクリックします。
エンドポイント関数を見つけて選択します。
[Settings] をクリックします。
Authenticationの下で、認証方法をSystemに変更します。
関数を配置するには、 Saveをクリックします。
Github Webhook へのエンドポイントの接続
エンドポイント関数をGoで使用できるようにしたら、イベントをエンドポイントに送信する Webhook をGithubリポジトリに設定する必要があります。
リポジトリに Webhook を作成するには、次の手順に従います。
リポジトリの設定を開き、左側のナビゲーション メニューで [ Webhooks ] を選択します。
新しい Webhook を追加するPayload URL を作成したエンドポイントの URL に設定し、
secret
クエリ パラメータをシークレット値に設定します(例:?secret=tutorial
。ペイロード URL は次のようになりますが、アプリの配置モデルによっていくつか違いがあります。 URL の末尾に?secret=tutorial
が追加されていることに注意します。https://us-west-2.aws.data.mongodb-api.com/app/<App ID>/endpoint/greetNewContributors?secret=tutorial Webhook コンテンツタイプをapplication/jsonに設定します。
Secretは空のままにします。 ここに入力された値は HTTPS エンドポイントによって無視されるため、前の手順ではペイロード URL のクエリ パラメーターとしてシークレットを追加しています。
を選択して個々のイベントを選択し、 IssuesとPull requestsのイベントのみを送信するように Webhook を構成します。
新しい Webhook を保存するには、 Add webhookをクリックします。
Webhook がエンドポイントを正常に呼び出すことを確認するには、Atlas App Services のアプリケーション ログでEndpoint
型のエントリを確認します。 左側のナビゲーション メニューでLogsをクリックすると、そのフィールドにアクセスできます。
Webhook のリクエスト ログ を確認することもできます WebhookGithub Recent Deliveriesの設定ページの の下の の。成功した各リクエストの横には緑色のチェックマークが表示されます。
Githubアクセス トークンを取得する
これで、 Githubからエンドポイントにイベントを送信するように Webhook が設定されました。 ただし、 Github APIを使用してエンドポイント内のイベントに応答するにはアクセス トークンが必要です。 このチュートリアルではパーソナル アクセス トークンを使用しますが、 Githubアプリを設定して 代わりにそのトークンを使用することもできます。
パーソナル アクセス トークンを作成するには、次の手順に従います。
Githubユーザー設定(リポジトリ設定ではない)を開き、左側のナビゲーション メニューで [Developer settings] を選択します。
左側のナビゲーション メニューで [] を選択し、[ Generate new token Personal access tokensクリックします。
わかりやすい名前と適切な有効期限でトークンを設定します。 これはチュートリアルであるため、7 日後にトークンを期限切れにすることを検討してください。
repo
の範囲を選択します。[Generate token] をクリックします。
再度アクセスできるように、トークンを安全な場所にコピーします。 この時点から、 Githubは再度トークンを表示しません。
トークンを値として保存
アプリに戻り、先ほど生成したパーソナル アクセス トークンを保持するために新しい値を追加します。 関数にトークンをハードコーディングしなくても、エンドポイントから値を参照できます。
値を作成するには
左側のナビゲーション メニューで、[ Values ] をクリックします。
[Create New Value] をクリックします。
値を
GitHubAccessToken
と名付けます。タイプはValueのままにします。
パーソナル アクセス トークンを 値の入力に貼り付けます。 値は有効な JSON である必要があるため、引用符が含まれていることを確認してください。
[Save] をクリックします。
Github APIクライアントのインストール
エンドポイントはGithubのREST APIとやり取りしてコメントを返します。 組み込みのcontext.http
クライアントまたは外部ライブラリを使用して、HTTP リクエストを直接 API に記述して送信することができます。 ただし、このチュートリアルでは、Github の公式の Node.js ライブラリ である MongoDB APIを使用します。 は、 をラップします。インストールが完了すると、アプリ内の任意の関数からライブラリをインポートできるようになります。
アプリに 10 個のライブラリを追加するには、次の手順に従います。
左側のナビゲーション メニューで、[ Functions ] をクリックします。
Dependencies タブを選択します。
[Add Dependency] をクリックします。
パッケージ名を入力します:
@octokit/request
。[Add] をクリックします。
App Services がパッケージをインストールするまで待ちます。 インストールは数秒で完了しますが、最大で 分かかる場合があります。
エンドポイント ロジックの記述
アクセス トークンを取得し、Ocrit をインストールしたので、エンドポイント関数を更新して、イベントを受け取ったときに実際に実行することができます。 具体的には、この関数は次のようにする必要があります。
受信する Webhook イベントを解析する
MongoDB での貢献度のログ
Github APIからコメントを追加する
Githubへの情報提供の送信
関数を更新するには:
左側のナビゲーション メニューで、[ Functions ] をクリックします。
endpoints/greetNewContributorsをクリックして、エンドポイント関数エディターを開きます。
基本的な関数を次のコードで置き換えます。
functions/endpoints/greetNewContributors.jsexports = async function greetNewContributors(request, response) { // Parse the webhook event from the incoming request. const event = JSON.parse(request.body.text()); // Don't do anything unless this is a new issue or pull request if (event.action !== "opened") { return response.setStatusCode(200); } // Get data from the GitHub webhook event. // Based on the webhook configuration the event will be one of the following: // - issues: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#issues // - pull_request: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request const sender = event.sender; const repo = event.repository; const contribution = event.issue || event.pull_request; const contribution_url = event.issue ? event.issue.url : event.pull_request.issue_url; const issue_number = contribution.number; // Record this contribution in the user's contributor document. // If this user hasn't contributed to the repo before, create a document for them. const atlas = context.services.get("mongodb-atlas"); const contributors = atlas.db("community").collection("contributors"); const contributor = await contributors.findOneAndUpdate( // Look up the user by their GitHub login { login: sender.login }, // Add this issue or pull request to their list of contributions { $push: { contributions: { date: new Date(), type: event.issue ? "issue" : "pull_request", url: contribution_url, }, }, }, // If they haven't contributed before, add them to the database { upsert: true, returnNewDocument: true } ); // Send a welcome message to first time contributors on their issue or pull request const isFirstTimeContributor = contributor.contributions.length === 1; if (isFirstTimeContributor) { const octokit = require("@octokit/request"); await octokit.request( "POST /repos/{owner}/{repo}/issues/{issue_number}/comments", { headers: { authorization: `token ${context.values.get("GitHubAccessToken")}`, }, owner: repo.owner.login, repo: repo.name, issue_number: issue_number, body: `Hi there ${sender.login} 👋 Thanks for your first contribution!`, } ); } // Configure the HTTP response sent back to GitHub return response .setStatusCode(200) .setHeader("Content-Type", "application/json") .setBody( isFirstTimeContributor ? `This is ${sender.login}'s first contribution!` : `${sender.login} has contributed before.` ); }; Saveをクリックしてエンドポイントを配置します。
エンドポイントをテストする
これで、ようこそメッセージ エンドポイントが完全に設定されるはずです。 正しく動作するかどうかをテストするには、リポジトリで新しい問題を開くか、リクエストをプルします。 エンドポイントは、これを初めて実行するとスレッドに新しいコメントを追加しますが、後続の試行ではようこそメッセージは追加されません。
Githubはリポジトリ Webhook リクエストをログに記録するため、 Githubのログ エントリを確認して、すべてが正常に動作していることを確認することもできます。 各リクエスト ログにはエンドポイントからの応答メッセージが含まれます。
Tip
テストをリセットする場合は、 Githubユーザー名を含むドキュメントを community.contributions
から削除します。 これにより、アプリは以前に貢献したことを「忘れる」ことができ、次の貢献時に受け入れられます。
週次コミュニティ レポートの生成
アプリはGithubに接続され、貢献に関する情報を保存し、新しいコントリビューターを受け入れます。 ここで、リポジトリのレポートを自動的に分析および生成するように拡張します。
レポートを生成するリポジトリを指定する
アプリでは、週ごとに生成するリポジトリを把握する方法が必要です。 このチュートリアルでは、リストを 値 でハードコードします。
オブジェクトの配列を含むGitHubProjects
という新しい値を作成します。 各オブジェクトは、 Githubリポジトリの owner
と repo
の名前を指定します。 リポジトリに のエントリを含めてください。
[ { "owner": "<GitHub Username>", "repo": "<Repository Name>" } ]
レポートを生成する関数の作成
レポート は、一定期間にわたるリポジトリへの貢献を要約するドキュメントです。 関数 を使用して、リポジトリのオンデマンド レポートを作成します。
generateCommunityReport
という名前の新しい関数を作成し、次のコードを追加します。
exports = async function generateCommunityReport({ owner, repo, startDate }) { // Look up issues and pull requests that had activity const octokit = require("@octokit/request"); const { data: issuesWithActivity } = await octokit.request( "GET /repos/{owner}/{repo}/issues", { headers: { authorization: `token ${context.values.get("GitHubAccessToken")}`, }, owner: owner, repo: repo, since: startDate, } ); // Look up users that contributed to the repo const atlas = context.services.get("mongodb-atlas"); const contributors = atlas.db("community").collection("contributors"); const allContributors = await contributors .find({ contributions: { $elemMatch: { date: { $gt: new Date(startDate) }, owner: owner, repo: repo, }, }, }) .toArray(); // Keep track of users who made their first contribution const newContributors = allContributors.filter((c) => { new Date(c.contributions[0].date) > new Date(startDate); }); // Return a report with the data return { owner, repo, startDate, issuesWithActivity, allContributors, newContributors, }; };
週ごとのレポートの生成と保存
作成した関数は、オンデマンドでリポジトリのレポートを作成します。 ただし、この時点では関数は呼び出されず、生成されたレポートはどこにも保存されません。 実際に使用するには、関数を週ごとに呼び出してリンクされたクラスターに生成されたレポートを保存するスケジュールされた Atlas trigger を作成します。
trigger を作成するには、次の手順に従います。
左側のナビゲーション メニューで、[ Triggers ] をクリックします。
[Add a Trigger] をクリックします。
trigger の種類としてScheduledを選択します。
trigger に名前を付ける
generateAndSaveCommunityReports
Advancedスケジュールタイプを選択します
次の cron スケジュールを入力して、週 1 回月曜日の午前 5 時(UTC)に実行します。
0 5 * * 1 trigger用に新しい関数を作成し、
triggers/generateAndSaveCommunityReports
と名前を付けます。[ Add Dependencyをクリックし、関数で日付を処理するために使用する
moment
をインストールします。次のコードを 関数本体にコピーします。
functions/triggers/generateAndSaveCommunityReports.jsexports = async function generateAndSaveCommunityReports() { const projects = context.values.get("GitHubProjects"); const lastMonday = getLastMonday(); // e.g. "2022-02-21T05:00:00.000Z" // Generate a report for every tracked repo const reportsForLastWeek = await Promise.all( // Call the `generateCommunityReport` function for each project projects.map(async (project) => { return context.functions.execute("generateCommunityReport", { owner: project.owner, repo: project.repo, startDate: lastMonday, }); }) ); // Save the generated reports in Atlas const atlas = context.services.get("mongodb-atlas"); const reports = atlas.db("community").collection("reports"); return await reports.insertMany(reportsForLastWeek); }; // Get an ISO string for last Monday at 5AM UTC function getLastMonday() { const moment = require("moment"); return moment(new Date().setUTCHours(5, 0, 0, 0)) .utc() .day(1 - 7) .toISOString(); } [Save] をクリックします。
このチュートリアルの前の段階の新しいエンドポイントの関数と一致するように新しい関数の認証設定を更新します。
レポート通知の送信
アプリが 1 週間ごとのレポートを自動的に生成して保存するようになりました。 しかし、そのレポートは他のユーザーが見ない場合、あまり有用ではありません。 新しいレポートをリッスンし、エンド ユーザーに送信できる形式のメッセージを作成するデータベースtriggerを作成します。
メッセージを設定するには
左側のナビゲーション メニューで、[ Triggers ] をクリックします。
[Add a Trigger] をクリックします。
trigger のタイプは [] に設定したままにしDatabase 。
trigger を
sendCommunityReport
と名付けます。trigger を
community.reports
コレクションに追加し、 Insertイベントをリッスンします。新しい各レポート ドキュメントを trigger 関数に渡される変更イベントに含めるには、 Full Documentを有効にします。
trigger用に新しい関数を作成し、
triggers/sendCommunityReport
と名前を付けます。次のコードを 関数本体にコピーします。
functions/triggers/sendCommunityReport.jsexports = async function sendCommunityReport(changeEvent) { // Pull out the report document from the database change event const report = changeEvent.fullDocument; // Format values from the report to include in the message const projectName = `${report.owner}/${report.repo}`; const moment = require("moment"); const formattedDate = moment(report.startDate).utc().format("MMMM Do, YYYY"); const numIssuesWithActivity = report.issuesWithActivity.length; const numContributors = report.allContributors.length; const numNewContributors = report.newContributors.length; // Create a message string that describes the data in the report const message = [ `# Community contributions to ${projectName} since ${formattedDate}`, `Last week, there was activity on ${numIssuesWithActivity} issues and pull requests.`, `We had ${numContributors} people contribute, including ${numNewContributors} first time contributors.`, ].join("\n"); // For this tutorial we'll just log the message, but you could use a // service to send it as an email or push notification instead. console.log(message); }; Saveをクリックして、trigger を配置します。
レポートトリガーをテストする
アプリは、週ごとにレポートを自動的に生成、保存、送信するように設定されています。 すべて機能することを確認するには、このレポート フローを手動で実行します。
スケジュールされたtrigger (triggers/generateAndSaveCommunityReports
)の関数エディターを開き、Runボタンをクリックします。 これにより、 GitHubProjects
値でリストしたすべてのリポジトリに対してオンデマンド レポートが生成され、保存されます。
確認方法
新しいレポート ドキュメントの
community.reports
を確認します。アプリのデータベースtriggerログを確認して、各レポートの形式化されたメッセージを見つけます
次のステップ
成功します。サーバーレスGithub貢献トラーを正常に設定し、このチュートリアルを終了しました。
構築を続ける
開発を続ける場合は、トグルにいくつかの新しい機能を追加してみてください。 たとえば、次のような場合です。
issue_comment のような Webhook イベントの種類を処理するようにエンドポイントを更新します。 または Pull_request_review が
Github APIからの詳細情報を含めるように週次レポートをアップデートする。
Twilio のような外部サービスへの接続 または CentGrid : ログに記録するだけでなく、メールまたは SMS 経由でレポートを実際に送信します。
ドキュメントを調べる
App Services には、アプリを強化できるサービスが多数含まれています。 これらのサービスとその使用方法の詳細については、ドキュメントの残りの部分を参照してください。
フィードバックを送る
Docsとチュートリアルの改善に常に役立てます。 このチュートリアルに提案がある場合や問題が発生した場合は、このページの下部にあるGive Feedbackをクリックしてチュートリアルを評価し、コメントを送信してください。
コミュニティに参加する
公式のMongoDB Community フォーラムは、他の開発者と交流したり、質問をして回答したり、最新の App Services 機能とリリースを最新の状態に保つのに最適な場所です。