Cloud Tasks を使用して Cloud Run 関数をトリガーする

このチュートリアルでは、App Engine アプリケーション内で Cloud Tasks を使用して Cloud Run 関数をトリガーし、スケジュールされたメールを送信する方法について説明します。

目標

  • 各コンポーネントのコードを理解する。
  • SendGrid アカウントを作成する。
  • ソースコードをダウンロードする。
  • Cloud Tasks リクエストを受信し、SendGrid API を介してメールを送信する Cloud Run 関数をデプロイする。
  • Cloud Tasks キューを作成する。
  • Cloud Tasks リクエストを認証するためのサービスアカウントを作成する。
  • ユーザーがメールを送信できるようにクライアントコードをデプロイする。

費用

Cloud Tasks、Cloud Run 関数、App Engine には無料枠があるため、無料枠でチュートリアルを実行する限り、追加の費用は発生しません。詳細については、料金をご覧ください。

始める前に

  1. Google Cloud プロジェクトの選択または作成

    [App Engine] ページに移動

  2. プロジェクトで App Engine アプリケーションを初期化します。

    1. [App Engine へようこそ] ページで [アプリケーションを作成] をクリックします。

    2. アプリケーションのリージョンを選択します。このロケーションは、Cloud Tasks リクエストの LOCATION_ID パラメータとして使用するため、メモしておいてください。App Engine コマンドで europe-west および us-central と呼ばれる 2 つのロケーションは、Cloud Tasks コマンドではそれぞれ europe-west1 および us-central1 と呼ばれます。

    3. 言語として [Node.js] を選択し、環境として [Standard] を選択します。

    4. [課金を有効にする] ポップアップが表示されたら、請求先アカウントを選択します。まだ請求先アカウントがない場合は、[請求先アカウントの作成] をクリックしてウィザードの手順を行います。

    5. [開始] ページで [次へ] をクリックします。他のことは後で対応します。

  3. Cloud Run functions と Cloud Tasks APIs を有効にします。

    API を有効にする

  4. gcloud CLI をインストールして初期化する

コードについて

このセクションでは、アプリのコードとその動作を順を追って説明します。

タスクの作成

インデックス ページは、app.yaml のハンドラを使用して提供されます。タスクの作成に必要な変数が、環境変数として渡されます。

runtime: nodejs16

env_variables:
  QUEUE_NAME: "my-queue"
  QUEUE_LOCATION: "us-central1"
  FUNCTION_URL: "https://<region>-<project_id>.cloudfunctions.net/sendEmail"
  SERVICE_ACCOUNT_EMAIL: "<member>@<project_id>.iam.gserviceaccount.com"

# Handlers for serving the index page.
handlers:
  - url: /static
    static_dir: static
  - url: /
    static_files: index.html
    upload: index.html

このコードにより、エンドポイント /send-email が作成されます。このエンドポイントは、インデックス ページからのフォーム送信を処理し、そのデータをタスク作成コードに渡します。

app.post('/send-email', (req, res) => {
  // Set the task payload to the form submission.
  const {to_name, from_name, to_email, date} = req.body;
  const payload = {to_name, from_name, to_email};

  createHttpTaskWithToken(
    process.env.GOOGLE_CLOUD_PROJECT,
    QUEUE_NAME,
    QUEUE_LOCATION,
    FUNCTION_URL,
    SERVICE_ACCOUNT_EMAIL,
    payload,
    date
  );

  res.status(202).send('📫 Your postcard is in the mail! 💌');
});

このコードでは実際にタスクが作成され、Cloud Tasks キューに送信されます。コードは、次の方法でタスクを構築します。

  • ターゲット タイプHTTP Request に指定します。

  • 使用する HTTP method とターゲットの URL を指定します。

  • ダウンストリーム アプリケーションが構造化ペイロードを解析できるように、Content-Typeヘッダーをapplication/jsonに設定します。

  • 認証を要求しているリクエスト ターゲットに Cloud Tasks が認証情報を提供できるように、サービス アカウントのメールアドレスを追加します。サービス アカウントは個別に作成されます。

  • 日付のユーザー入力が最大 30 日以内であることを確認し、フィールド scheduleTime としてリクエストに追加します。

const MAX_SCHEDULE_LIMIT = 30 * 60 * 60 * 24; // Represents 30 days in seconds.

const createHttpTaskWithToken = async function (
  project = 'my-project-id', // Your GCP Project id
  queue = 'my-queue', // Name of your Queue
  location = 'us-central1', // The GCP region of your queue
  url = 'https://example.com/taskhandler', // The full url path that the request will be sent to
  email = '<member>@<project-id>.iam.gserviceaccount.com', // Cloud IAM service account
  payload = 'Hello, World!', // The task HTTP request body
  date = new Date() // Intended date to schedule task
) {
  // Imports the Google Cloud Tasks library.
  const {v2beta3} = require('@google-cloud/tasks');

  // Instantiates a client.
  const client = new v2beta3.CloudTasksClient();

  // Construct the fully qualified queue name.
  const parent = client.queuePath(project, location, queue);

  // Convert message to buffer.
  const convertedPayload = JSON.stringify(payload);
  const body = Buffer.from(convertedPayload).toString('base64');

  const task = {
    httpRequest: {
      httpMethod: 'POST',
      url,
      oidcToken: {
        serviceAccountEmail: email,
        audience: url,
      },
      headers: {
        'Content-Type': 'application/json',
      },
      body