Trabalhar com eventos do Google Drive

Nesta página, explicamos como receber eventos do Google Drive do Google Cloud Pub/Sub.

Um evento do Drive representa uma atividade ou mudança em um recurso do Drive, como um novo arquivo em uma pasta. É possível usar eventos para entender o que aconteceu e tomar medidas ou responder de maneira significativa para os usuários.

Confira alguns exemplos de como usar eventos:

  • Observar e responder a mudanças em um arquivo, pasta ou drive compartilhado, como quando um arquivo é editado ou uma nova revisão é enviada por upload.

  • Monitore as mudanças nos arquivos para melhorar a performance do app.

  • Audite atividades como compartilhamento, movimentação e exclusão de arquivos para detectar possíveis vazamentos de dados e acessos não autorizados.

  • Oferecer insights sobre como os usuários estão gerenciando os arquivos, ajudando a identificar áreas em que o gerenciamento de conteúdo pode ser melhorado.

  • Acompanhe as mudanças nos arquivos para verificar a conformidade com os requisitos regulamentares ou políticas de segurança.

  • Analise a atividade do Drive usando outros produtos do Google Cloud, como Eventarc, Workflows e BigQuery.

Como os eventos funcionam

Sempre que algo acontece no Drive, um recurso da API Google Drive é criado, atualizado ou excluído. O Drive usa eventos para fornecer informações ao seu app sobre o tipo de atividade que ocorreu e o recurso da API Drive afetado.

O Drive categoriza os eventos por tipo. Os tipos de eventos ajudam a filtrar e receber apenas as informações necessárias, além de permitir que você lide com atividades semelhantes da mesma forma.

A tabela a seguir mostra como uma atividade no Drive afeta um recurso relacionado da API Drive e o tipo de evento que seu app do Drive recebe:

Atividade Recurso da API Drive Tipo de evento
Um usuário adiciona um arquivo a uma pasta ou drive compartilhado. Um recurso File é criado. Novo arquivo
Um usuário cria uma proposta de acesso em um arquivo. Um recurso AccessProposal é criado. Nova proposta de acesso

Receber eventos do Google Drive

Tradicionalmente, seu app Drive podia localizar eventos usando a API Drive ou a API Google Drive Activity. Com a adição de eventos do Drive na API Google Workspace Events, agora há um terceiro método para receber eventos:

A tabela a seguir explica a diferença e os motivos para assinar eventos em vez de consultá-los:

Inscrever-se nos eventos do Google Workspace Inscrever-se em eventos de observação da API Drive Consultar eventos da API Drive Activity
Casos de uso
  • Processar ou responder a eventos em tempo real.
  • Monitore as mudanças nos recursos para melhorar a performance do app.
  • Receba dados de eventos estruturados pelo Pub/Sub e use produtos do Google Cloud, como o Cloud Run.
  • Detecte mudanças nos metadados de arquivos e monitore com eficiência as alterações em itens específicos com notificações em tempo real.
  • Compatível com um URL de callback de webhook para evitar a sondagem repetida dos endpoints da API.
  • Extrair um histórico detalhado de todas as atividades, incluindo informações granulares sobre cada evento.
  • Recupere atividades precisas que incluem informações de ActionDetail, Actor e Target para tarefas específicas, como auditorias.
API API Google Workspace Events API Drive Drive Activity API
Origem dos eventos Arquivos, pastas e drives compartilhados changes.watch e files.watch DriveActivity
Eventos aceitos
  • File
  • AccessProposal
Para conferir uma lista de tipos de eventos compatíveis, consulte Tipos de eventos para criar assinaturas na documentação da API Google Workspace Events.
Channel

Para uma lista de tipos de eventos compatíveis, consulte Entender eventos de notificação da API Google Drive na documentação da API Drive.
Action

Para uma lista de campos compatíveis, consulte o recurso Action na documentação de referência da API Drive Activity.
Formato de eventos Uma mensagem do Pub/Sub, formatada de acordo com a especificação do CloudEvent. Para mais detalhes, consulte Estrutura dos eventos do Google Workspace. Um recurso da API Drive (Channel) Um recurso da API Drive Activity (Action)
Dados do evento String codificada em base64 com ou sem dados de recursos. Para exemplos de payloads, consulte Dados de eventos. Payload JSON que contém dados de recursos. Para um exemplo de payload, consulte o recurso Channel na documentação de referência. Payload JSON que contém dados de recursos. Para um exemplo de payload, consulte o corpo da resposta activity.query na documentação de referência.

Começar a usar eventos do Drive

Este guia explica como criar e gerenciar uma assinatura de eventos do Google Workspace em um recurso do Drive. Isso permite que seu app receba eventos pelo Google Cloud Pub/Sub.

Criar um projeto do Google Cloud

Para gerar um projeto do Google Cloud, consulte Criar um projeto do Google Cloud.

Ativar a API Google Workspace Events, a API Google Cloud Pub/Sub e a API Google Drive

Antes de usar as APIs do Google, é necessário 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

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

    Ative as APIs

  2. Confirme se você está ativando as APIs no projeto do Cloud correto e clique em Próxima.

  3. Confirme se você está ativando as APIs corretas e clique em Ativar.

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 seu app:

    gcloud config set project PROJECT_ID

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

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

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

Configurar um ID do cliente

Para gerar um ID do cliente OAuth 2.0, consulte Criar credenciais de ID do cliente OAuth.

Criar um tópico do Pub/Sub

Antes de criar uma assinatura, crie um tópico do Google Cloud Pub/Sub que receba eventos relevantes para seu aplicativo. Para criar o tópico do Pub/Sub, consulte Criar e assinar um tópico do Pub/Sub.

Não se esqueça de fazer referência à conta de serviço do Drive (drive-api-event-push@system.gserviceaccount.com) nas suas solicitações.

Criar uma assinatura do Drive

Os eventos do Cloud são enviados quando o assunto da assinatura (ou qualquer outro arquivo na hierarquia do assunto) muda. Por exemplo, se você criar uma assinatura em um drive compartilhado e um arquivo aninhado em várias subpastas desse drive for alterado, um evento será gerado. Para conferir os recursos e tipos de eventos do Drive compatíveis, consulte Tipos de eventos para criar assinaturas.

O aplicativo Node.js a seguir cria uma assinatura de eventos do Drive em um arquivo ou pasta para detectar eventos de mudança de conteúdo. Para mais informações, consulte Criar uma assinatura do Google Workspace.

Para executar este exemplo, verifique se você tem o Node.js e o npm instalados. Além disso, verifique se você instalou as dependências necessárias para executar este exemplo.

# Install needed dependencies
$ npm install googleapis @google-cloud/local-auth axios

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

// app.js

const fs = require('fs').promises;
const {authenticate} = require('@google-cloud/local-auth');
const {google} = require('googleapis');
const axios = require('axios');

// Scopes for Google Drive API access.
const SCOPES = ['SCOPES'];

/**
 * Authenticates the user running the script.
 * @return {Promise<OAuth2Client>} The authorized client.
 */
async function authorize() {
  const client = await authenticate({
    scopes: SCOPES,
    keyfilePath: 'credentials.json',
  });
  if (client.credentials) {
    const content = await fs.readFile('credentials.json');
    const keys = JSON.parse(content);
    const {client_id, client_secret} = keys.installed || keys.web;
    const payload = JSON.stringify({
      type: 'authorized_user',
      client_id,
      client_secret,
      refresh_token: client.credentials.refresh_token,
    });
    await fs.writeFile('token.json', payload);
    return client;
  } else {
    throw new Exception(
        'credentials.json did not have the Oauth client secret or it was not properly formatted');
  }
  }

/**
 * Creates a subscription to Google Drive events.
 * @param {OAuth2Client} authClient An authorized OAuth2 client.
 */
async function createSubscription(authClient) {
  const url = 'https://workspaceevents.googleapis.com/v1beta/subscriptions';
  const data = {
    targetResource: 'TARGET_RESOURCE',
    eventTypes: ['EVENT_TYPES'],
    payload_options: {
      include_resource: {
        {
          '<var>RESOURCE_DATA</var>'
        }
      }
    },
    drive_options: {
      include_descendants: {
        {
          '<var>INCLUDE_DESCENDANTS</var>'
        }
      }
    },
    notification_endpoint: {pubsub_topic: 'TOPIC_NAME'}
  };
  try {
    const {token} = await authClient.getAccessToken();
    const response = await axios.post(
        url, data, {headers: {'Authorization': `Bearer ${token}`}});
    console.log('Subscription created:', response.data);
  } catch (error) {
    const message = error.response ? error.response.data : error.message;
    console.error('Error creating subscription:', message);
  }
}

authorize().then(createSubscription).catch(console.error);

Substitua:

  • SCOPES: um ou mais escopos do OAuth que oferecem suporte a cada tipo de evento da assinatura. Formatado como uma matriz de strings. Para listar vários escopos, separe-os por vírgulas. Como prática recomendada, use o escopo mais restritivo que ainda permita o funcionamento do app. Por exemplo, 'https://www.googleapis.com/auth/drive.file'.

  • TARGET_RESOURCE: o recurso do Google Workspace a que você está se inscrevendo, formatado como o nome completo do recurso. Por exemplo, para se inscrever em um arquivo ou pasta do Drive, use //drive.googleapis.com/files/FileID.

  • EVENT_TYPES: um ou mais tipos de evento a que você quer se inscrever no recurso de destino. Formate como uma matriz de strings, como 'google.workspace.drive.file.v3.contentChanged'.

  • RESOURCE_DATA: um booleano que especifica se a assinatura inclui dados de recursos no payload do evento. Essa propriedade afeta a duração da sua assinatura. Para saber mais, consulte Dados de eventos.

    • True: inclui todos os dados de recursos. Para limitar os campos incluídos, adicione o fieldMask e especifique pelo menos um campo para o recurso alterado. Somente as assinaturas do Chat e do recurso do Drive permitem incluir dados de recursos.

    • False: exclui dados de recursos.

  • INCLUDE_DESCENDANTS: um campo booleano que faz parte de DriveOptions. Disponível apenas quando o targetResource é um arquivo do Drive ou um drive compartilhado com o tipo MIME definido como application/vnd.google-apps.folder. Não pode ser definido na pasta raiz do Meu Drive ou dos drives compartilhados.

    • True: a assinatura inclui todos os arquivos descendentes do Drive na lista de eventos.

    • False: a assinatura é criada para o arquivo único ou o drive compartilhado especificado como targetResource.

  • TOPIC_NAME: o nome completo do tópico do Pub/Sub que você criou no projeto do Cloud. Esse tópico do Pub/Sub recebe eventos para a assinatura. Formatado como projects/PROJECT_ID/topics/TOPIC_ID. O campo notificationEndpoint é usado para especificar o tópico do Pub/Sub, e é nele que a assinatura entrega eventos.

Testar sua assinatura do Drive

Para testar se você está recebendo eventos do Drive, acione um evento e extraia mensagens para a assinatura do Pub/Sub. Para mais informações, consulte Testar sua assinatura do Google Workspace.

Processar eventos do Drive usando o Cloud Functions

Os eventos do Drive são enviados ao tópico do Pub/Sub na assinatura que você cria. Ao criar o gatilho, verifique se o tópico do Pub/Sub para o gatilho corresponde ao tópico do Pub/Sub na sua assinatura de evento. Em seguida, implante sua função do Cloud Run e faça edições no arquivo para ver as mudanças de eventos nos registros.

Antes de criar a função, atualize o package.json para as dependências:

{
  "dependencies": {
    "@google-cloud/functions-framework": "^3.0.0",
    "cloudevents": "^8.0.0"
  }
}

Em seguida, crie o código-fonte da função:

const functions = require('@google-cloud/functions-framework');
const { HTTP } = require("cloudevents");

/**
 * A Cloud Function triggered by Pub/Sub messages containing Google Drive activity events.
 * This function processes different types of Drive events.
 *
 * @param {object} cloudEvent The CloudEvent object.
 * @param {object} cloudEvent.data The data payload from the event source.
 */
functions.cloudEvent('helloFromDrive', async (cloudEvent) => {
  try {
    // Verify the Pub/Sub message exists
    if (!cloudEvent.data || !cloudEvent.data.message) {
      console.warn("Event is missing the Pub/Sub message payload.");
      return;
    }

    // Extract the Pub/Sub message details
    const { message } = cloudEvent.data;
    const { attributes, data } = message;

    // The original Drive CloudEvent is reconstructed from the Pub/Sub message attributes
    const driveEvent = HTTP.toEvent({ headers: attributes });
    const { type } = driveEvent;

    // The Drive event's payload is a base64 encoded JSON string
    const payload = JSON.parse(Buffer.from(data, "base64").toString());

    console.log(`Processing Drive event type: ${type}`);

    // Use a switch statement to handle different event types
    switch (type) {
      case 'google.workspace.drive.file.v3.contentChanged':
        console.log('File Content Changed:', payload);
        break;
      case 'google.workspace.drive.accessproposal.v3.created':
        console.log('Access Proposal Created:', payload);
        break;
      default:
        console.log(`Received unhandled event type: ${type}`);
        break;
    }
  } catch (error) {
    console.error("An error occurred while processing the Drive event:", error);
  }
});

Limitações

  • Quando o campo booleano includeDescendants em DriveOptions é true, as assinaturas do Drive em drives e pastas compartilhados sempre enviam um evento, mesmo que o arquivo que acionou o evento esteja aninhado muitas camadas abaixo da pasta usada para a assinatura do Drive.
  • Mesmo que você tenha criado uma assinatura em uma pasta, talvez não receba todos os eventos na hierarquia de arquivos porque o usuário ou aplicativo não tem acesso a eles. Nesse caso, a assinatura permanece ativa, mas você não recebe eventos de recursos a que não tem acesso.
  • As assinaturas são compatíveis com eventos em todos os arquivos e pastas, mas não na pasta raiz dos drives compartilhados. As assinaturas só são compatíveis com arquivos e pastas dentro dos drives compartilhados. As mudanças feitas diretamente na pasta raiz de um drive compartilhado não acionam eventos.
  • O usuário que autoriza a inscrição precisa ter permissão no arquivo correspondente aos eventos em que se inscreveu.
  • A assinatura só recebe eventos de recursos a que o usuário tem acesso pela conta do Google Workspace ou Conta do Google.