处理 Google 云端硬盘中的活动

本页面介绍了如何从 Google Cloud Pub/Sub 接收 Google 云端硬盘事件。

云端硬盘事件表示对云端硬盘资源的活动或更改,例如文件夹中的新文件。您可以使用事件来了解发生了什么情况,然后采取行动,或者以有意义的方式为用户提供响应。

以下是一些示例,展示了如何使用事件:

  • 观察并响应文件、文件夹或共享云端硬盘中的更改,例如文件被修改或上传了新修订版本。

  • 监控文件更改,以提升应用性能。

  • 审核文件共享、文件移动和删除等活动,以帮助检测潜在的数据泄露和未经授权的访问。

  • 提供有关用户如何管理文件的数据洞见,帮助确定可以改进内容管理的方面。

  • 跟踪文件更改,以验证是否符合法规要求或安全政策。

  • 使用其他 Google Cloud 产品(例如 EventarcWorkflowsBigQuery)分析云端硬盘活动。

事件的运作方式

每当云端硬盘中发生某些事件时,系统都会创建、更新或删除 Google 云端硬盘 API 资源。云端硬盘使用事件向您的应用传递有关发生的活动类型和受影响的云端硬盘 API 资源的信息。

云端硬盘会按类型对活动进行分类。事件类型可帮助您过滤并仅接收所需类型的信息,并让您以相同的方式处理类似活动。

下表显示了云端硬盘中的活动如何影响相关的云端硬盘 API 资源,以及您的云端硬盘应用会收到哪种类型的事件:

活动 Drive API 资源 事件类型
用户将文件添加到文件夹或共享云端硬盘。 创建 File 资源。 新建文件
用户针对文件创建访问权限提案。 创建 AccessProposal 资源。 新的访问权限提案

接收来自 Google 云端硬盘的事件

过去,您的云端硬盘应用可以通过 Drive API 或 Google Drive Activity API 查找事件。随着 Google Workspace Events API 中新增了 Drive 事件,现在有第三种接收事件的方法:

下表说明了订阅事件与查询事件之间的区别以及订阅事件的原因:

订阅 Google Workspace 活动 订阅 Drive API 监视事件 查询 Drive Activity API 事件
使用场景
  • 实时处理或响应事件。
  • 监控资源变化,以提升应用性能。
  • 通过 Pub/Sub 接收结构化事件数据,并使用 Cloud Run 等 Google Cloud 产品。
  • 检测文件元数据的更改,并通过实时通知高效监控特定项目的更改。
  • 支持 webhook 回调网址,以避免重复轮询 API 端点。
  • 获取所有活动的详细历史记录,包括有关每个事件的精细信息。
  • 检索包含 ActionDetailActorTarget 信息的精确活动,以用于审核等特定任务。
API Google Workspace Events API Drive API Drive Activity API
事件来源 文件、文件夹和共享云端硬盘 changes.watchfiles.watch DriveActivity
支持的事件
  • File
  • AccessProposal
如需查看支持的事件类型的列表,请参阅 Google Workspace Events API 文档中的 用于创建订阅的事件类型
Channel

如需查看支持的事件类型的列表,请参阅 Drive API 文档中的 了解 Google Drive API 通知事件
Action

如需查看受支持字段的列表,请参阅 Drive Activity API 参考文档中的 Action 资源
事件格式 根据 CloudEvent 规范设置格式的 Pub/Sub 消息。如需了解详情,请参阅 Google Workspace 事件的结构 Drive API 资源 (Channel) Drive Activity API 资源 (Action)
事件数据 包含或不包含资源数据的 Base64 编码字符串。如需查看载荷示例,请参阅事件数据 包含资源数据的 JSON 载荷。如需查看有效负载示例,请参阅参考文档中的 Channel 资源 包含资源数据的 JSON 载荷。如需查看有效负载示例,请参阅参考文档中的 activity.query 响应正文

开始使用云端硬盘活动

本指南介绍了如何在云端硬盘资源上创建和管理 Google Workspace 事件订阅。这样一来,您的应用就可以通过 Google Cloud Pub/Sub 接收事件。

创建 Google Cloud 项目

如需生成 Google Cloud 项目,请参阅创建 Google Cloud 项目

启用 Google Workspace Events API、Google Cloud Pub/Sub API 和 Google Drive API

在使用 Google API 之前,您需要在 Google Cloud 项目中启用它们。 您可以在单个 Google Cloud 项目中启用一个或多个 API。

Google Cloud 控制台

  1. 在 Google Cloud 控制台中,打开应用的 Google Cloud 项目,然后启用 Google Workspace Events API、Pub/Sub API 和 Drive API:

    启用 API

  2. 确认您要在正确的 Cloud 项目中启用 API,然后点击下一步

  3. 确认您要启用正确的 API,然后点击启用

gcloud

  1. 在工作目录中,登录您的 Google 账号:

    gcloud auth login
  2. 将项目设置为应用的 Cloud 项目:

    gcloud config set project PROJECT_ID

    PROJECT_ID 替换为应用的 Cloud 项目的项目 ID

  3. 启用 Google Workspace Events API、Pub/Sub API 和 Drive API:

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

设置客户端 ID

如需生成 OAuth 2.0 客户端 ID,请参阅创建 OAuth 客户端 ID 凭据

创建 Pub/Sub 主题

在创建订阅之前,您必须先创建一个 Google Cloud Pub/Sub 主题,用于接收您的应用感兴趣的相关事件。如需创建 Pub/Sub 主题,请参阅创建和订阅 Pub/Sub 主题

请务必在请求中引用云端硬盘服务账号 (drive-api-event-push@system.gserviceaccount.com)。

创建云端硬盘订阅

当订阅主题(或主题层次结构下的任何其他文件)发生更改时,系统会分派 Cloud 事件。例如,如果您在共享云端硬盘上创建订阅,并且该共享云端硬盘中嵌套在多个子文件夹中的某个文件发生更改,系统就会生成一个事件。如需了解支持的资源和 Google 云端硬盘事件类型,请参阅用于创建订阅的事件类型

以下 Node.js 应用会在文件或文件夹上创建云端硬盘事件订阅,以监听内容变更事件。如需了解详情,请参阅创建 Google Workspace 订阅

如需运行此示例,请确保您已安装 Node.js 和 npm。 您还需要确保已安装运行此示例所需的依赖项。

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

如需创建云端硬盘订阅,您可以使用 Google Workspace Events API 的 subscriptions.create() 方法来创建 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);

替换以下内容:

  • SCOPES:支持订阅的每种事件类型的一个或多个 OAuth 范围。格式为字符串数组。如需列出多个范围,请用英文逗号分隔。最佳实践是,您应使用仍能让应用正常运行的最严格的范围。例如 'https://www.googleapis.com/auth/drive.file'

  • TARGET_RESOURCE:您要订阅的 Google Workspace 资源,格式为完整资源名称。例如,如需订阅云端硬盘文件或文件夹,请使用 //drive.googleapis.com/files/FileID

  • EVENT_TYPES:您要在目标资源中订阅的一个或多个事件类型。格式为字符串数组,例如 'google.workspace.drive.file.v3.contentChanged'

  • RESOURCE_DATA:一个布尔值,用于指定订阅是否在事件载荷中包含资源数据。此属性会影响订阅的时长。如需了解详情,请参阅活动数据

    • True:包含所有资源数据。如需限制包含的字段,请添加 fieldMask 并为更改的资源指定至少一个字段。只有对 Chat 和云端硬盘资源的订阅支持包含资源数据。

    • False:排除资源数据。

  • INCLUDE_DESCENDANTS:属于 DriveOptions 的布尔值字段。仅当 targetResource 是云端硬盘文件或 MIME 类型设置为 application/vnd.google-apps.folder 的共享云端硬盘时可用。无法在“我的云端硬盘”或共享云端硬盘的根文件夹中设置。

    • True:相应订阅包含事件列表中的所有后代云端硬盘文件。

    • False:系统会为指定为 targetResource 的单个文件或共享云端硬盘创建订阅。

  • TOPIC_NAME:您在 Cloud 项目中创建的 Pub/Sub 主题的全名。此 Pub/Sub 主题接收订阅的事件。格式为 projects/PROJECT_ID/topics/TOPIC_IDnotificationEndpoint 字段用于指定 Pub/Sub 主题,订阅会向该主题传送事件。

测试您的 Google 云端硬盘订阅

如需测试您是否正在接收云端硬盘事件,您可以触发一个事件,然后将消息拉取到 Pub/Sub 订阅。如需了解详情,请参阅测试 Google Workspace 订阅

使用 Cloud Functions 处理 Google 云端硬盘事件

Drive 事件会发送到您创建的订阅中的 Pub/Sub 主题。请确保在创建触发器时,触发器的 Pub/Sub 主题与事件订阅中的 Pub/Sub 主题一致。然后,您可以部署 Cloud Run 函数并修改文件,以在日志中查看事件变化。

在创建函数之前,请更新依赖项的 package.json

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

接下来,创建函数的源代码:

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

限制

  • DriveOptions 中的 includeDescendants 布尔值字段为 true 时,即使触发事件的文件嵌套在用于云端硬盘订阅的文件夹下方多层,共享云端硬盘和文件夹上的云端硬盘订阅也始终会调度事件。
  • 即使您已在某个文件夹中创建订阅,您也可能无法收到文件层次结构中的所有事件,因为用户或应用可能未被授予对这些事件的访问权限。在这种情况下,订阅仍处于有效状态,但您不会收到自己无权访问的资源的任何事件。
  • 订阅功能支持所有文件和文件夹的事件,但不支持共享云端硬盘的根文件夹。订阅功能仅适用于共享云端硬盘的文件和文件夹。直接对共享云端硬盘的根文件夹所做的更改不会触发事件。
  • 授权订阅的用户必须对相应文件拥有权限,才能订阅相应事件。
  • 订阅仅接收用户通过其 Google Workspace 账号或 Google 账号有权访问的资源的事件。