Criar assinaturas de push

Este documento descreve como criar uma assinatura push. É possível usar o console do Google Cloud, a Google Cloud CLI, a biblioteca de cliente ou a API Pub/Sub para criar uma assinatura push.

Antes de começar

Papéis e permissões necessárias

Para criar uma assinatura, configure o controle de acesso no nível do projeto. Você também precisa de permissões no nível do recurso se as assinaturas e os tópicos estiverem em projetos diferentes, conforme discutido mais adiante nesta seção.

Para receber as permissões necessárias para criar assinaturas push, peça ao administrador para conceder a você o papel do IAM de Editor do Pub/Sub (roles/pubsub.editor) no projeto. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Esse papel predefinido contém as permissões necessárias para criar assinaturas push. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As permissões a seguir são necessárias para criar assinaturas push:

  • Criar uma assinatura: pubsub.subscriptions.create
  • Excluir uma assinatura: pubsub.subscriptions.delete
  • Receber uma assinatura: pubsub.subscriptions.get
  • Listar uma assinatura: pubsub.subscriptions.list
  • Atualizar uma assinatura: pubsub.subscriptions.update
  • Anexe uma assinatura a um tópico: pubsub.topics.attachSubscription
  • Acesse a política do IAM para uma assinatura: pubsub.subscriptions.getIamPolicy
  • Configure a política do IAM para uma assinatura: pubsub.subscriptions.setIamPolicy

Essas permissões também podem ser concedidas com funções personalizadas ou outros papéis predefinidos.

Se você precisar criar assinaturas push em um projeto associado a um tópico em outro projeto, peça ao administrador do tópico para conceder a você a função do IAM (roles/pubsub.editor) do Editor do Pub/Sub no tópico.

Propriedades de assinatura por push

Ao configurar uma assinatura push, é possível especificar as seguintes propriedades.

Propriedades comuns

Saiba mais sobre as propriedades comuns de assinatura que podem ser definidas em todas as assinaturas.

Endpoints

URL do endpoint (obrigatório). Um endereço HTTPS acessível publicamente. O servidor do endpoint de push precisa ter um certificado SSL válido assinado por uma autoridade de certificação. O serviço do Pub/Sub entrega mensagens para enviar endpoints da mesma região do Google Cloud em que o serviço do Pub/Sub armazena as mensagens. O serviço Pub/Sub entrega mensagens da mesma região do Google Cloud com base no melhor esforço.

O Pub/Sub não exige mais prova de propriedade para domínios de URL de assinatura por push. Se o domínio receber solicitações POST inesperadas do Pub/Sub, relate suspeita de abuso.

Autenticação

Ative a autenticação. Quando ativada, as mensagens enviadas pelo Pub/Sub para o endpoint de push incluem um cabeçalho de autorização para permitir que o endpoint autentique a solicitação. Os mecanismos de autenticação e autorização automáticos estão disponíveis para os endpoints do Cloud Run Functions e do ambiente padrão do App Engine hospedados no mesmo projeto da assinatura.

A configuração de autenticação de uma assinatura de push autenticada consiste em uma conta de serviço gerenciado pelo usuário e os parâmetros de público-alvo que são especificados em uma chamada create, patch ou ModifyPushConfig. Você também precisa conceder um papel específico a um agente de serviço, conforme discutido na próxima seção.

  • Conta de serviço gerenciado pelo usuário (obrigatória). A conta de serviço associada à assinatura de push. Essa conta é usada como a declaração email do JSON Web Token (JWT) gerado. Confira a seguir uma lista de requisitos para a conta de serviço:

  • Público-alvo. Uma única string, indiferente a maiúsculas, que o webhook usa para validar o público-alvo desse token.

  • Agente de serviço (obrigatório).

    • O Pub/Sub cria automaticamente uma conta de serviço para você com o formato service-{PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com.

    • Esse agente de serviço precisa receber a permissão iam.serviceAccounts.getOpenIdToken (incluída no papel roles/iam.serviceAccountTokenCreator) para permitir que o Pub/Sub crie tokens JWT para solicitações de push autenticadas.

Desencapsulamento de payload

A opção Ativar desencapsulamento de payload remove todos os metadados das mensagens do Pub/Sub, exceto os dados da mensagem. Com a abertura de payload, os dados da mensagem são entregues diretamente como o corpo HTTP.

  • Gravar metadados. Adiciona os metadados removidos das mensagens de volta ao cabeçalho da solicitação.

VPC Service Controls

Para um projeto protegido pelo VPC Service Controls, considere as seguintes limitações para assinaturas de push:

  • Só é possível criar novas assinaturas de push em que o endpoint de push está configurado para um serviço do Cloud Run com um URL run.app padrão ou uma execução do Workflows. Os domínios personalizados não funcionam.

  • Ao rotear eventos pelo Eventarc para destinos do Workflows em que o endpoint de push está definido como uma execução do Workflows, só é possível criar novas assinaturas de push pelo Eventarc.

  • Não é possível atualizar as assinaturas de push atuais. Essas assinaturas push continuam funcionando, mas não são protegidas pelo VPC Service Controls.

Criar uma assinatura por push

Os exemplos a seguir demonstram como criar uma assinatura com entrega por push usando as configurações padrão fornecidas.

Por padrão, as assinaturas usam a entrega por pull, a menos que você defina explicitamente uma configuração de push, conforme mostrado nos exemplos a seguir.

Console

Para criar uma assinatura de push, siga estas etapas:

  1. No console do Google Cloud, acesse a página Assinaturas.

    Acessar "Assinaturas"

  2. Clique em Criar assinatura.
  3. No campo ID da assinatura, insira um nome.

    Para saber como nomear uma assinatura, consulte Diretrizes para nomear um tópico ou uma assinatura.

  4. Escolha ou crie um tópico no menu suspenso. A assinatura recebe mensagens do tópico.
  5. Selecione Push como Tipo de envio.
  6. Especifique um URL de endpoint.
  7. Mantenha todos os outros valores padrão.
  8. Clique em Criar.

Você também pode criar uma assinatura na seção Tópicos. Esse atalho é útil para associar tópicos a assinaturas.

  1. No console do Google Cloud, acesse a página Tópicos.

    Acesse Tópicos

  2. Clique em ao lado do tópico em que você quer criar uma assinatura.
  3. No menu de contexto, selecione Criar assinatura.
  4. Insira o ID da assinatura.

    Para saber como nomear uma assinatura, consulte as Diretrizes para nomear um tópico ou uma assinatura.

  5. Selecione Push como Tipo de envio.
  6. Especifique um URL de endpoint.
  7. Mantenha todos os outros valores padrão.
  8. Clique em Criar.

gcloud

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Para criar uma assinatura push, execute o comando gcloud pubsub subscriptions create.

    gcloud pubsub subscriptions create SUBSCRIPTION_ID \
        --topic=TOPIC_ID \
        --push-endpoint=PUSH_ENDPOINT

    Substitua:

    • SUBSCRIPTION_ID: o nome ou ID da nova assinatura de push.
    • TOPIC_ID: o nome ou ID do tópico.
    • PUSH_ENDPOINT: o URL a ser usado como endpoint dessa assinatura. Por exemplo, https://myproject.appspot.com/myhandler.

REST

Para criar uma inscrição de push, use o método projects.subscriptions.create:

Solicitação:

A solicitação precisa ser autenticada com um token de acesso no cabeçalho Authorization. Para conseguir um token de acesso para o Application Default Credentials atual, use: gcloud auth application-default print-access-token.

PUT https://pubsub.googleapis.com/v1/projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID
Authorization: Bearer ACCESS_TOKEN

Corpo da solicitação:

{
  "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
  // Only needed if you are using push delivery
  "pushConfig": {
    "pushEndpoint": "PUSH_ENDPOINT"
  }
}

Em que:

  • PROJECT_ID é o ID do projeto;
  • SUBSCRIPTION_ID é o ID da sua assinatura.
  • TOPIC_ID é o ID do tópico.
  • PUSH_ENDPOINT é um URL a ser usado como endpoint. Por exemplo, https://myproject.appspot.com/myhandler.
  • Resposta:

    {
      "name": "projects/PROJECT_ID/subscriptions/SUBSCRIPTION_ID",
      "topic": "projects/PROJECT_ID/topics/TOPIC_ID",
      "pushConfig": {
        "pushEndpoint": "https://PROJECT_ID.appspot.com/myhandler",
        "attributes": {
          "x-goog-version": "v1"
        }
      },
      "ackDeadlineSeconds": 10,
      "messageRetentionDuration": "604800s",
      "expirationPolicy": {
        "ttl": "2678400s"
      }
    }

    C++

    Antes de tentar esse exemplo, siga as instruções de configuração do C++ em Guia de início rápido: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C++.

    namespace pubsub = ::google::cloud::pubsub;
    namespace pubsub_admin = ::google::cloud::pubsub_admin;
    [](pubsub_admin::SubscriptionAdminClient client,
       std::string const& project_id, std::string const& topic_id,
       std::string const& subscription_id, std::string const& endpoint) {
      google::pubsub::v1::Subscription request;
      request.set_name(
          pubsub::Subscription(project_id, subscription_id).FullName());
      request.set_topic(pubsub::Topic(project_id, topic_id).FullName());
      request.mutable_push_config()->set_push_endpoint(endpoint);
      auto sub = client.CreateSubscription(request);
      if (sub.status().code() == google::cloud::StatusCode::kAlreadyExists) {
        std::cout << "The subscription already exists\n";
        return;
      }
      if (!sub) throw std::move(sub).status();
    
      std::cout << "The subscription was successfully created: "
                << sub->DebugString() << "\n";

    C#

    Antes de testar esta amostra, siga as instruções de configuração do C# no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub C#.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    
    using Google.Cloud.PubSub.V1;
    
    public class CreatePushSubscriptionSample
    {
        public Subscription CreatePushSubscription(string projectId, string topicId, string subscriptionId, string pushEndpoint)
        {
            SubscriberServiceApiClient subscriber = SubscriberServiceApiClient.Create();
            TopicName topicName = TopicName.FromProjectTopic(projectId, topicId);
            SubscriptionName subscriptionName = SubscriptionName.FromProjectSubscription(projectId, subscriptionId);
    
            PushConfig pushConfig = new PushConfig { PushEndpoint = pushEndpoint };
    
            // The approximate amount of time in seconds (on a best-effort basis) Pub/Sub waits for the
            // subscriber to acknowledge receipt before resending the message.
            var ackDeadlineSeconds = 60;
            var subscription = subscriber.CreateSubscription(subscriptionName, topicName, pushConfig, ackDeadlineSeconds);
            return subscription;
        }
    }

    Go

    Antes de testar esta amostra, siga as instruções de configuração do Go no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Go.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    import (
    	"context"
    	"fmt"
    	"io"
    	"time"
    
    	"cloud.google.com/go/pubsub"
    )
    
    func createWithEndpoint(w io.Writer, projectID, subID string, topic *pubsub.Topic, endpoint string) error {
    	// projectID := "my-project-id"
    	// subID := "my-sub"
    	// topic of type https://godoc.org/cloud.google.com/go/pubsub#Topic
    	// endpoint := "https://my-test-project.appspot.com/push"
    	ctx := context.Background()
    	client, err := pubsub.NewClient(ctx, projectID)
    	if err != nil {
    		return fmt.Errorf("pubsub.NewClient: %w", err)
    	}
    	defer client.Close()
    
    	sub, err := client.CreateSubscription(ctx, subID, pubsub.SubscriptionConfig{
    		Topic:       topic,
    		AckDeadline: 10 * time.Second,
    		PushConfig:  pubsub.PushConfig{Endpoint: endpoint},
    	})
    	if err != nil {
    		return fmt.Errorf("CreateSubscription: %w", err)
    	}
    	fmt.Fprintf(w, "Created push subscription: %v\n", sub)
    	return nil
    }
    

    Java

    Antes de testar esta amostra, siga as instruções de configuração do Java no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Java.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    
    import com.google.cloud.pubsub.v1.SubscriptionAdminClient;
    import com.google.pubsub.v1.PushConfig;
    import com.google.pubsub.v1.Subscription;
    import com.google.pubsub.v1.SubscriptionName;
    import com.google.pubsub.v1.TopicName;
    import java.io.IOException;
    
    public class CreatePushSubscriptionExample {
      public static void main(String... args) throws Exception {
        // TODO(developer): Replace these variables before running the sample.
        String projectId = "your-project-id";
        String subscriptionId = "your-subscription-id";
        String topicId = "your-topic-id";
        String pushEndpoint = "https://my-test-project.appspot.com/push";
    
        createPushSubscriptionExample(projectId, subscriptionId, topicId, pushEndpoint);
      }
    
      public static void createPushSubscriptionExample(
          String projectId, String subscriptionId, String topicId, String pushEndpoint)
          throws IOException {
        try (SubscriptionAdminClient subscriptionAdminClient = SubscriptionAdminClient.create()) {
          TopicName topicName = TopicName.of(projectId, topicId);
          SubscriptionName subscriptionName = SubscriptionName.of(projectId, subscriptionId);
          PushConfig pushConfig = PushConfig.newBuilder().setPushEndpoint(pushEndpoint).build();
    
          // Create a push subscription with default acknowledgement deadline of 10 seconds.
          // Messages not successfully acknowledged within 10 seconds will get resent by the server.
          Subscription subscription =
              subscriptionAdminClient.createSubscription(subscriptionName, topicName, pushConfig, 10);
          System.out.println("Created push subscription: " + subscription.getName());
        }
      }
    }

    Node.js

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const pushEndpoint = 'YOUR_ENDPOINT_URL';
    // const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
    // const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
    
    // Imports the Google Cloud client library
    const {PubSub} = require('@google-cloud/pubsub');
    
    // Creates a client; cache this for further use
    const pubSubClient = new PubSub();
    
    async function createPushSubscription(
      pushEndpoint,
      topicNameOrId,
      subscriptionNameOrId
    ) {
      const options = {
        pushConfig: {
          // Set to an HTTPS endpoint of your choice. If necessary, register
          // (authorize) the domain on which the server is hosted.
          pushEndpoint,
        },
      };
    
      await pubSubClient
        .topic(topicNameOrId)
        .createSubscription(subscriptionNameOrId, options);
      console.log(`Subscription ${subscriptionNameOrId} created.`);
    }

    Node.js

    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const pushEndpoint = 'YOUR_ENDPOINT_URL';
    // const topicNameOrId = 'YOUR_TOPIC_NAME_OR_ID';
    // const subscriptionNameOrId = 'YOUR_SUBSCRIPTION_NAME_OR_ID';
    
    // Imports the Google Cloud client library
    import {PubSub, CreateSubscriptionOptions} from '@google-cloud/pubsub';
    
    // Creates a client; cache this for further use
    const pubSubClient = new PubSub();
    
    async function createPushSubscription(
      pushEndpoint: string,
      topicNameOrId: string,
      subscriptionNameOrId: string
    ) {
      const options: CreateSubscriptionOptions = {
        pushConfig: {
          // Set to an HTTPS endpoint of your choice. If necessary, register
          // (authorize) the domain on which the server is hosted.
          pushEndpoint,
        },
      };
    
      await pubSubClient
        .topic(topicNameOrId)
        .createSubscription(subscriptionNameOrId, options);
      console.log(`Subscription ${subscriptionNameOrId} created.`);
    }

    PHP

    Antes de testar esta amostra, siga as instruções de configuração do PHP no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub PHP.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    use Google\Cloud\PubSub\PubSubClient;
    
    /**
     * Creates a Pub/Sub push subscription.
     *
     * @param string $projectId  The Google project ID.
     * @param string $topicName  The Pub/Sub topic name.
     * @param string $subscriptionName  The Pub/Sub subscription name.
     * @param string $endpoint  The endpoint for the push subscription.
     */
    function create_push_subscription($projectId, $topicName, $subscriptionName, $endpoint)
    {
        $pubsub = new PubSubClient([
            'projectId' => $projectId,
        ]);
        $topic = $pubsub->topic($topicName);
        $subscription = $topic->subscription($subscriptionName);
        $subscription->create([
            'pushConfig' => ['pushEndpoint' => $endpoint]
        ]);
    
        printf('Subscription created: %s' . PHP_EOL, $subscription->name());
    }

    Python

    Antes de testar esta amostra, siga as instruções de configuração do Python no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Python.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    from google.cloud import pubsub_v1
    
    # TODO(developer)
    # project_id = "your-project-id"
    # topic_id = "your-topic-id"
    # subscription_id = "your-subscription-id"
    # endpoint = "https://my-test-project.appspot.com/push"
    
    publisher = pubsub_v1.PublisherClient()
    subscriber = pubsub_v1.SubscriberClient()
    topic_path = publisher.topic_path(project_id, topic_id)
    subscription_path = subscriber.subscription_path(project_id, subscription_id)
    
    push_config = pubsub_v1.types.PushConfig(push_endpoint=endpoint)
    
    # Wrap the subscriber in a 'with' block to automatically call close() to
    # close the underlying gRPC channel when done.
    with subscriber:
        subscription = subscriber.create_subscription(
            request={
                "name": subscription_path,
                "topic": topic_path,
                "push_config": push_config,
            }
        )
    
    print(f"Push subscription created: {subscription}.")
    print(f"Endpoint for subscription is: {endpoint}")

    Ruby

    Antes de testar esta amostra, siga as instruções de configuração do Ruby no Guia de início rápido do Pub/Sub: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Pub/Sub Ruby.

    Para autenticar no Pub/Sub, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

    # topic_id          = "your-topic-id"
    # subscription_id   = "your-subscription-id"
    # endpoint          = "https://your-test-project.appspot.com/push"
    
    pubsub = Google::Cloud::Pubsub.new
    
    topic        = pubsub.topic topic_id
    subscription = topic.subscribe subscription_id,
                                   endpoint: endpoint
    
    puts "Push subscription #{subscription_id} created."

    Monitorar inscrições de push

    O Cloud Monitoring oferece várias métricas para monitorar assinaturas.

    Para conferir uma lista de todas as métricas disponíveis relacionadas ao Pub/Sub e as descrições delas, consulte a documentação de monitoramento do Pub/Sub.

    Também é possível monitorar assinaturas no Pub/Sub.

    A seguir