Next.jsからCloudTasksにタスクを登録する

Next.js13からCloudTasksにタスクを登録する際に、ハマったので記事にします。

事前準備

  • CloduTasksでキューを作成
  • サービスアカウントにタスク追加のためのロールを追加
  • サービスアカウントのメール、シークレットキーを環境変数に登録
  • プロジェクトID、CloduTasksのロケーション、キューを環境変数に登録
目次

@google-cloud/tasksを使わない

僕がはじめにインストールした@google-cloud/tasksのバージョンは現在最新の5.4.0でした。

@google-cloud/tasks@5.4.0はローカルでは問題なく動きますが、CloudRunにデプロイする際にCloudBuildで以下のエラーがでました。

cannot find module '/app/node_modules/@google-cloud/tasks/build/esm/src/v2/cloud_tasks_client_config.json

このエラーの解決方法として、以下の2つが挙げられていましたが、どちらもうまく動きませんでした。

@google-cloud/tasksをダウングレードする

ダウングレードすることで解決する人はいるみたいです。

npm i @google-cloud/tasks@5.1.0
npm i @google-cloud/tasks@4.1.0

しかし、@google-cloud/tasksは常に問題があるため使用しないことを勧めていました。

outputFileTracingIncludesでjsonを読み込む

ビルド時に読み込めなかったファイルをnext.config.jsのoutputFileTracingIncludesで読み込んでおくことで、解決する人がいるようです。

しかし、僕は解決できず。。

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: "standalone",
  reactStrictMode: true,
  experimental: {
    outputFileTracingIncludes: {
      '/': ['./node_modules/@google-cloud/tasks/build/esm/src/**/*.json'],
    },
  }

};

export default nextConfig;

google-auth-libraryを使ってCloudTasksにタスクを登録する

google-auth-libraryを使用するとビルドができたので、GoogleAuthで認証してからCloduTasksのキューにタスクを登録するようにしました。

import { GoogleAuth } from "google-auth-library";
import type { NextApiRequest, NextApiResponse } from "next";

export default async function createTasks(
  req: NextApiRequest,
  res: NextApiResponse
) {
  ...

  const projectId = process.env.GOOGLE_PROJECT_ID;
  const taskLocation = process.env.GOOGLE_TASKS_LOCATION;
  const taskQueue = process.env.GOOGLE_TASKS_QUEUE;
  if (!projectId || !taskLocation || !taskQueue) {
    return res.status(500).end("Missing environment variables");
  }
  const client = new GoogleAuth({
    credentials: {
      client_email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL,
      private_key: (process.env.GOOGLE_PRIVATE_KEY as string).replace(
        /\\n/g,
        "\n"
      ),
    },
    scopes: "https://www.googleapis.com/auth/cloud-platform",
  });

  const url = `https://cloudtasks.googleapis.com/v2/projects/${projectId}/locations/${taskLocation}/queues/${taskQueue}/tasks`;

  const today = new Date();
  const token = await client.getAccessToken();

  
  // タスクを作成
  const task = {
    httpRequest: {
      headers: {
        "Content-Type": "application/json",
      },
      httpMethod: "POST",
      url: "https://example.com/api/tasks/post",
      body: Buffer.from(
        JSON.stringify({
          message:'test',
        })
      ).toString("base64"),
    },
    scheduleTime: {
      seconds: Math.floor(new Date().getTime() / 1000),
    },
  };
  const response = await fetch(url, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ task }),
  });

    if (!response.ok) {
      console.log(`Error creating task: ${response.statusText}`);
    }
  }
  

  return res.status(200).end();
}
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

目次