HTTP ターゲット タスクを作成する

Cloud Tasks ハンドラは、GKECompute Engine、オンプレミス ウェブサーバーなど、外部 IP アドレスを持つ任意の HTTP エンドポイントで実行できます。タスクは、これらのサービスのいずれでも、信頼性が高く構成可能な方法で実行できます。

このページでは、基本的な HTTP Target タスクをプログラムで作成し、Cloud Tasks キューに入れる方法を示します。

HTTP ターゲットを持つタスクの場合(一般的な App Engine ターゲットとは対照的です)、タスクを作成する方法は 2 つあります。

  • BufferTask メソッド: サービスの前にタスクをバッファリングするようにキューが設定されている場合は、このメソッドを使用します。キューにはキューレベルのルーティングが必要です。 ほとんどのユースケースでは、これが最適なアプローチです。この方法では、BufferTask メソッドを使用します。

  • CreateTask メソッド: より複雑なメソッドです。タスク オブジェクトは、明示的に作成する必要があります。このメソッドは、キュー内のタスクが異なるルーティング構成を持つ場合に使用してください。この場合、タスクレベルでルーティングを指定することになり、キューレベルのルーティングは使用できません。この方法では、CreateTask メソッドを使用します。

基本的なタスクの作成(BufferTask メソッド)

このセクションでは、HTTP リクエストを送信してタスクを作成する方法について説明します。使用するメソッドは BufferTask と呼ばれます。

制限事項

BufferTask メソッドには次の制限があります。

  • クライアント ライブラリ: BufferTask メソッドは、クライアント ライブラリではサポートされていません。

  • RPC API: BufferTask メソッドは、RPC API ではサポートされていません。

  • タスクレベルのルーティング: このメソッドは、タスクレベルのルーティングをサポートしていません。この方法でタスクを作成する際にはルーティング情報を追加する場所がないため、キューレベルのルーティングを使用する必要があります(そうしないと、タスクにルーティング情報がありません)。キューでキューレベルのルーティングを使用していない場合は、HTTP タスクのキューレベル ルーティングを構成するをご覧ください。

BufferTask メソッドを呼び出す

次の例では、Cloud Tasks API の buffer エンドポイントに HTTP POST リクエストを送信してタスクを作成する方法を示します。

curl

次のコード スニペットでは、curl を使用して BufferTask メソッドでタスクを作成する例を示します。

curl -X HTTP_METHOD\
"https://cloudtasks.googleapis.com/v2/projects/PROJECT_ID/locations/LOCATION/queues/QUEUE_ID/tasks:buffer" \

以下を置き換えます。

  • HTTP_METHOD: リクエストの HTTP メソッド(例: GET または POST)。
  • PROJECT_ID: Google Cloud プロジェクトの ID。 これは、ターミナルで次のコマンドを実行することで取得できます。
    gcloud config get-value project
  • LOCATION: キューの場所
  • QUEUE_ID: キューの ID。

Python

from google.cloud import tasks_v2beta3 as tasks

import requests


def send_task_to_http_queue(
    queue: tasks.Queue, body: str = "", token: str = "", headers: dict = {}
) -> int:
    """Send a task to an HTTP queue.
    Args:
        queue: The queue to send task to.
        body: The body of the task.
        auth_token: An authorization token for the queue.
        headers: Headers to set on the task.
    Returns:
        The matching queue, or None if it doesn't exist.
    """

    # Use application default credentials if not supplied in a header
    if token:
        headers["Authorization"] = f"Bearer {token}"

    endpoint = f"https://cloudtasks.googleapis.com/v2beta3/{queue.name}/tasks:buffer"
    response = requests.post(endpoint, body, headers=headers)

    return response.status_code

高度なタスクの作成(CreateTask メソッド)

このセクションでは、タスク オブジェクトを構築してタスクを作成する方法について説明します。CreateTask メソッドを使用します。

CreateTask メソッドを使用してタスクを作成すると、タスク・オブジェクトが明示的に作成および定義されます。タスクを処理するサービスとハンドラを指定する必要があります。

タスク固有のデータは、必要に応じてハンドラに渡せます。また、タスクが実行される将来の時間をスケジューリングすることや、タスクが失敗した場合に再試行する回数を制限することなど、タスクの構成を細かく調整することもできます(詳細構成を参照)。

次の例では、Cloud Tasks クライアント ライブラリを使用し、CreateTask メソッドを呼び出してタスクを作成します。

C#


using Google.Cloud.Tasks.V2;
using Google.Protobuf;
using Google.Protobuf.WellKnownTypes;
using System;

class CreateHttpTask
{
    public string CreateTask(
        string projectId = "YOUR-PROJECT-ID",
        string location = "us-central1",
        string queue = "my-queue",
        string url = "http://example.com/taskhandler",
        string payload = "Hello World!",
        int inSeconds = 0)
    {
        CloudTasksClient client = CloudTasksClient.Create();
        QueueName parent = new QueueName(projectId, location, queue);

        var response = client.CreateTask(new CreateTaskRequest
        {
            Parent = parent.ToString(),
            Task = new Task
            {
                HttpRequest = new HttpRequest
                {
                    HttpMethod = HttpMethod.Post,
                    Url = url,
                    Body = ByteString.CopyFromUtf8(payload)
                },
                ScheduleTime = Timestamp.FromDateTime(
                    DateTime.UtcNow.AddSeconds(inSeconds))
            }
        });

        Console.WriteLine($"Created Task {response.Name}");
        return response.Name;
    }
}

Go


// Command createHTTPtask constructs and adds a task to a Cloud Tasks Queue.
package main

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb"
)

// createHTTPTask creates a new task with a HTTP target then adds it to a Queue.
func createHTTPTask(projectID, locationID, queueID, url, message string) (*taskspb.Task, error) {

	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %w", err)
	}

	return createdTask, nil
}

Java

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.HttpRequest;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;

public class CreateHttpTask {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    createTask(projectId, locationId, queueId);
  }

  // Create a task with a HTTP target using the Cloud Tasks client.
  public static void createTask(String projectId, String locationId, String queueId)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url = "https://example.com/taskhandler";
      String payload = "Hello, World!";

      // Construct the fully qualified queue name.
      String queuePath = QueueName.of(projectId, locationId, queueId).toString();

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setUrl(url)
                      .setHttpMethod(HttpMethod.POST)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

pom.xml ファイルをメモします。

<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.tasks</groupId>
  <artifactId>cloudtasks-snippets</artifactId>
  <packaging>jar</packaging>
  <name>Google Cloud Tasks Snippets</name>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.2.0</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>libraries-bom</artifactId>
        <version>26.32.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.4.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

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

async function createHttpTask() {
  // TODO(developer): Uncomment these lines and replace with your values.
  // const project = 'my-project-id';
  // const queue = 'my-queue';
  // const location = 'us-central1';
  // const url = 'https://example.com/taskhandler';
  // const payload = 'Hello, World!';
  // const inSeconds = 180;

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

  const task = {
    httpRequest: {
      headers: {
        'Content-Type': 'text/plain', // Set content type to ensure compatibility your application's request parsing
      },
      httpMethod: 'POST',
      url,
    },
  };

  if (payload) {
    task.httpRequest.body = Buffer.from(payload).toString('base64');
  }

  if (inSeconds) {
    // The time when the task is scheduled to be attempted.
    task.scheduleTime = {
      seconds: parseInt(inSeconds) + Date.now() / 1000,
    };
  }

  // Send create task request.
  console.log('Sending task:');
  console.log(task);
  const request = {parent: parent, task: task};
  const [response] = await client.createTask(request);
  console.log(`Created task ${response.name}`);
}
createHttpTask();

package.json ファイルをメモします。

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=16.0.0"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "c8 mocha -p -j 2 --timeout 30000",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^5.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^10.0.0",
    "chai": "^4.5.0",
    "mocha": "^10.0.0",
    "uuid": "^10.0.0"
  }
}

PHP

use Google\Cloud\Tasks\V2\Client\CloudTasksClient;
use Google\Cloud\Tasks\V2\CreateTaskRequest;
use Google\Cloud\Tasks\V2\HttpMethod;
use Google\Cloud\Tasks\V2\HttpRequest;
use Google\Cloud\Tasks\V2\Task;

/** Uncomment and populate these variables in your code */
// $projectId = 'The Google project ID';
// $locationId = 'The Location ID';
// $queueId = 'The Cloud Tasks Queue ID';
// $url = 'The full url path that the task request will be sent to.'
// $payload = 'The payload your task should carry to the task handler. Optional';

// Instantiate the client and queue name.
$client = new CloudTasksClient();
$queueName = $client->queueName($projectId, $locationId, $queueId);

// Create an Http Request Object.
$httpRequest = new HttpRequest();
// The full url path that the task request will be sent to.
$httpRequest->setUrl($url);
// POST is the default HTTP method, but any HTTP method can be used.
$httpRequest->setHttpMethod(HttpMethod::POST);
// Setting a body value is only compatible with HTTP POST and PUT requests.
if (!empty($payload)) {
    $httpRequest->setBody($payload);
}

// Create a Cloud Task object.
$task = new Task();
$task->setHttpRequest($httpRequest);

// Send request and print the task name.
$request = (new CreateTaskRequest())
    ->setParent($queueName)
    ->setTask($task);
$response = $client->createTask($request);
printf('Created task %s' . PHP_EOL, $response->getName());

composer.json ファイルをメモします。

{
    "require": {
        "google/cloud-tasks": "^1.14"
    }
}

Python

import datetime
import json
from typing import Dict, Optional

from google.cloud import tasks_v2
from google.protobuf import duration_pb2, timestamp_pb2


def create_http_task(
    project: str,
    location: str,
    queue: str,
    url: str,
    json_payload: Dict,
    scheduled_seconds_from_now: Optional[int] = None,
    task_id: Optional[str] = None,
    deadline_in_seconds: Optional[int] = None,
) -> tasks_v2.Task:
    """Create an HTTP POST task with a JSON payload.
    Args:
        project: The project ID where the queue is located.
        location: The location where the queue is located.
        queue: The ID of the queue to add the task to.
        url: The target URL of the task.
        json_payload: The JSON payload to send.
        scheduled_seconds_from_now: Seconds from now to schedule the task for.
        task_id: ID to use for the newly created task.
        deadline_in_seconds: The deadline in seconds for task.
    Returns:
        The newly created task.
    """

    # Create a client.
    client = tasks_v2.CloudTasksClient()

    # Construct the task.
    task = tasks_v2.Task(
        http_request=tasks_v2.HttpRequest(
            http_method=tasks_v2.HttpMethod.POST,
            url=url,
            headers={"Content-type": "application/json"},
            body=json.dumps(json_payload).encode(),
        ),
        name=(
            client.task_path(project, location, queue, task_id)
            if task_id is not None
            else None
        ),
    )

    # Convert "seconds from now" to an absolute Protobuf Timestamp
    if scheduled_seconds_from_now is not None:
        timestamp = timestamp_pb2.Timestamp()
        timestamp.FromDatetime(
            datetime.datetime.utcnow()
            + datetime.timedelta(seconds=scheduled_seconds_from_now)
        )
        task.schedule_time = timestamp

    # Convert "deadline in seconds" to a Protobuf Duration
    if deadline_in_seconds is not None:
        duration = duration_pb2.Duration()
        duration.FromSeconds(deadline_in_seconds)
        task.dispatch_deadline = duration

    # Use the client to send a CreateTaskRequest.
    return client.create_task(
        tasks_v2.CreateTaskRequest(
            # The queue to add the task to
            parent=client.queue_path(project, location, queue),
            # The task itself
            task=task,
        )
    )

requirements.txt ファイルをメモします。

google-cloud-tasks==2.13.1

Ruby

require "google/cloud/tasks"

# Create a Task with an HTTP Target
#
# @param [String] project_id Your Google Cloud Project ID.
# @param [String] location_id Your Google Cloud Project Location ID.
# @param [String] queue_id Your Google Cloud Tasks Queue ID.
# @param [String] url The full path to sent the task request to.
# @param [String] payload The request body of your task.
# @param [Integer] seconds The delay, in seconds, to process your task.
def create_http_task project_id, location_id, queue_id, url, payload: nil, seconds: nil
  # Instantiates a client.
  client = Google::Cloud::Tasks.cloud_tasks

  # Construct the fully qualified queue name.
  parent = client.queue_path project: project_id, location: location_id, queue: queue_id

  # Construct task.
  task = {
    http_request: {
      http_method: "POST",
      url:         url
    }
  }

  # Add payload to task body.
  task[:http_request][:body] = payload if payload

  # Add scheduled time to task.
  if seconds
    timestamp = Google::Protobuf::Timestamp.new
    timestamp.seconds = Time.now.to_i + seconds.to_i
    task[:schedule_time] = timestamp
  end

  # Send create task request.
  puts "Sending task #{task}"

  response = client.create_task parent: parent, task: task

  puts "Created task #{response.name}" if response.name
end

HTTP ターゲット ハンドラの認証のサービス アカウントの設定

Cloud Tasks から HTTP ターゲット ハンドラを呼び出すことができます。このハンドラにアクセスするには認証が必要であり、サービス アカウントに適切な認証情報が設定されている必要があります。

現在使用しているサービス アカウントがある場合は、適切なロールを付与します。ここでは、この機能専用の新しいサービス アカウントを作成する方法について説明します。Cloud Tasks の認証に使用する既存または新しいサービス アカウントは、Cloud Tasks キューと同じプロジェクトにあることが必要です。

  1. Google Cloud Console で、[サービス アカウント] ページに移動します。

    [サービス アカウント] に移動

  2. 必要に応じて、該当するプロジェクトを選択します。

  3. [サービス アカウントを作成] をクリックします。

  4. [サービス アカウントの詳細] セクションで、アカウントに名前を付けます。コンソールでアカウントに関連するメール アカウント名が作成されます。この名前でアカウントが参照されます。アカウントの説明を追加することもできます。[作成して続行] をクリックします。

  5. [このサービス アカウントにプロジェクトへのアクセスを許可する] セクションで、[ロールを選択] をクリックします。[Cloud Tasks へのデータ追加] を検索して選択します。このロールにより、タスクをキューに追加する権限がサービス アカウントに付与されます。

  6. [+ 別の役割を追加] をクリックします。

  7. [ロールを選択] をクリックします。[サービス アカウント ユーザー] を検索して選択します。このロールにより、サービス アカウントは、サービスア アカウントの認証情報を使用してキューがトークンを作成することを承認できます。

  8. ハンドラが Google Cloud の一部である場合は、ハンドラが実行されているサービスへのアクセスに関連付けられたロールをサービスア アカウントに付与します。 Google Cloud 内の各サービスには異なるロールが必要です。たとえば、Cloud Run でハンドラにアクセスするには、Cloud Run 起動元のロールを付与します。作成したサービス アカウントまたはプロジェクト内の他のサービス アカウントを使用できます。

  9. [完了] をクリックして、サービス アカウントの作成を完了します。

Cloud Tasks 自体には、Cloud Tasks Service Agent ロールが付与された独自のサービス アカウントが必要です。これは、Cloud Tasks サービス アカウントに関連付けられた認証情報に基づいてヘッダー トークンを生成し、ハンドラ ターゲットで認証できるようにするためです。このロールが付与された Cloud Tasks のサービス アカウントは、Cloud Task API を有効にすると自動的に作成されます。ただし、2019 年 3 月 19 日より前にこの API を有効にしていた場合は、このロールを手動で追加する必要があります。

認証トークンがある HTTP ターゲット タスクの使用

Cloud Tasks とそのような認証が必要な HTTP ターゲット ハンドラの間で認証を行うために、Cloud Tasks はヘッダー トークンを作成します。このトークンは、メールアドレスで識別される Cloud Tasks Enqueuer サービス アカウントの認証情報に基づいて生成されます。認証に使用するサービス アカウントは、Cloud Tasks キューが存在するプロジェクトの一部でなければなりません。リクエストは、ヘッダー トークンとともに HTTPS でキューからハンドラに送信されます。ID トークンまたはアクセス トークンのいずれかを使用できます。ID トークンは通常、Google Cloud で実行されているハンドラ(Cloud RUN Functions や Cloud Run など)で使用されます。主な例外は、*.googleapis.com でホストされている Google API で、この API ではアクセス トークンが使用されます。

認証は、キューレベルまたはタスクレベルで構成できます。キューレベルで認証を構成するには、Cloud Tasks キューを作成するをご覧ください。認証がキューレベルで構成されている場合、この構成はタスクレベルの構成をオーバーライドします。タスクレベルで認証を構成するには、ID(OIDC)トークンまたはアクセス(OAuth)トークンタスク自体に指定します。

BufferTask メソッド

次の例では、BufferTask メソッドを使用してタスクを作成するときに、アプリケーションのデフォルト認証情報を使用して認証を行います。

curl

curl -X HTTP_METHOD\
"https://cloudtasks.googleapis.com/v2/projects/PROJECT_ID/locations/LOCATION/queues/QUEUE_ID/tasks:buffer" \
    -H "Authorization: Bearer ACCESS_TOKEN"

以下を置き換えます。

  • HTTP_METHOD: リクエストの HTTP メソッド(例: GET または POST)。
  • PROJECT_ID: Google Cloud プロジェクトの ID。 これは、ターミナルで次のコマンドを実行することで取得できます。
    gcloud config get-value project
  • LOCATION: キューの場所
  • QUEUE_ID: キューの ID。
  • ACCESS_TOKEN:自分のアクセス トークン。これは、ターミナルで次のコマンドを実行することで取得できます。
  • gcloud auth application-default login
  • gcloud auth application-default print-access-token

Python

次のコードサンプルでは、お使いの認証トークンの値を指定してください。

from google.cloud import tasks_v2beta3 as tasks

import requests


def send_task_to_http_queue(
    queue: tasks.Queue, body: str = "", token: str = "", headers: dict = {}
) -> int:
    """Send a task to an HTTP queue.
    Args:
        queue: The queue to send task to.
        body: The body of the task.
        auth_token: An authorization token for the queue.
        headers: Headers to set on the task.
    Returns:
        The matching queue, or None if it doesn't exist.
    """

    # Use application default credentials if not supplied in a header
    if token:
        headers["Authorization"] = f"Bearer {token}"

    endpoint = f"https://cloudtasks.googleapis.com/v2beta3/{queue.name}/tasks:buffer"
    response = requests.post(endpoint, body, headers=headers)

    return response.status_code

CreateTask メソッド

次の例では、Cloud Tasks クライアント ライブラリで CreateTask メソッドを使用して、ヘッダー トークンの作成も含まれるタスクを作成します。この例では ID トークンが使用されます。 アクセス トークンを使用する場合は、リクエストの作成時に OIDC パラメータを、それぞれの言語に応じて適切な OAuth パラメータに置き換えます。

Go

import (
	"context"
	"fmt"

	cloudtasks "cloud.google.com/go/cloudtasks/apiv2"
	taskspb "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb"
)

// createHTTPTaskWithToken constructs a task with a authorization token
// and HTTP target then adds it to a Queue.
func createHTTPTaskWithToken(projectID, locationID, queueID, url, email, message string) (*taskspb.Task, error) {
	// Create a new Cloud Tasks client instance.
	// See https://godoc.org/cloud.google.com/go/cloudtasks/apiv2
	ctx := context.Background()
	client, err := cloudtasks.NewClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewClient: %w", err)
	}
	defer client.Close()

	// Build the Task queue path.
	queuePath := fmt.Sprintf("projects/%s/locations/%s/queues/%s", projectID, locationID, queueID)

	// Build the Task payload.
	// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#CreateTaskRequest
	req := &taskspb.CreateTaskRequest{
		Parent: queuePath,
		Task: &taskspb.Task{
			// https://godoc.org/google.golang.org/genproto/googleapis/cloud/tasks/v2#HttpRequest
			MessageType: &taskspb.Task_HttpRequest{
				HttpRequest: &taskspb.HttpRequest{
					HttpMethod: taskspb.HttpMethod_POST,
					Url:        url,
					AuthorizationHeader: &taskspb.HttpRequest_OidcToken{
						OidcToken: &taskspb.OidcToken{
							ServiceAccountEmail: email,
						},
					},
				},
			},
		},
	}

	// Add a payload message if one is present.
	req.Task.GetHttpRequest().Body = []byte(message)

	createdTask, err := client.CreateTask(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("cloudtasks.CreateTask: %w", err)
	}

	return createdTask, nil
}

Java

import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.HttpRequest;
import com.google.cloud.tasks.v2.OidcToken;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.charset.Charset;

public class CreateHttpTaskWithToken {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "my-project-id";
    String locationId = "us-central1";
    String queueId = "my-queue";
    String serviceAccountEmail =
        "java-docs-samples-testing@java-docs-samples-testing.iam.gserviceaccount.com";
    createTask(projectId, locationId, queueId, serviceAccountEmail);
  }

  // Create a task with a HTTP target and authorization token using the Cloud Tasks client.
  public static void createTask(
      String projectId, String locationId, String queueId, String serviceAccountEmail)
      throws IOException {

    // Instantiates a client.
    try (CloudTasksClient client = CloudTasksClient.create()) {
      String url =
          "https://example.com/taskhandler"; // The full url path that the request will be sent to
      String payload = "Hello, World!"; // The task HTTP request body

      // Construct the fully qualified queue name.
      String queuePath = QueueName.of(projectId, locationId, queueId).toString();

      // Add your service account email to construct the OIDC token.
      // in order to add an authentication header to the request.
      OidcToken.Builder oidcTokenBuilder =
          OidcToken.newBuilder().setServiceAccountEmail(serviceAccountEmail);

      // Construct the task body.
      Task.Builder taskBuilder =
          Task.newBuilder()
              .setHttpRequest(
                  HttpRequest.newBuilder()
                      .setBody(ByteString.copyFrom(payload, Charset.defaultCharset()))
                      .setHttpMethod(HttpMethod.POST)
                      .setUrl(url)
                      .setOidcToken(oidcTokenBuilder)
                      .build());

      // Send create task request.
      Task task = client.createTask(queuePath, taskBuilder.build());
      System.out.println("Task created: " + task.getName());
    }
  }
}

pom.xml ファイルをメモします。

<?xml version='1.0' encoding='UTF-8'?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example.tasks</groupId>
  <artifactId>cloudtasks-snippets</artifactId>
  <packaging>jar</packaging>
  <name>Google Cloud Tasks Snippets</name>

  <!--
    The parent pom defines common style checks and testing strategies for our samples.
    Removing or replacing it should not affect the execution of the samples in anyway.
  -->
  <parent>
    <groupId>com.google.cloud.samples</groupId>
    <artifactId>shared-configuration</artifactId>
    <version>1.2.0</version>
  </parent>

  <properties>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.source>1.8</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>libraries-bom</artifactId>
        <version>26.32.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-tasks</artifactId>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.google.truth</groupId>
      <artifactId>truth</artifactId>
      <version>1.4.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Node.js

// Imports the Google Cloud Tasks library.
const {CloudTasksClient} = require('@google-cloud/tasks');

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

async function createHttpTaskWithToken() {
  // TODO(developer): Uncomment these lines and replace with your values.
  // const project = 'my-project-id';
  // const queue = 'my-queue';
  // const location = 'us-central1';
  // const url = 'https://example.com/taskhandler';
  // const serviceAccountEmail = 'client@<project-id>.iam.gserviceaccount.com';
  // const payload = 'Hello, World!';

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

  const task = {
    httpRequest: {
      headers: {
        'Content-Type': 'text/plain', // Set content type to ensure compatibility your application's request parsing
      },
      httpMethod: 'POST',
      url,
      oidcToken: {
        serviceAccountEmail,
      },
    },
  };

  if (payload) {
    task.httpRequest.body = Buffer.from(payload).toString('base64');
  }

  console.log('Sending task:');
  console.log(task);
  // Send create task request.
  const request = {parent: parent, task: task};
  const [response] = await client.createTask(request);
  const name = response.name;
  console.log(`Created task ${name}`);
}
createHttpTaskWithToken();

package.json ファイルをメモします。

{
  "name": "appengine-cloudtasks",
  "description": "Google App Engine Cloud Tasks example.",
  "license": "Apache-2.0",
  "author": "Google Inc.",
  "private": true,
  "engines": {
    "node": ">=16.0.0"
  },
  "files": [
    "*.js"
  ],
  "scripts": {
    "test": "c8 mocha -p -j 2 --timeout 30000",
    "start": "node server.js"
  },
  "dependencies": {
    "@google-cloud/tasks": "^5.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^10.0.0",
    "chai": "^4.5.0",
    "mocha": "^10.0.0",
    "uuid": "^10.0.0"
  }
}

Python

from typing import Optional

from google.cloud import tasks_v2


def create_http_task_with_token(
    project: str,
    location: str,
    queue: str,
    url: str,
    payload: bytes,
    service_account_email: str,
    audience: Optional[str] = None,
) -> tasks_v2.Task:
    """Create an HTTP POST task with an OIDC token and an arbitrary payload.
    Args:
        project: The project ID where the queue is located.
        location: The location where the queue is located.
        queue: The ID of the queue to add the task to.
        url: The target URL of the task.
        payload: The payload to send.
        service_account_email: The service account to use for generating the OIDC token.
        audience: Audience to use when generating the OIDC token.
    Returns:
        The newly created task.
    """

    # Create a client.
    client = tasks_v2.CloudTasksClient()

    # Construct the request body.
    task = tasks_v2.Task(
        http_request=tasks_v2.HttpRequest(
            http_method=tasks_v2.HttpMethod.POST,
            url=url,
            oidc_token=tasks_v2.OidcToken(
                service_account_email=service_account_email,
                audience=audience,
            ),
            body=payload,
        ),
    )

    # Use the client to build and send the task.
    return client.create_task(
        tasks_v2.CreateTaskRequest(
            parent=client.queue_path(project, location, queue),
            task=task,
        )
    )

requirements.txt ファイルをメモします。

google-cloud-tasks==2.13.1

独自の HTTP ターゲット タスクハンドラの指定

HTTP Target タスクハンドラは App Engine タスクハンドラとよく似ていますが、次の点が異なります。

  • タイムアウト: HTTP ターゲット タスクハンドラでは、デフォルトのタイムアウトは 10 分、最大は 30 分です。
  • 認証ロジック: 対象とするサービスで独自のコードを作成してトークンを検証する場合は、ID トークンを使用する必要があります。この操作に関する詳細については、OpenID Connect の、特に ID トークンの検証をご覧ください。
  • ヘッダー: HTTP ターゲット リクエストには、ハンドラが使用できるタスク固有の情報が含まれたキューによって、ヘッダーが設定されています。これらは App Engine タスク リクエストに設定されたヘッダーと似ていますが、同じではありません。 これらのヘッダーは情報のみを提供します。これらは ID のソースとして使用しないでください

    アプリに対する外部ユーザー リクエストにこのようなヘッダーが含まれている場合、それらは内部ユーザー リクエストによって置換されます。ただし、ログイン済みのアプリケーション管理者からのリクエストは唯一の例外です。アプリケーション管理者は、テストの目的でこのヘッダーを設定することが許可されています。

    HTTP ターゲット リクエストには、常に次のヘッダーが含まれます。

    ヘッダー 説明
    X-CloudTasks-QueueName キューの名前。
    X-CloudTasks-TaskName タスクの「省略」名。または、作成時に名前が指定されなかった場合は、システムによって生成された一意の ID です。これは、完全なタスク名(task_name = projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id)の my-task-id 値になります。
    X-CloudTasks-TaskRetryCount このタスクが再試行された回数。最初の試行の場合は、この値は 0 です。この試行回数には、5XX エラーコードが原因でタスクが異常終了したため実行フェーズに到達できなかった試行も含まれています。
    X-CloudTasks-TaskExecutionCount タスクがハンドラからレスポンスを受け取った合計回数。Cloud Tasks は成功のレスポンスを受け取った時点でタスクを削除するため、それ以前のハンドラからのレスポンスはすべて失敗を意味します。この回数には、5XX エラーコードが原因の失敗は含まれていません。
    X-CloudTasks-TaskETA タスクのスケジュール時間。1970 年 1 月 1 日からの秒数で指定されます。

    さらに、Cloud Tasks からのリクエストには次のヘッダーが含まれる場合もあります。

    ヘッダー 説明
    X-CloudTasks-TaskPreviousResponse 前回の再試行の HTTP レスポンス コード。
    X-CloudTasks-TaskRetryReason タスクを再試行する理由。

Cloud Tasks サービス アカウントに Cloud Tasks サービス エージェントの役割を追加

この操作は、Cloud Tasks API を 2019 年 3 月 19 日より前に有効にした場合のみ必要になります。

コンソール

  1. プロジェクトのプロジェクト番号は、Google Cloud プロジェクトの設定ページで確認できます。
  2. その番号をコピーします。
  3. IAM 管理コンソール ページを開きます。
  4. [アクセス権を付与] をクリックします。[アクセス権を付与] 画面が開きます。
  5. [プリンシパルの追加] セクションで、次の形式のメールアドレスを追加します:

     service-PROJECT_NUMBER@gcp-sa-cloudtasks.iam.gserviceaccount.com
     

    PROJECT_NUMBER は、実際の Google Cloud プロジェクトの番号に置き換えます。

  6. [ロールの割り当て] セクションで、Cloud Tasks サービス エージェント ロールを探して選択します。

  7. [保存] をクリックします。

gcloud

  1. プロジェクト番号を確認します。

        gcloud projects describe PROJECT_ID --format='table(projectNumber)'
        

    PROJECT_ID は、実際のプロジェクト ID に置き換えます。

  2. その番号をコピーします。

  3. コピーしたプロジェクト番号を使用して、Cloud Tasks サービス アカウントに Cloud Tasks Service Agent の役割を付与します。

        gcloud projects add-iam-policy-binding PROJECT_ID --member serviceAccount:service-PROJECT_NUMBER@gcp-sa-cloudtasks.iam.gserviceaccount.com --role roles/cloudtasks.serviceAgent

    以下を置き換えます。

    • PROJECT_ID: Google Cloud プロジェクト ID
    • PROJECT_NUMBER: Google Cloud プロジェクト番号。

詳細構成

タスクで構成できる属性はいくつかあります。完全なリストについては、タスクのリソース定義をご覧ください。

カスタマイズできる属性の例:

  • 名前付け: タスクの名前を指定した場合、Cloud Tasks はその名前を使用してタスクの重複排除を行いますが、必要な処理によってレイテンシが増加する場合があります。
  • スケジュール: タスクを将来の任意の時間にスケジュール設定できます。CreateTask でのみサポートされます(BufferTask ではサポートされません)
  • 再試行の構成: タスクが失敗した場合の再試行動作を構成します。CreateTask でのみサポートされます(BufferTask ではサポートされません)

次のステップ