Google ドライブのイベントを操作する

このページでは、Google Cloud Pub/Sub から Google ドライブのイベントを受信する方法について説明します。

ドライブ イベントは、フォルダ内の新しいファイルなど、ドライブ リソースに対するアクティビティまたは変更を表します。イベントを使用すると、何が起こったかを把握して対応したり、ユーザーにとって意味のある方法で応答したりできます。

イベントの使用例を次に示します。

  • ファイル、フォルダ、共有ドライブの変更(ファイルの編集や新しいリビジョンのアップロードなど)を監視し、対応します。

  • ファイルの変更をモニタリングして、アプリのパフォーマンスを改善します。

  • ファイル共有、ファイルの移動、削除などのアクティビティを監査して、データ漏洩や不正アクセスを検出します。

  • ユーザーがファイルをどのように管理しているかについての分析情報を提供し、コンテンツ管理を改善できる領域を特定するのに役立ちます。

  • ファイル変更を追跡して、規制要件またはセキュリティ ポリシーの遵守を確認します。

  • EventarcWorkflowsBigQuery などの他の Google Cloud プロダクトを使用して、ドライブ アクティビティを分析します。

イベントの仕組み

ドライブで何らかの処理が行われるたびに、Google Drive API リソースが作成、更新、削除されます。ドライブはイベントを使用して、発生したアクティビティのタイプと、影響を受けた Drive API リソースに関する情報をアプリに配信します。

ドライブはイベントを種類別に分類します。イベントタイプを使用すると、必要な種類の情報のみをフィルタして受信し、同様のアクティビティを同じ方法で処理できます。

次の表は、ドライブのアクティビティが関連する Drive API リソースにどのように影響するかと、ドライブアプリが受け取るイベントのタイプを示しています。

アクティビティ Drive API リソース イベントの種類
ユーザーがフォルダまたは共有ドライブにファイルを追加する。 File リソースが作成されます。 新しいファイル
ユーザーがファイルに対するアクセス提案を作成します。 AccessProposal リソースが作成されます。 新しいアクセス候補

Google ドライブからイベントを受信する

従来、ドライブアプリは Drive API または Google Drive Activity API を使用してイベントを特定していました。Google Workspace Events API にドライブ イベントが追加されたことで、イベントを受信する 3 つ目の方法が利用できるようになりました。

次の表に、イベントのサブスクライブとクエリの違いと理由を示します。

Google Workspace イベントをサブスクライブする Drive API のウォッチ イベントをサブスクライブする Drive Activity API イベントのクエリ
ユースケース
  • イベントをリアルタイムで処理または応答します。
  • リソースの変化をモニタリングして、アプリのパフォーマンスを改善します。
  • Pub/Sub を介して構造化イベントデータを受信し、Cloud Run などの Google Cloud プロダクトを使用します。
  • ファイル メタデータの変更を検出し、リアルタイム通知で特定のアイテムの変更を効率的にモニタリングします。
  • API エンドポイントのポーリングを繰り返さないように、Webhook コールバック URL をサポートします。
  • 各イベントの詳細情報など、すべてのアクティビティの詳細な履歴を取得します。
  • 監査などの特定のタスクの 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 プロジェクトで API を有効にする必要があります。1 つの Google Cloud プロジェクトで 1 つ以上の 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)を参照してください。

ドライブ サブスクリプションを作成する

サブスクリプションのサブジェクト(またはサブジェクトの階層の下にある他のファイル)が変更されると、クラウド イベントがディスパッチされます。たとえば、共有ドライブでサブスクリプションを作成し、その共有ドライブ内の複数のサブフォルダにネストされているファイルが変更されると、イベントが生成されます。サポートされているリソースとドライブ イベントタイプについては、サブスクリプションを作成するためのイベントタイプをご覧ください。

次の 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: サブスクリプションの各イベントタイプをサポートする 1 つ以上の OAuth スコープ。文字列の配列としてフォーマットされます。複数のスコープを一覧表示するには、カンマで区切ります。ベスト プラクティスとして、アプリが機能する最も制限の厳しいスコープを使用することをおすすめします。例: 'https://www.googleapis.com/auth/drive.file'

  • TARGET_RESOURCE: サブスクライブする Google Workspace リソース。完全なリソース名としてフォーマットされます。たとえば、ドライブのファイルまたはフォルダを購読するには、//drive.googleapis.com/files/FileID を使用します。

  • EVENT_TYPES: ターゲット リソースでサブスクライブする 1 つ以上のイベントタイプ'google.workspace.drive.file.v3.contentChanged' などの文字列の配列としてフォーマットします。

  • RESOURCE_DATA: サブスクリプションのイベント ペイロードにリソースデータが含まれるかどうかを指定するブール値。このプロパティは、サブスクリプションの期間に影響します。詳細については、イベントデータをご覧ください。

    • True: すべてのリソースデータが含まれます。含めるフィールドを制限するには、fieldMask を追加して、変更されたリソースのフィールドを 1 つ以上指定します。リソース データを含めることができるのは、Chat とドライブのリソースのサブスクリプションのみです。

    • False: リソースデータを除外します。

  • INCLUDE_DESCENDANTS: DriveOptions の一部であるブール値フィールド。targetResource が Google ドライブのファイルまたは MIME タイプが application/vnd.google-apps.folder に設定されている共有ドライブの場合にのみ使用できます。マイドライブまたは共有ドライブのルートフォルダには設定できません。

    • True: サブスクリプションには、イベントのリスト内のすべての子孫 Drive ファイルが含まれます。

    • False: targetResource として指定された単一のファイルまたは共有ドライブに対してサブスクリプションが作成されます。

  • TOPIC_NAME: Cloud プロジェクトで作成した Pub/Sub トピックの完全名。この Pub/Sub トピックは、サブスクリプションのイベントを受信します。projects/PROJECT_ID/topics/TOPIC_ID の形式で指定します。notificationEndpoint フィールドは、Pub/Sub トピックを指定するために使用されます。サブスクリプションは、このトピックにイベントを配信します。

ドライブのサブスクリプションをテストする

Drive イベントを受信していることをテストするには、イベントをトリガーして、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);
  }
});

制限事項

  • DriveOptionsincludeDescendants ブール値フィールドが true の場合、イベントをトリガーしたファイルが Drive サブスクリプションに使用されるフォルダの何層も下にネストされている場合でも、共有ドライブとフォルダの Drive サブスクリプションは常にイベントをディスパッチします。
  • フォルダでサブスクリプションを作成しても、ユーザーまたはアプリケーションにアクセス権が付与されていない場合、ファイル階層内のすべてのイベントを受信できないことがあります。この場合、サブスクリプションは有効なままですが、アクセスできないリソースのイベントは受信されません。
  • サブスクリプションは、すべてのファイルとフォルダのイベントでサポートされていますが、共有ドライブのルートフォルダではサポートされていません。サブスクリプションは、共有ドライブ内のファイルとフォルダでのみサポートされます。共有ドライブのルートフォルダに直接変更を加えても、イベントはトリガーされません。
  • サブスクリプションを承認するユーザーには、登録するイベントに対応するファイルに対する権限が必要です。
  • サブスクリプションは、ユーザーが Google Workspace アカウントまたは Google アカウントでアクセスできるリソースのイベントのみを受信します。