处理 Google 云端硬盘中的活动

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

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

以下是一些有关如何使用事件的示例:

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

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

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

  • 深入了解用户如何管理其文件,帮助确定哪些方面可以改进内容管理。

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

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

事件的工作原理

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

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

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

活动 Drive API 资源 事件类型
用户对文件创建访问权限提案。 系统会创建 AccessProposal 资源。 新建访问权限提案

用户对文件创建审批。

系统会创建 Approval 资源。 新建审批
用户在 Google 文档、表格或幻灯片文件中发布评论。 系统会创建 Comment 资源。 新建评论
用户向文件夹或共享云端硬盘添加文件。 系统会创建 File 资源。 新建文件
用户对文件创建权限。 系统会创建 Permission 资源。 新建权限
用户回复评论。 系统会创建 Reply 资源。 新回复

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

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

下表介绍了订阅事件与查询事件之间的区别和原因:

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

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

如需查看支持的字段的列表,请参阅 Drive Activity API 参考文档中的 Action 资源
事件格式 Pub/Sub 消息,根据 CloudEvent 规范进行格式化。如需了解详情,请参阅 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 云项目中启用它们。您可以在单个 Google Cloud 项目中启用一个或多个 API。

Google Cloud 控制台

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

    启用 API

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

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

gcloud

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

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

    gcloud config set project PROJECT_ID

    PROJECT_ID 替换为应用的 云项目 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 事件。例如,如果您在共享云端硬盘上创建订阅,并且该共享云端硬盘中嵌套在多个子文件夹中的文件发生更改,则系统会生成一个事件。如需了解支持的资源 和云端硬盘事件类型,请参阅创建订阅的事件类型

以下 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/v1/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 并为更改后的资源指定至少一个字段。只有对聊天室和云端硬盘资源的订阅才支持包含资源数据。

    • False:排除资源数据。

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

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

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

  • TOPIC_NAME:您在云项目中创建的 Pub/Sub 主题的完整名称。此 Pub/Sub 主题接收订阅的事件。格式为 projects/PROJECT_ID/topics/TOPIC_IDnotificationEndpoint 字段用于指定 Pub/Sub 主题,订阅会将事件发送到该主题 。

测试云端硬盘订阅

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

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

云端硬盘事件会发送到您创建的订阅中的 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);
  }
});

限制

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