Criar uma assinatura do Google Workspace

Esta página explica como usar a API Google Workspace Events para criar uma assinatura em um recurso do Google Workspace. Uma assinatura do Google Workspace permite que seu app receba informações sobre eventos do Google Workspace, que representam mudanças em um recurso do Google Workspace. Para saber quais recursos e tipos de evento são compatíveis com a API Google Workspace Events, consulte a Visão geral da API Google Workspace Events.

Esta página inclui as seguintes etapas para criar uma assinatura do Google Workspace:

  1. Prepare o ambiente.
  2. Crie e assine um tópico do Google Cloud Pub/Sub. Use esse tópico como um endpoint para receber eventos do Google Workspace.
  3. Chame o método create() da API Google Workspace Events no recurso Subscription.
  4. Teste sua assinatura do Google Workspace para garantir que o tópico do Pub/Sub receba os eventos aos quais você se inscreveu.
  5. Se quiser, configure como enviar eventos para um endpoint do app para que ele possa processar o evento e, se necessário, tomar medidas.

Pré-requisitos

Apps Script

  • Para usar os comandos da CLI do Google Cloud neste guia:
    1. Instale o Google Cloud CLI.
    2. Para inicializar a CLI gcloud, execute o seguinte código:
    3.   gcloud init
        
  • Um projeto do Google Cloud com o faturamento ativado. Para assinaturas do Chat, também é necessário ativar a API Chat no seu projeto do Cloud e configurar os campos Nome do app, URL do avatar e Descrição. Saiba mais em Criar um app do Google Chat.
  • Requer a autenticação do usuário com a tela de consentimento do OAuth configurada para o app. Ao configurar a tela de consentimento, é necessário especificar um escopo para oferecer suporte a cada tipo de evento da assinatura. Para configurar a tela de consentimento e identificar os escopos necessários, consulte Escolher escopos.
  • Um projeto do Apps Script:
    • Use seu projeto do Google Cloud em vez do padrão criado automaticamente pelo Apps Script.
    • Para todos os escopos que você adicionou para configurar a tela de consentimento do OAuth, também é necessário adicionar os escopos ao arquivo appsscript.json no seu projeto do Apps Script. Exemplo:
    • "oauthScopes": [
        "https://www.googleapis.com/auth/chat.messages.readonly"
      ]
          
    • Ative o serviço avançado Google Workspace Events.

Python

  • Python 3.6 ou mais recente
  • A ferramenta de gerenciamento de pacotes pip
  • As bibliotecas de cliente mais recentes do Google para Python. Para instalar ou atualizar, execute o seguinte comando na interface de linha de comando:
      pip3 install --upgrade google-api-python-client google-auth-oauthlib
      
  • Para usar os comandos da CLI do Google Cloud neste guia:
    1. Instale o Google Cloud CLI.
    2. Para inicializar a CLI gcloud, execute o seguinte código:
    3.   gcloud init
        
  • Um projeto do Google Cloud com o faturamento ativado. Para assinaturas do Chat, também é necessário ativar a API Chat no seu projeto do Cloud e configurar os campos Nome do app, URL do avatar e Descrição. Saiba mais em Criar um app do Google Chat.
  • Requer a autenticação do usuário com a tela de consentimento do OAuth configurada para o app. Ao configurar a tela de consentimento, é necessário especificar um escopo para oferecer suporte a cada tipo de evento da assinatura. Para configurar a tela de consentimento e identificar os escopos necessários, consulte Escolher escopos.

Configurar o ambiente

A seção a seguir explica como configurar seu ambiente antes de criar uma assinatura do Google Workspace.

Ative a API Google Workspace Events e a API Google Cloud Pub/Sub.

Antes de usar as APIs do Google, você precisa ativá-las em um projeto do Google Cloud. É possível ativar uma ou mais APIs em um único projeto do Google Cloud.

Console do Google Cloud

No console do Google Cloud, abra o projeto do Google Cloud para seu app e ative a API Google Workspace Events e a API Pub/Sub:

Ativar as APIs

gcloud

  1. No diretório de trabalho, faça login na sua Conta do Google:

    gcloud auth login
  2. Defina o projeto do Cloud para o app:

    gcloud config set project PROJECT_ID

    Substitua PROJECT_ID pelo ID do projeto do Cloud para o app.

  3. Ative a API Google Workspace Events e a API Google Cloud Pub/Sub:

    gcloud services enable pubsub.googleapis.com workspaceevents.googleapis.com

Criar credenciais do ID do cliente OAuth

Escolha o tipo de aplicativo para ver instruções específicas sobre como criar um ID do cliente do OAuth:

Aplicativo da Web

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de aplicativo > Aplicativo da Web.
  4. No campo Nome, digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. Adicione URIs autorizados relacionados ao seu app:
    • Apps do lado do cliente (JavaScript): em Origens JavaScript autorizadas, clique em Adicionar URI. Em seguida, insira um URI para usar nas solicitações do navegador. Isso identifica os domínios de onde o aplicativo pode enviar solicitações de API para o servidor OAuth 2.0.
    • Apps do lado do servidor (Java, Python e outros): em URIs de redirecionamento autorizados, clique em Adicionar URI. Em seguida, insira um URI de endpoint para o qual o servidor OAuth 2.0 possa enviar respostas.
  6. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.

    Anote o ID do cliente. As chaves secretas do cliente não são usadas para aplicativos da Web.

  7. Clique em OK. A credencial recém-criada aparece em IDs de cliente do OAuth 2.0.

Android

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de aplicativo > Android.
  4. No campo "Nome", digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. No campo "Nome do pacote", insira o nome do pacote do arquivo AndroidManifest.xml.
  6. No campo "Impressão digital do certificado SHA-1", insira a impressão digital do certificado SHA-1 gerada.
  7. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID do cliente.
  8. Clique em OK. A credencial recém-criada aparece em "IDs de cliente OAuth 2.0".

iOS

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de app > iOS.
  4. No campo "Nome", digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. No campo "ID do pacote", insira o identificador do pacote conforme listado no arquivo Info.plist do app.
  6. Opcional: se o app aparecer na App Store da Apple, insira o ID da App Store.
  7. Opcional: no campo "ID da equipe", insira a string exclusiva de 10 caracteres gerada pela Apple e atribuída à sua equipe.
  8. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.
  9. Clique em OK. A credencial recém-criada aparece em "IDs de cliente OAuth 2.0".

App do Chrome

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de aplicativo > App do Chrome.
  4. No campo "Nome", digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. No campo "ID do aplicativo", insira a string de ID exclusiva de 32 caracteres do seu app. Você pode encontrar esse valor de ID no URL do app na Chrome Web Store e no Painel de controle do desenvolvedor da Chrome Web Store.
  6. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.
  7. Clique em OK. A credencial recém-criada aparece em "IDs de cliente OAuth 2.0".

App para computador

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de aplicativo > App para computador.
  4. No campo Nome, digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.
  6. Clique em OK. A credencial recém-criada aparece em IDs de cliente OAuth 2.0.

TVs e dispositivos de entrada limitada

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de aplicativo > TVs e dispositivos de entrada limitados.
  4. No campo "Nome", digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.
  6. Clique em OK. A credencial recém-criada aparece em "IDs de cliente OAuth 2.0".

Plataforma Universal do Windows (UWP)

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Clique em Criar credenciais > ID do cliente OAuth.
  3. Clique em Tipo de app > Universal Windows Platform (UWP).
  4. No campo "Nome", digite um nome para a credencial. Esse nome é mostrado apenas no console do Google Cloud.
  5. No campo "ID da loja", insira o valor exclusivo de 12 caracteres do ID da Microsoft Store do seu app. Você pode encontrar esse ID no URL da Microsoft Store do app e no Centro de parceiros.
  6. Clique em Criar. A tela do cliente OAuth criado aparece, mostrando o novo ID e a chave secreta do cliente.
  7. Clique em OK. A credencial recém-criada aparece em "IDs de cliente OAuth 2.0".

Fazer o download do arquivo JSON da chave secreta do cliente

O arquivo de chave secreta do cliente é uma representação JSON das credenciais do ID do cliente OAuth que o app pode referenciar ao fornecer credenciais.

  1. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  2. Em IDs do cliente do OAuth 2.0, clique no ID do cliente que você criou.

  3. Clique em Fazer o download do JSON.

  4. Salve o arquivo como client_secrets.json.

Criar e se inscrever em um tópico do Pub/Sub

Nesta seção, você vai criar um tópico e uma assinatura do Pub/Sub. Seu tópico do Pub/Sub serve como o endpoint de notificação em que a assinatura do Google Workspace recebe eventos.

Para saber mais sobre como criar e gerenciar tópicos do Pub/Sub, consulte a documentação do Pub/Sub.

Para criar e se inscrever em um tópico do Pub/Sub:

Console do Google Cloud

  1. No console do Google Cloud, acesse a página do Pub/Sub:

    Acessar o Google Cloud Pub/Sub

    Verifique se o projeto do Cloud para o app está selecionado.

  2. Clique em Criar tópico e faça o seguinte:

    1. Digite um nome para o tópico, como workspace-events-topic.
    2. Deixe a opção Adicionar uma assinatura padrão selecionada. O Pub/Sub nomeia essa assinatura padrão de forma semelhante ao nome do tópico, como workspace-events-topic-sub.
    3. Opcional: atualize ou configure outras propriedades para o tópico.
  3. Clique em Criar. O nome completo do tópico é formatado como projects/PROJECT_ID/topics/TOPIC_ID. Você vai usar esse nome completo em uma etapa posterior.

  4. Conceda acesso para publicar mensagens do Pub/Sub no seu tópico:

    1. Na página do tópico, acesse o painel lateral e abra a guia Permissões.
    2. Clique em Adicionar principal.
    3. No campo Adicionar participantes, adicione a conta de serviço do aplicativo do Google Workspace que envia eventos para sua assinatura:
      1. Para eventos do Chat, chat-api-push@system.gserviceaccount.com.
      2. Para eventos do Meet, meet-api-event-push@system.gserviceaccount.com.
    4. No menu Atribuir papéis, selecione Pub/Sub Publisher.
    5. Clique em Salvar. Pode levar alguns minutos para atualizar as permissões do seu tópico.

gcloud

  1. No seu projeto do Cloud, crie um tópico executando o seguinte comando:

    gcloud pubsub topics create TOPIC_ID

    Substitua TOPIC_ID por um ID exclusivo do tópico, como workspace-events-topic.

    A saída mostra o nome completo do tópico, formatado como projects/PROJECT_ID/topics/TOPIC_ID. Anote o nome e verifique se o valor de PROJECT_ID é o ID do projeto do Cloud para o app. Você vai usar o nome do tópico na próxima etapa e para criar a assinatura do Google Workspace mais tarde.

  2. Conceder acesso para publicar mensagens no tópico:

    gcloud pubsub topics add-iam-policy-binding TOPIC_NAME --member='serviceAccount:GOOGLE_WORKSPACE_APPLICATION' --role='roles/pubsub.publisher'

    Substitua:

    • TOPIC_NAME: o nome completo do tópico, que é a saída da etapa anterior. Formatado como projects/PROJECT_ID/topics/TOPIC_ID.
    • GOOGLE_WORKSPACE_APPLICATION: o app do Google Workspace que precisa enviar eventos para sua assinatura:

      • Para receber eventos do Chat, use chat-api-push@system.gserviceaccount.com.
      • Para receber eventos do Meet, use meet-api-event-push@system.gserviceaccount.com.

    Pode levar alguns minutos para atualizar as permissões do seu tópico.

  3. Crie uma assinatura do Pub/Sub para o tópico:

     gcloud pubsub subscriptions create SUBSCRIPTION_NAME --topic=TOPIC_NAME

    Substitua:

    • SUBSCRIPTION_NAME: um nome para sua assinatura, como workspace-events-subscription.
    • TOPIC_NAME: o nome do tópico que você criou na etapa anterior.

Assinar um recurso do Google Workspace

Nesta seção, você se inscreve no recurso do Google Workspace que quer monitorar para eventos.

Escolher e identificar o recurso de destino

Em uma assinatura do Google Workspace, o recurso de destino é o recurso do Google Workspace que você monitora para eventos. O recurso de destino é representado no campo targetResource da assinatura, formatado usando o nome completo do recurso. Por exemplo, para uma assinatura que monitora um espaço do Google Chat (spaces/AAAABBBBBBB), o valor de targetResource é //chat.googleapis.com/spaces/AAAABBBBBBB.

Antes de criar a assinatura, use as seções a seguir para saber como identificar e formatar o recurso de destino.

Identificar um recurso de destino para o Chat

Recurso de destino Formato Limitações
Espaço

//chat.googleapis.com/spaces/SPACE

em que SPACE é o ID no nome do recurso do recurso space da API Chat. É possível conseguir o ID do URL do espaço ou usando o método spaces.list().

O usuário do Chat que autoriza a assinatura precisa ser membro do espaço usando a Conta do Google ou do Google Workspace.
Todos os espaços de um usuário

//chat.googleapis.com/spaces/-

A assinatura só recebe eventos dos espaços em que o usuário é membro pelo Google Workspace ou pela Conta do Google.
Usuário

//cloudidentity.googleapis.com/users/USER

em que USER é o ID no nome do recurso do recurso user da API Chat. Para saber mais, consulte Identificar e especificar usuários do Google Chat.

A assinatura só recebe eventos sobre o usuário que autorizou a assinatura. Um usuário não pode autorizar uma assinatura em nome de outros usuários.

Identificar um recurso de destino para o Meet

Recurso de destino Formato Limitações (se aplicável)
Espaço para reuniões //meet.googleapis.com/spaces/SPACE

em que SPACE é o ID no nome do recurso do recurso space da API REST do Meet. Confira mais detalhes em Como o Meet identifica um espaço de reunião.

Usuário //cloudidentity.googleapis.com/users/USER

em que USER é o ID no campo signedinUser.user do recurso participant da API REST do Meet. Para mais detalhes, consulte Trabalhar com participantes.

A assinatura recebe eventos sobre espaços de reunião em que o usuário é um dos seguintes:

  • O proprietário do espaço de reunião.
  • O organizador do evento do Google Agenda associado ao espaço de reunião.

Criar uma assinatura do Google Workspace

Para criar uma assinatura, use o método subscriptions.create() da API Google Workspace Events para criar um recurso Subscription. Especifique os seguintes campos:

  • targetResource: um Google Workspace que você identificou na seção anterior, formatado usando o nome completo do recurso.
  • eventTypes: uma matriz de um ou mais tipos de evento que você quer receber sobre o recurso. Por exemplo, se o app só precisa saber sobre novas mensagens postadas em um espaço do Chat, ele pode se inscrever em eventos sobre mensagens criadas.
  • notificationEndpoint: um endpoint de notificação em que sua assinatura do Google Workspace envia eventos. Use o tópico do Pub/Sub que você criou na seção anterior.
  • payloadOptions: opções para especificar quantos dados de recurso incluir no payload do evento. Essa configuração afeta o prazo de validade da sua assinatura. Para saber mais, consulte Dados de eventos.

Para criar uma assinatura do Google Workspace:

Apps Script

  1. No projeto do Apps Script, crie um novo arquivo de script chamado createSubscription e adicione o seguinte código:

    function createSubscription() {
      // The Google Workspace resource to monitor for events.
      const targetResource = 'TARGET_RESOURCE';
    
      // The types of events to receive.
      const eventTypes = [EVENT_TYPES];
    
      // The endpoint to deliver events to, such as a Google Cloud Pub/Sub topic.
      const pubsubTopic = 'TOPIC_NAME';
    
      // Whether to include resource data or not.
      const resourceData = RESOURCE_DATA;
    
      // Call the Workspace Events API using the advanced service.
      const response = WorkspaceEvents.Subscriptions.create({
        targetResource: targetResource,
        eventTypes: eventTypes,
        notificationEndpoint: {
          pubsubTopic: pubsubTopic,
        },
        payloadOptions: {
          includeResource: resourceData
        }
      });
      console.log(response);
    }
    

    Substitua:

    • TARGET_RESOURCE: o recurso do Google Workspace em que você está se inscrevendo, formatado como o nome completo do recurso. Por exemplo, para se inscrever em um espaço do Google Chat com o ID AAAABBBB, use //chat.googleapis.com/spaces/AAAABBBB.
    • EVENT_TYPES: um ou mais tipos de evento aos quais você quer se inscrever no recurso de destino. Formate como uma matriz de strings, como 'google.workspace.chat.message.v1.created'.
    • TOPIC_NAME: o nome completo do tópico do Pub/Sub que você criou no projeto do Cloud. Formatado como projects/PROJECT_ID/topics/TOPIC_ID.
    • RESOURCE_DATA: um booleano que especifica se a assinatura inclui dados de recursos no payload:

      • True: inclui todos os dados de recursos. Para limitar quais campos são incluídos, adicione o campo fieldMask e especifique pelo menos um campo para o recurso alterado. Somente as assinaturas de recursos do Chat são compatíveis com a inclusão de dados de recursos.
      • False: exclui dados de recursos.
  2. Para criar a assinatura do Google Workspace, execute a função createSubscription no seu projeto do Apps Script.

Python

  1. No diretório de trabalho, crie um arquivo chamado create_subscription.py e adicione o seguinte código:

    """Create subscription."""
    
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient.discovery import build
    
    # Specify required scopes.
    SCOPES = [SCOPES]
    
    # Authenticate with Google Workspace and get user authentication.
    flow = InstalledAppFlow.from_client_secrets_file('client_secrets.json', SCOPES)
    CREDENTIALS = flow.run_local_server()
    
    # The Google Workspace resource to monitor for events.
    TARGET_RESOURCE = 'TARGET_RESOURCE'
    
    # The types of events to receive.
    EVENT_TYPES = [EVENT_TYPES]
    
    # The endpoint to deliver events to, such as a Google Cloud Pub/Sub topic.
    TOPIC = 'TOPIC_NAME'
    
    # Call the Workspace Events API using the service endpoint.
    service = build(
        'workspaceevents',
        'v1',
        credentials=CREDENTIALS,
    )
    
    BODY = {
        'target_resource': TARGET_RESOURCE,
        'event_types': EVENT_TYPES,
        'notification_endpoint': {'pubsub_topic': TOPIC},
        'payload_options': {'include_resource': RESOURCE_DATA},
    }
    response = service.subscriptions().create(body=BODY).execute()
    print(response)
    

    Substitua:

    • SCOPES: um ou mais escopos do OAuth compatíveis com cada tipo de evento da assinatura. Formatado como uma matriz de strings. Para listar vários escopos, separe-os por vírgulas. Por exemplo, 'https://www.googleapis.com/auth/chat.spaces.readonly', 'https://www.googleapis.com/auth/chat.memberships.readonly'.
    • TARGET_RESOURCE: o recurso do Google Workspace em que você está se inscrevendo, formatado como o nome completo do recurso. Por exemplo, para se inscrever em um espaço do Google Chat com o ID AAAABBBB, use //chat.googleapis.com/spaces/AAAABBBB.
    • EVENT_TYPES: um ou mais tipos de evento aos quais você quer se inscrever no recurso de destino. Formate como uma matriz de strings, como 'google.workspace.chat.message.v1.created'.
    • TOPIC_NAME: o nome completo do tópico do Pub/Sub que você criou no projeto do Cloud. Formatado como projects/PROJECT_ID/topics/TOPIC_ID.
    • RESOURCE_DATA: um booleano que especifica se a assinatura inclui dados de recursos no payload:

      • True: inclui todos os dados de recursos. Para limitar quais campos são incluídos, adicione o campo fieldMask e especifique pelo menos um campo para o recurso alterado. Somente as assinaturas de recursos do Chat são compatíveis com a inclusão de dados de recursos.
      • False: exclui dados de recursos.
  2. Para criar a assinatura do Google Workspace, execute o seguinte no terminal:

    python3 create_subscription.py

A API Google Workspace Events retorna uma operação de longa duração concluída que contém a instância do recurso Subscription que você criou.

Testar sua assinatura do Google Workspace

Para testar se você está recebendo eventos do Google Workspace, acione um evento e extraia mensagens para a assinatura do Pub/Sub.

Para testar sua assinatura do Google Workspace:

Console do Google Cloud

  1. Acionar um ou mais tipos de eventos no recurso de destino da sua assinatura do Google Workspace. Por exemplo, se você se inscreveu para receber novas mensagens em um espaço do Chat, envie uma mensagem para o espaço.

  2. No console do Google Cloud, acesse a página do Pub/Sub:

    Ir para o Pub/Sub

    Verifique se o projeto do Cloud para o app está selecionado.

  3. No menu Pub/Sub, clique em Assinaturas.

  4. Na tabela, encontre a assinatura do Pub/Sub para seu tópico e clique no nome dela.

  5. Clique na guia Mensagens.

  6. Clique em Pull. Pode levar alguns minutos para que um evento gere uma mensagem do Pub/Sub.

gcloud

  1. Acionar um ou mais tipos de eventos no recurso de destino da sua assinatura do Google Workspace. Por exemplo, se você se inscreveu para receber novas mensagens em um espaço do Chat, publique uma mensagem nele.

  2. Execute este comando:

    gcloud pubsub subscriptions pull PUBSUB_SUBSCRIPTION_NAME --format=json --limit=MESSAGE_COUNT --auto-ack

    Substitua:

    • PUBSUB_SUBSCRIPTION_NAME: o nome completo da assinatura do Pub/Sub, formatado como projects/SUBSCRIPTION_ID/subscriptions/SUBSCRIPTION_ID.
    • MESSAGE_COUNT: o número máximo de mensagens do Pub/Sub que você quer extrair.

    Pode levar alguns minutos para que um evento gere uma mensagem do Pub/Sub.

Para cada evento do Google Workspace acionado, uma mensagem é enviada à assinatura do Pub/Sub que contém o evento. Para mais detalhes, consulte Receber eventos como mensagens do Google Cloud Pub/Sub.

Configurar como o app recebe eventos

A assinatura do Pub/Sub que você criou é baseada em pull. Depois de testar a assinatura do Pub/Sub, atualize o tipo de entrega para mudar a forma como o app recebe eventos. Por exemplo, é possível configurar a assinatura do Pub/Sub para um tipo de entrega por push, para que o app receba eventos diretamente em um endpoint do app.

Para saber como configurar uma assinatura do Pub/Sub, consulte a documentação do Pub/Sub.