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

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

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

イベントの使用例をいくつかご紹介します。

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

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

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

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

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

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

イベントの仕組み

ドライブで何かが発生すると、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 にドライブ イベントが追加されたことで、イベントを受信する 3 つ目の方法が利用可能になりました。

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

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

    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: {
        {
          '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: サブスクリプションの各イベントタイプをサポートする 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 がドライブ ファイルまたは共有ドライブで、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 サブスクリプションにメッセージを pull します。詳しくは、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 の使用量上限をご覧ください。