Crear tareas de destino HTTP

Los controladores de Cloud Tasks se pueden ejecutar en cualquier extremo HTTP con una dirección IP externa, como GKE, Compute Engine o incluso un servidor web local. Las tareas se pueden ejecutar en cualquiera de estos servicios de forma confiable y configurable.

En esta página, se muestra cómo crear tareas de destino HTTP básicas de manera programática y colocarlas en colas de Cloud Tasks.

Para las tareas que tienen objetivos HTTP (a diferencia de los objetivos explícitos de App Engine, que son menos comunes), existen dos formas de crear tareas:

  • Método BufferTask: Usa este método si tu cola está configurada para almacenar las tareas en búfer frente a un servicio. La cola debe tener enrutamiento al nivel de la cola. Para la mayoría de los casos de uso, este es el mejor enfoque. En este enfoque, se usa el método BufferTask.

  • Método CreateTask: Es más complejo. Debes crear un objeto de tarea de forma explícita. Usa este método si las tareas de tu cola tienen diferentes configuraciones de enrutamiento. En este caso, especificas el enrutamiento a nivel de tarea y no puedes usar el enrutamiento a nivel de cola. En este enfoque, se usa el método CreateTask.

Creación de tareas básicas (método BufferTask)

En esta sección, se explica cómo crear una tarea mediante el envío de una solicitud HTTP. El método que usas se llama BufferTask.

Limitaciones

El método BufferTask está sujeto a las siguientes limitaciones:

  • Bibliotecas cliente: Las bibliotecas cliente no admiten el método BufferTask.

  • API de RPC: El método BufferTask no es compatible con la API de RPC.

  • Enrutamiento a nivel de tarea: Este método no admite el enrutamiento a nivel de tarea. Dado que no hay lugar para agregar información de enrutamiento cuando se crea una tarea de esta manera, debes usar el enrutamiento a nivel de cola (de lo contrario, la tarea no tendrá información de enrutamiento). Si tu cola aún no usa el enrutamiento a nivel de cola, consulta Configura el enrutamiento a nivel de la cola para tareas HTTP.

Llama al método BufferTask

En los siguientes ejemplos, se muestra cómo crear una tarea mediante el envío de una solicitud HTTP POST al extremo buffer de la API de Cloud Tasks.

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 delete.
        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 does not 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

curl

En el siguiente fragmento de código, se muestra un ejemplo de creación de tareas con el método BufferTask usando curl:

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

Reemplaza lo siguiente:

  • HTTP_METHOD: Es el método HTTP para tu solicitud, por ejemplo GET o POST.
  • PROJECT_ID: El ID del proyecto de Google Cloud. Para obtenerlo, ejecuta el siguiente comando en la terminal:
    gcloud config get-value project
  • LOCATION: Es la ubicación de la fila.
  • QUEUE_ID: Es el ID de la fila.

Creación avanzada de tareas (método CreateTask)

En esta sección, se explica cómo crear una tarea mediante la construcción del objeto de tarea. Debes usar el método CreateTask.

Cuando creas una tarea con el método CreateTask, creas y defines de forma explícita el objeto de tarea. Debes especificar el servicio y el controlador que procesan la tarea.

De manera opcional, puedes pasar datos específicos de la tarea al controlador. También puedes ajustar la configuración de la tarea, como programar un momento en el futuro en el que se debería ejecutar o limitar la cantidad de veces que deseas que se reintente la tarea si falla (consulta Configuración avanzada).

En los siguientes ejemplos, se llama al método CreateTask para crear una tarea con las bibliotecas cliente de Cloud Tasks.

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;
    }
}

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,
        )
    )

Ten en cuenta el archivo requirements.txt:

google-cloud-tasks==2.13.1

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());
    }
  }
}

Ten en cuenta el archivo 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>

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());

Ten en cuenta el archivo composer.json:

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

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
}

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();

Ten en cuenta el archivo 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": "^4.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^8.0.0",
    "chai": "^4.2.0",
    "mocha": "^10.0.0",
    "uuid": "^9.0.0"
  }
}

Rita

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

Configura cuentas de servicio para la autenticación del controlador de destino HTTP

Cloud Tasks puede llamar a los controladores de destino HTTP que requieren autenticación si tienes una cuenta de servicio con las credenciales adecuadas para acceder al controlador.

Si tienes una cuenta de servicio actual que deseas usar, puedes hacerlo. Solo otórgale las funciones adecuadas. Estas instrucciones abarcan la creación de una cuenta de servicio nueva, en particular, para esta función. La cuenta de servicio nueva o existente que se use para la autenticación de Cloud Tasks debe estar en el mismo proyecto que tus colas de Cloud Tasks.

  1. En la consola de Google Cloud, ve a la página Cuentas de servicio.

    Ir a Cuentas de servicio

  2. Si es necesario, selecciona el proyecto adecuado.

  3. Haz clic en Crear cuenta de servicio.

  4. En la sección Detalles de la cuenta de servicio, asigna un nombre a la cuenta. La consola crea un nombre de cuenta de correo electrónico relacionado para la cuenta. Así es como se hace referencia a la cuenta. También puedes agregar una descripción sobre para qué sirve la cuenta. Haz clic en Crear y continuar.

  5. En la sección Otorga a esta cuenta de servicio acceso al proyecto, haz clic en Seleccionar un rol. Busca y selecciona Agregador de elementos en cola de Cloud Tasks. Este rol le otorga permiso a la cuenta de servicio para agregar tareas a la cola.

  6. Haz clic en + Agregar otra función.

  7. Haga clic en Selecciona un rol. Busca y selecciona Usuario de cuenta de servicio. Esta función permite que la cuenta de servicio autorice a la cola para crear tokens en su nombre con las credenciales de la cuenta de servicio.

  8. Si tu controlador es parte de Google Cloud, otorga a la cuenta de servicio la función asociada con el acceso al servicio en el que se ejecuta tu controlador. Cada servicio dentro de Google Cloud requiere una función diferente. Por ejemplo, para acceder a un controlador en Cloud Run, se necesita la función Invocador de Cloud Run, y así sucesivamente. Puedes usar la cuenta de servicio que acabas de crear o cualquier otra cuenta de servicio de tu proyecto.

  9. Haz clic en Listo para terminar de crear la cuenta de servicio.

Cloud Tasks en sí debe tener una cuenta de servicio propia que tenga la función Cloud Tasks Service Agent otorgada. Esto es para que pueda generar tokens de encabezado basados en las credenciales asociadas con la cuenta de servicio de Cloud Tasks a fin de autenticarse con tu objetivo de controlador. La cuenta de servicio de Cloud Tasks con esta función otorgada se crea automáticamente cuando habilitas la API de Cloud Tasks, a menos que la hayas habilitado antes del 19 de marzo de 2019. Si ese es el caso, debes agregar la función manualmente.

Cómo usar tareas de destino HTTP con tokens de autenticación

Para autenticar entre Cloud Tasks y un controlador de destino HTTP que requiere esa autenticación, Cloud Tasks crea un token de encabezado. Este token se basa en las credenciales de la cuenta de servicio Cloud Tasks Enqueuer, que se identifica por su dirección de correo electrónico. La cuenta de servicio que se usa para la autenticación debe ser parte del mismo proyecto en el que reside tu cola de Cloud Tasks. HTTPS envía la solicitud con el token de encabezado de la cola al controlador. Puedes usar un token de ID o un token de acceso. Los tokens de ID suelen usarse para cualquier controlador que se ejecute en Google Cloud, por ejemplo, en Cloud Functions o Cloud Run. La principal excepción son las APIs de Google alojadas en *.googleapis.com: estas APIs esperan un token de acceso.

Puedes configurar la autenticación a nivel de la cola o de la tarea. Para configurar la autenticación a nivel de la cola, consulta Crea colas de Cloud Tasks. Si la autenticación se configura a nivel de la cola, esta configuración anula la configuración a nivel de la tarea. Para configurar la autenticación a nivel de la tarea, especifica un token de ID (OIDC) o un token de acceso (OAuth) en la tarea.

Método BufferTask

En los siguientes ejemplos, se usan credenciales predeterminadas de la aplicación para autenticarse cuando se usa el método BufferTask a fin de crear una tarea.

Python

En la siguiente muestra de código, proporciona el valor del token de autenticación.

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 delete.
        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 does not 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

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"

Reemplaza lo siguiente:

  • HTTP_METHOD: Es el método HTTP para tu solicitud, por ejemplo GET o POST.
  • PROJECT_ID: El ID del proyecto de Google Cloud. Para obtenerlo, ejecuta el siguiente comando en la terminal:
    gcloud config get-value project
  • LOCATION: Es la ubicación de la fila.
  • QUEUE_ID: Es el ID de la fila.
  • ACCESS_TOKEN: Es tu token de acceso. Para ello, ejecuta lo siguiente en la terminal:
  • gcloud auth application-default login
  • gcloud auth application-default print-access-token

Método CreateTask

En los siguientes ejemplos, se usa el método CreateTask con las bibliotecas cliente de Cloud Tasks para crear una tarea que también incluye la creación de un token de encabezado. Los tokens de ID se usan en los ejemplos. Si quieres usar un token de acceso, reemplaza el parámetro de OIDC por el parámetro de OAuth apropiado para el lenguaje en la construcción de la solicitud.

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,
        )
    )

Ten en cuenta el archivo requirements.txt:

google-cloud-tasks==2.13.1

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());
    }
  }
}

Ten en cuenta el archivo 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>

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
}

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();

Ten en cuenta el archivo 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": "^4.0.0",
    "express": "^4.16.3"
  },
  "devDependencies": {
    "c8": "^8.0.0",
    "chai": "^4.2.0",
    "mocha": "^10.0.0",
    "uuid": "^9.0.0"
  }
}

Proporciona tus propios controladores de tareas de destino HTTP

Los controladores de tareas de destino HTTP son muy similares a los controladores de tareas de App Engine, con las siguientes excepciones:

  • Tiempos de espera: Para todos los controladores de tareas de destino HTTP, el tiempo de espera predeterminado es de 10 minutos, con un máximo de 30 minutos.
  • Lógica de autenticación: Si escribes tu propio código en el servicio de destino para validar el token, debes usar un token de ID. Para obtener más información sobre lo que esto implica, consulta OpenID Connect, en particular Valida un token de ID.
  • Encabezados: Una solicitud de destino HTTP tiene encabezados establecidos por la cola, que contienen información específica de la tarea que puede usar tu controlador. Estos son similares a los encabezados configurados en las solicitudes de tareas de App Engine, pero no son idénticos. Estos encabezados solo proporcionan información. No se deben usar como fuentes de identidad.

    Si estos encabezados estaban presentes en una solicitud de usuario externo a tu app, se reemplazan por los internos. La única excepción es para solicitudes de administradores que hayan accedido a la aplicación y que tengan permitido establecer encabezados con fines de prueba.

    Las solicitudes de destino HTTP siempre contienen los siguientes encabezados:

    Encabezado Descripción
    X-CloudTasks-QueueName El nombre de la cola.
    X-CloudTasks-TaskName El nombre "breve" de la tarea o (si no se especificó un nombre durante su creación) un ID único generado por el sistema. Este es el valor my-task-id en el nombre completo de la tarea, es decir, task_name = projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id.
    X-CloudTasks-TaskRetryCount La cantidad de veces que se reintentó esta tarea. Si es el primer intento, el valor es 0. Este número incluye los intentos en los que la tarea falló debido a códigos de error de 5XX y nunca alcanzó la fase de ejecución.
    X-CloudTasks-TaskExecutionCount La cantidad total de veces que la tarea recibió una respuesta de un controlador. Dado que Cloud Tasks borra la tarea una vez que se recibe una respuesta en la que se indica que se ejecutó correctamente, todas las respuestas anteriores que envió el controlador fueron ejecuciones con errores. Este número no incluye errores debido a los códigos de error 5XX.
    X-CloudTasks-TaskETA La fecha y hora programadas para la tarea, que se especifica en la cantidad de segundos transcurridos desde el 1 de enero de 1970.

    Además, las solicitudes de Cloud Tasks pueden contener los siguientes encabezados:

    Header Descripción
    X-CloudTasks-TaskPreviousResponse El código de respuesta HTTP del reintento anterior.
    X-CloudTasks-TaskRetryReason La razón por la que se volvió a intentar la tarea.

Agrega la función de agente de servicio de Cloud Tasks a tu cuenta de servicio de Cloud Tasks de forma manual

Esto es necesario solo si habilitas la API de Cloud Tasks antes del 19 de marzo de 2019.

Usar Console

  1. Encuentra el número del proyecto en la página de configuración del proyecto de Google Cloud.
  2. Copia el número.
  3. Abre la página de la Consola del administrador de IAM.
  4. Haz clic en Otorgar acceso. Se abrirá la pantalla Otorgar acceso.
  5. En la sección Agregar principales, agrega una dirección de correo electrónico con el formato:

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

    Reemplaza PROJECT_NUMBER por el número de proyecto de arriba.

  6. En la sección Asignar roles, busca y selecciona Agente de servicio de Cloud Tasks.

  7. Haz clic en Guardar.

Usa gcloud

  1. Busca el número de tu proyecto:

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

    Reemplaza PROJECT_ID con el ID del proyecto.

  2. Copia el número.

  3. Otorga la función Cloud Tasks Service Agent a la cuenta de servicio de Cloud Tasks con el número del proyecto que copiaste:

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

    Reemplaza PROJECT_ID por el ID del proyecto y PROJECT_NUMBER por el número de proyecto anterior.

Configuración avanzada

Hay varios atributos que puedes configurar en tu tarea. Para obtener una lista completa, consulta la definición del recurso de la tarea.

Estos son algunos ejemplos de atributos que puedes personalizar:

  • Nombre: Si elegiste especificar un nombre para la tarea, Cloud Tasks puede usar ese nombre a fin de garantizar la anulación de duplicación de tareas, aunque el procesamiento necesario para esto puede aumentar la latencia.
  • Programación: Puedes programar una tarea en el futuro. Solo es compatible con CreateTask (no compatible con BufferTask).
  • Configuración de reintento: Configura el comportamiento de reintento de una tarea si esta falla. Solo es compatible con CreateTask (no compatible con BufferTask).

¿Qué sigue?