处理 Google 云端硬盘中的活动

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

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

以下一些示例展示了事件的使用方法:

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

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

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

  • 提供有关用户如何管理文件的分析洞见,帮助确定内容管理方面有待改进的地方。

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

  • 使用其他 Google Cloud 产品(例如 Eventarc、Workflows 和 BigQuery)分析云端硬盘活动。

事件的工作原理

每当云端硬盘中发生事件时,系统都会创建、更新或删除 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 端点。
  • 获取所有活动的详细历史记录,包括每个事件的精细信息。
  • 检索包含 ActionDetail、Actor 和 Target 信息的精确活动,以便执行审核等特定任务。
API Google Workspace Events API Google Drive API Google Drive Activity API
事件来源 文件、文件夹和共享云端硬盘 changes.watch 和 files.watch DriveActivity
支持的事件
  • AccessProposal
  • Approval
  • Comment
  • File
  • Permission
  • Reply
如需查看支持的事件类型列表,请参阅 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 项目中启用这些 API。您可以在单个 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 替换为应用的 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 事件。例如,如果您在共享云端硬盘上创建订阅,并且该共享云端硬盘中嵌套在多个子文件夹中的文件发生更改,则会生成一个事件。如需了解支持的资源和云端硬盘事件类型,请参阅用于创建订阅的事件类型。

以下 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: {
        {
          'RESOURCE_DATA'
        }
      }
    },
    drive_options: {
      include_descendants: {
        {
          'INCLUDE_DESCENDANTS'
        }
      }
    },
    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:您在云项目中创建的 Pub/Sub 主题的全名。此 Pub/Sub 主题会接收订阅的事件。格式为 projects/PROJECT_ID/topics/TOPIC_ID。notificationEndpoint 字段用于指定 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);
  }
});

限制

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

如需了解订阅配额和速率限制,请参阅 Google Workspace Events API 用量限额。