Criar assinaturas de push

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

Antes de começar

Papéis e permissões necessárias

Para receber as permissões necessárias para criar uma assinatura por 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 uma assinatura por push. Para acessar as permissões exatas que são necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

As seguintes permissões são necessárias para criar uma assinatura por push:

  • pubsub.subscriptions.create no projeto
  • pubsub.topics.attachSubscription no tópico

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

Assinaturas entre projetos

Se você criar uma assinatura em um projeto para um tópico em outro projeto, será necessário ter a permissão pubsub.subscriptions.create no projeto em que você está criando a assinatura e a permissão pubsub.topics.attachSubscription no tópico.

Propriedades da assinatura por push

As assinaturas por push oferecem suporte a todas as propriedades de assinatura comuns. As seções a seguir descrevem propriedades específicas das assinaturas por push.

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 endpoints de push de mesma Google Cloud região em que o serviço do Pub/Sub armazena as mensagens. O serviço do Pub/Sub entrega mensagens da mesma Google Cloud região com base no melhor esforço.

  • Se os assinantes usam um firewall, eles não podem receber solicitações push. Para receber solicitações push, desative o firewall e verifique o JSON Web Token (JWT) usado na solicitação. Se um assinante tiver um firewall, você poderá receber um erro 403 permission denied.

  • O Pub/Sub não exige prova de propriedade para domínios de URL de assinatura por push. Se seu domínio recebe solicitações POST inesperadas do Pub/Sub, você pode relatar suspeita de abuso.

Autenticação

Ativar a autenticação. Quando ativadas, as mensagens entregues pelo Pub/Sub ao 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 padrão do App Engine e do Cloud Run hospedados no mesmo projeto que a assinatura.

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

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

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

Pré-requisitos para ativar a autenticação

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

  • Essa conta serviço gerenciado pelo usuário precisa estar no mesmo projeto que a assinatura por push.

  • O principal que está criando ou modificando a assinatura por push precisa ter a permissão iam.serviceAccounts.actAs na conta de serviço gerenciada pelo usuário para anexar a conta de serviço à assinatura por push. Para mais informações, consulte Como anexar contas de serviço a recursos.

  • Permissões necessárias: essa conta de serviço precisa receber a iam.serviceAccounts.getOpenIdToken permissão (incluída no roles/iam.serviceAccountTokenCreatorpapel) para permitir que o Pub/Sub crie tokens JWT para a conta de serviço especificada para autenticar solicitações push.

Desencapsulamento de payload

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

Também é possível ativar a opção Gravar metadados. A opção Gravar metadados adiciona os metadados removidos das mensagens de volta ao cabeçalho da solicitação.

Entregar a endereços VPC particulares

O Pub/Sub opera fora das redes VPC e não pode enviar mensagens diretamente para endereços VPC particulares. No entanto, é possível usar o Eventarc para rotear mensagens para serviços na sua VPC. O Pub/Sub pode enviar mensagens para um gatilho do Eventarc, que pode encaminhá-las para um serviço na sua VPC, como um serviço do Cloud Run ou uma execução do Workflows. Para mais informações, consulte a documentação do Eventarc.

VPC Service Controls

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

  • Só é possível criar novas assinaturas por push para as quais o endpoint de push está definido como um serviço do Cloud Run com um URL run.app padrão ou uma execução do Workflows. 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 por push pelo Eventarc.

  • Não é possível atualizar assinaturas por push. Essas assinaturas por push continuam funcionando, embora não sejam protegidas pelo VPC Service Controls.

Criar uma assinatura por push

Os exemplos a seguir mostram 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 por push, siga estas etapas:

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

    Acessar "Assinaturas"

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

    Para informações sobre 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 o Tipo de entrega como Push.
  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 Google Cloud console do, 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 informações sobre como nomear uma assinatura, consulte Diretrizes para nomear um tópico ou uma assinatura.

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

gcloud

  1. No Google Cloud console do, ative o Cloud Shell.

    Ativar o Cloud Shell

    Na parte de baixo do Google Cloud console do, uma Cloud Shell sessão é iniciada e exibe um prompt de linha de comando. O Cloud Shell é um ambiente shell com a Google Cloud CLI já instalada e com valores já definidos para o projeto atual. A inicialização da sessão pode levar alguns segundos.

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

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

    Substitua:

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

REST

Para criar uma assinatura por push, use o projects.subscriptions.create método:

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 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 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# .

    
    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

    O exemplo a seguir usa a versão principal da biblioteca de cliente do Go Pub/Sub (v2). Se você ainda estiver usando a biblioteca v1, consulte o guia de migração para a v2. Para conferir uma lista de exemplos de código v1, consulte os exemplos de código obsoletos.

    Antes de tentar esse exemplo, siga as instruções de configuração do Go 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 Go.

    import (
    	"context"
    	"fmt"
    	"io"
    
    	"cloud.google.com/go/pubsub/v2"
    	"cloud.google.com/go/pubsub/v2/apiv1/pubsubpb"
    )
    
    func createWithEndpoint(w io.Writer, projectID, topic, subscription, endpoint string) error {
    	// projectID := "my-project-id"
    	// topic := "projects/my-project-id/topics/my-topic"
    	// subscription := "projects/my-project/subscriptions/my-sub"
    	// 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.SubscriptionAdminClient.CreateSubscription(ctx, &pubsubpb.Subscription{
    		Name:               subscription,
    		Topic:              topic,
    		AckDeadlineSeconds: 10,
    		PushConfig:         &pubsubpb.PushConfig{PushEndpoint: endpoint},
    	})
    	if err != nil {
    		return fmt.Errorf("failed to create push sub: %w", err)
    	}
    	fmt.Fprintf(w, "Created push subscription: %v\n", sub)
    	return nil
    }
    

    Java

    Antes de tentar essa amostra, siga as instruções de configuração do Java 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 para Java (em inglês).

    
    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

    Antes de tentar essa amostra, siga as instruções de configuração do Node.js 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 para Node.js (em inglês).

    /**
     * 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.ts

    Antes de tentar essa amostra, siga as instruções de configuração do Node.js 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 para Node.js (em inglês).

    /**
     * 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 tentar esse exemplo, siga as instruções de configuração do PHP 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 PHP.

    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 tentar esse exemplo, siga as instruções de configuração do Python 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 Python do Pub/Sub.

    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

    O exemplo a seguir usa a biblioteca de cliente do Ruby Pub/Sub v3. Se você ainda estiver usando a biblioteca v2, consulte o guia de migração para a v3. Para conferir uma lista de exemplos de código do Ruby v2, consulte os exemplos de código obsoletos.

    Antes de tentar esse exemplo, siga as instruções de configuração do Ruby 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 Ruby.

    # topic_id          = "your-topic-id"
    # subscription_id   = "your-subscription-id"
    # endpoint          = "https://your-test-project.appspot.com/push"
    
    pubsub = Google::Cloud::PubSub.new
    subscription_admin = pubsub.subscription_admin
    
    subscription = subscription_admin.create_subscription \
      name: pubsub.subscription_path(subscription_id),
      topic: pubsub.topic_path(topic_id),
      push_config: {
        push_endpoint: endpoint
      }
    
    puts "Push subscription #{subscription_id} created."

    Monitorar assinaturas por 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 do Monitoring para o Pub/Sub.

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

    A seguir