Docs Menu
Docs Home
/ /
Atlas App Services

チュートリアル:Github Atlas Triggers、関数、値を使用したサーバーレス コントリビューション トラッカーの構築

項目一覧

  • 前提条件
  • 新しいアプリを作成する
  • 新しいGithubコントリビューターをようこそ
  • エンドポイントを作成する
  • エンドポイント関数の認証設定を更新する
  • Github Webhook へのエンドポイントの接続
  • Githubアクセス トークンを取得する
  • トークンを値として保存
  • Github APIクライアントのインストール
  • エンドポイント ロジックの記述
  • エンドポイントをテストする
  • 週次コミュニティ レポートの生成
  • レポートを生成するリポジトリを指定する
  • レポートを生成する関数の作成
  • 週ごとのレポートの生成と保存
  • レポート通知の送信
  • レポートトリガーをテストする
  • 次のステップ
  • 構築を続ける
  • ドキュメントを調べる
  • フィードバックを送る
  • コミュニティに参加する

完了までの推定時間: 30 分

このチュートリアルでは、 Atlas App Servicesを使用して、 Githubリポジトリを監視し、コントリビューションを追跡するサーバーレス アプリケーションを構築します。

ビルドするApp Services Appには、いくつかの機能があります。

  • MongoDB Atlas コレクションでプロジェクトに貢献したユーザーを追跡します。

  • プルリクエストを開くか、問題をファイルするときに、新しいコンフィギュレーションを呼び出すコメントを残す。

  • リポジトリへの貢献を要約する週次レポートを生成して送信します。

このチュートリアルを完了すると、次のタスクを実行する方法がわかります。

このチュートリアルを開始する前に、以下のものが必要です。

  • Githubリポジトリ。 ビルドするアプリは、このリポジトリへの貢献を追跡します。 新しいリポジトリを作成できます このチュートリアルでは、 または 、管理者アクセス権を持つ既存のリポジトリを使用します。

  • MongoDB Atlas クラスター。 まだクラスターがない場合は、 MongoDB Atlas に登録して無料のクラスターを作成してください 。

また、このチュートリアルでは配置案ワークフローを使用していないことにも注意してください。 配置案は、単一のユニットとして配置または破棄できるアプリ変更のコレクションです。 配置案を無効にしていない限り、変更を配置案に保存してから、手動で配置する必要がある場合があります。

まず、App Services でアプリケーションを作成する必要があります。

アプリを作成するには

  1. cloud.mongodb.com で Atlas プロジェクトを開きます。

  2. 上部のナビゲーションで、 [ App Servicesをクリックします。

  3. [Create a New App] をクリックします。

  4. アプリ github-tracker-tutorialと名付けます。

  5. クラスターを選択して、新しいアプリにリンクします。

  6. [Create App Service] をクリックします。

Githubリポジトリ Webhook を使用してアプリを リポジトリに接続しますGithub 。Webhook は、新しいコミットやプル リクエストなどの何らかのイベントがリポジトリで発生するたびに、アプリに通知します。 各イベントはサーバーレス関数を実行し、応答して何も実行できます。

このチュートリアルでは、 を使用しますGithubREST API リポジトリで最初のプルリクエストまたは発行を開くたびに、コンフィギュレーションサーバーにようこそメッセージを送信します。

Webhook は、アプリが管理する URL にイベントに関するリクエストを送信することで機能します。 アプリ内で、Webhook リクエストを受信して処理するには、一意の URL でカスタム エンドポイントを公開する必要があります。

エンドポイントを作成するには、次の手順に従います。

  1. 左側のナビゲーション メニューで、[ HTTPS Endpoints ] をクリックします。

  2. [Add An Endpoint] をクリックします。

  3. エンドポイント ルート/greetNewContributorsと名付けます。

  4. Operation Typeの下で、エンドポイント コールバック URL をコピーします。 後でGithub Webhook を設定する際に必要になります。

  5. HTTP メソッドはPOSTに設定したままにします。

  6. 認可にはRequire a Secretを選択します。

  7. Enter a new secret name and click Create to create a new secret. 次に、シークレット値としてtutorialを入力します。 これには、すべての受信リクエストでリクエスト URL にクエリ パラメータsecret=tutorialが含まれている必要があります。

  8. エンドポイント用に新しいAtlas Functionを作成し、 endpoints/greetNewContributorsと名付けます。

  9. ここでは、他の作業をせずに着信呼び出しにのみ応答する基本的なハンドラーを設定します。 次のコードを 関数本体にコピーします。

    exports = async function greetNewContributors(request, response) {
    return response
    .setStatusCode(200)
    .setBody("Successfully received a GitHub webhook event")
    }
  10. Saveをクリックしてエンドポイントを配置します。

アプリでエンドポイントを作成したので、 Github Webhook が受け入れられるように、エンドポイントの関数の認証設定を変更する必要があります。

関数の認証設定を更新するには:

  1. 左側のナビゲーション メニューで、[ Functions ] をクリックします。

  2. エンドポイント関数を見つけて選択します。

  3. [Settings] をクリックします。

  4. Authenticationの下で、認証方法をSystemに変更します。

  5. 関数を配置するには、 Saveをクリックします。

エンドポイント関数をGoで使用できるようにしたら、イベントをエンドポイントに送信する Webhook をGithubリポジトリに設定する必要があります。

リポジトリに Webhook を作成するには、次の手順に従います。

  1. リポジトリの設定を開き、左側のナビゲーション メニューで [ Webhooks ] を選択します。

  2. 新しい 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
  3. Webhook コンテンツタイプをapplication/jsonに設定します。

  4. Secretは空のままにします。 ここに入力された値は HTTPS エンドポイントによって無視されるため、前の手順ではペイロード URL のクエリ パラメーターとしてシークレットを追加しています。

  5. を選択して個々のイベントを選択し、 IssuesPull requestsのイベントのみを送信するように Webhook を構成します。

  6. 新しい Webhook を保存するには、 Add webhookをクリックします。

Webhook がエンドポイントを正常に呼び出すことを確認するには、Atlas App Services のアプリケーション ログEndpoint型のエントリを確認します。 左側のナビゲーション メニューでLogsをクリックすると、そのフィールドにアクセスできます。

Webhook のリクエスト ログ を確認することもできます WebhookGithub Recent Deliveriesの設定ページの の下の の。成功した各リクエストの横には緑色のチェックマークが表示されます。

ping イベントに対するカスタム エンドポイントの応答を示す Github のログ エントリ。 レスポンスのステータス コードは 200 で、レスポンス本文には「 Github Webhook イベントが正常に受信されました」と表示されています。

これで、 Githubからエンドポイントにイベントを送信するように Webhook が設定されました。 ただし、 Github APIを使用してエンドポイント内のイベントに応答するにはアクセス トークンが必要です。 このチュートリアルではパーソナル アクセス トークンを使用しますが、 Githubアプリを設定して 代わりにそのトークンを使用することもできます。

パーソナル アクセス トークンを作成するには、次の手順に従います。

  1. Githubユーザー設定(リポジトリ設定ではない)を開き、左側のナビゲーション メニューで [Developer settings] を選択します。

  2. 左側のナビゲーション メニューで [] を選択し、[ Generate new token Personal access tokensクリックします。

  3. わかりやすい名前と適切な有効期限でトークンを設定します。 これはチュートリアルであるため、7 日後にトークンを期限切れにすることを検討してください。

  4. repoの範囲を選択します。

  5. [Generate token] をクリックします。

  6. 再度アクセスできるように、トークンを安全な場所にコピーします。 この時点から、 Githubは再度トークンを表示しません。

アプリに戻り、先ほど生成したパーソナル アクセス トークンを保持するために新しい値を追加します。 関数にトークンをハードコーディングしなくても、エンドポイントから値を参照できます。

値を作成するには

  1. 左側のナビゲーション メニューで、[ Values ] をクリックします。

  2. [Create New Value] をクリックします。

  3. 値をGitHubAccessTokenと名付けます。

  4. タイプはValueのままにします。

  5. パーソナル アクセス トークンを 値の入力に貼り付けます。 値は有効な JSON である必要があるため、引用符が含まれていることを確認してください。

  6. [Save] をクリックします。

エンドポイントはGithubのREST APIとやり取りしてコメントを返します。 組み込みのcontext.httpクライアントまたは外部ライブラリを使用して、HTTP リクエストを直接 API に記述して送信することができます。 ただし、このチュートリアルでは、Github の公式の Node.js ライブラリ である MongoDB APIを使用します。 は、 をラップします。インストールが完了すると、アプリ内の任意の関数からライブラリをインポートできるようになります。

アプリに 10 個のライブラリを追加するには、次の手順に従います。

  1. 左側のナビゲーション メニューで、[ Functions ] をクリックします。

  2. Dependencies タブを選択します。

  3. [Add Dependency] をクリックします。

  4. パッケージ名を入力します: @octokit/request

  5. [Add] をクリックします。

  6. App Services がパッケージをインストールするまで待ちます。 インストールは数秒で完了しますが、最大で 分かかる場合があります。

アクセス トークンを取得し、Ocrit をインストールしたので、エンドポイント関数を更新して、イベントを受け取ったときに実際に実行することができます。 具体的には、この関数は次のようにする必要があります。

  • 受信する Webhook イベントを解析する

  • MongoDB での貢献度のログ

  • Github APIからコメントを追加する

  • Githubへの情報提供の送信

関数を更新するには:

  1. 左側のナビゲーション メニューで、[ Functions ] をクリックします。

  2. endpoints/greetNewContributorsをクリックして、エンドポイント関数エディターを開きます。

  3. 基本的な関数を次のコードで置き換えます。

    functions/endpoints/greetNewContributors.js
    exports = 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.`
    );
    };
  4. Saveをクリックしてエンドポイントを配置します。

これで、ようこそメッセージ エンドポイントが完全に設定されるはずです。 正しく動作するかどうかをテストするには、リポジトリで新しい問題を開くか、リクエストをプルします。 エンドポイントは、これを初めて実行するとスレッドに新しいコメントを追加しますが、後続の試行ではようこそメッセージは追加されません。

エンドポイントによって追加されたGithubのようこそコメントの例。

Githubはリポジトリ Webhook リクエストをログに記録するため、 Githubのログ エントリを確認して、すべてが正常に動作していることを確認することもできます。 各リクエスト ログにはエンドポイントからの応答メッセージが含まれます。

Githubのログ エントリで、初めてコンストラクターに対するカスタム エンドポイントの応答を表示

Tip

テストをリセットする場合は、 Githubユーザー名を含むドキュメントを community.contributions から削除します。 これにより、アプリは以前に貢献したことを「忘れる」ことができ、次の貢献時に受け入れられます。

アプリはGithubに接続され、貢献に関する情報を保存し、新しいコントリビューターを受け入れます。 ここで、リポジトリのレポートを自動的に分析および生成するように拡張します。

アプリでは、週ごとに生成するリポジトリを把握する方法が必要です。 このチュートリアルでは、リストを 値 でハードコードします。

オブジェクトの配列を含むGitHubProjectsという新しい値を作成します。 各オブジェクトは、 Githubリポジトリの ownerrepo の名前を指定します。 リポジトリに のエントリを含めてください。

values/projects.json
[
{ "owner": "<GitHub Username>", "repo": "<Repository Name>" }
]

レポート は、一定期間にわたるリポジトリへの貢献を要約するドキュメントです。 関数 を使用して、リポジトリのオンデマンド レポートを作成します。

generateCommunityReportという名前の新しい関数を作成し、次のコードを追加します。

functions/generateCommunityReport.js
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 を作成するには、次の手順に従います。

  1. 左側のナビゲーション メニューで、[ Triggers ] をクリックします。

  2. [Add a Trigger] をクリックします。

  3. trigger の種類としてScheduledを選択します。

  4. trigger に名前を付ける generateAndSaveCommunityReports

  5. Advancedスケジュールタイプを選択します

  6. 次の cron スケジュールを入力して、週 1 回月曜日の午前 5 時(UTC)に実行します。

    0 5 * * 1
  7. trigger用に新しい関数を作成し、triggers/generateAndSaveCommunityReports と名前を付けます。

  8. [ Add Dependencyをクリックし、関数で日付を処理するために使用するmomentをインストールします。

  9. 次のコードを 関数本体にコピーします。

    functions/triggers/generateAndSaveCommunityReports.js
    exports = 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();
    }
  10. [Save] をクリックします。

  11. このチュートリアルの前の段階の新しいエンドポイントの関数と一致するように新しい関数の認証設定を更新します。

アプリが 1 週間ごとのレポートを自動的に生成して保存するようになりました。 しかし、そのレポートは他のユーザーが見ない場合、あまり有用ではありません。 新しいレポートをリッスンし、エンド ユーザーに送信できる形式のメッセージを作成するデータベースtriggerを作成します。

メッセージを設定するには

  1. 左側のナビゲーション メニューで、[ Triggers ] をクリックします。

  2. [Add a Trigger] をクリックします。

  3. trigger のタイプは [] に設定したままにしDatabase

  4. trigger をsendCommunityReportと名付けます。

  5. trigger をcommunity.reportsコレクションに追加し、 Insertイベントをリッスンします。

  6. 新しい各レポート ドキュメントを trigger 関数に渡される変更イベントに含めるには、 Full Documentを有効にします。

  7. trigger用に新しい関数を作成し、triggers/sendCommunityReport と名前を付けます。

  8. 次のコードを 関数本体にコピーします。

    functions/triggers/sendCommunityReport.js
    exports = 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);
    };
  9. Saveをクリックして、trigger を配置します。

アプリは、週ごとにレポートを自動的に生成、保存、送信するように設定されています。 すべて機能することを確認するには、このレポート フローを手動で実行します。

スケジュールされたtrigger (triggers/generateAndSaveCommunityReports)の関数エディターを開き、Runボタンをクリックします。 これにより、 GitHubProjects値でリストしたすべてのリポジトリに対してオンデマンド レポートが生成され、保存されます。

確認方法

  1. 新しいレポート ドキュメントのcommunity.reportsを確認します。

  2. アプリのデータベースtriggerログを確認して、各レポートの形式化されたメッセージを見つけます

成功します。サーバーレスGithub貢献トラーを正常に設定し、このチュートリアルを終了しました。

開発を続ける場合は、トグルにいくつかの新しい機能を追加してみてください。 たとえば、次のような場合です。

App Services には、アプリを強化できるサービスが多数含まれています。 これらのサービスとその使用方法の詳細については、ドキュメントの残りの部分を参照してください。

Docsとチュートリアルの改善に常に役立てます。 このチュートリアルに提案がある場合や問題が発生した場合は、このページの下部にあるGive Feedbackをクリックしてチュートリアルを評価し、コメントを送信してください。

公式のMongoDB Community フォーラムは、他の開発者と交流したり、質問をして回答したり、最新の App Services 機能とリリースを最新の状態に保つのに最適な場所です。

次へ

Atlas アプリケーション サービスとは