このページでは、Google Cloud Pub/Sub から Google ドライブのイベントを受信する方法について説明します。
ドライブ イベントは、フォルダ内の新しいファイルなど、ドライブ リソースに対するアクティビティまたは変更を表します。イベントを使用すると、何が起こったかを把握して対応したり、ユーザーにとって意味のある方法で応答したりできます。
イベントの使用例を次に示します。
ファイル、フォルダ、共有ドライブの変更(ファイルの編集や新しいリビジョンのアップロードなど)を監視し、対応します。
ファイルの変更をモニタリングして、アプリのパフォーマンスを改善します。
ファイル共有、ファイルの移動、削除などのアクティビティを監査して、データ漏洩や不正アクセスを検出します。
ユーザーがファイルをどのように管理しているかについての分析情報を提供し、コンテンツ管理を改善できる領域を特定するのに役立ちます。
ファイル変更を追跡して、規制要件またはセキュリティ ポリシーの遵守を確認します。
Eventarc、Workflows、BigQuery などの他の 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 Events API を使用してイベントに登録し、イベントが発生したときにイベントを受信します。詳細については、Google ドライブのイベントを購読するをご覧ください。
Drive API を使用してイベントをサブスクライブします。
changes.watch
メソッドを使用してユーザー変更イベントを取得するか、files.watch
メソッドを使用してファイル変更イベントを取得します。Google Drive Activity API を呼び出して、最近のイベントをクエリします。
次の表に、イベントのサブスクライブとクエリの違いと理由を示します。
Google Workspace イベントをサブスクライブする | Drive API のウォッチ イベントをサブスクライブする | Drive Activity API イベントのクエリ | |
---|---|---|---|
ユースケース |
|
|
|
API | Google Workspace Events API | Drive API | Drive Activity API |
イベントのソース | ファイル、フォルダ、共有ドライブ |
changes.watch 、files.watch
|
DriveActivity
|
サポートされるイベント |
|
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 コンソール
Google Cloud コンソールで、アプリの Google Cloud プロジェクトを開き、Google Workspace Events API、Pub/Sub API、Drive API を有効にします。
正しい Cloud プロジェクトで API を有効にしていることを確認し、[次へ] をクリックします。
正しい API を有効にしていることを確認し、[有効にする] をクリックします。
gcloud
作業ディレクトリで、Google アカウントにログインします。
gcloud auth login
プロジェクトをアプリの Cloud プロジェクトに設定します。
gcloud config set project PROJECT_ID
PROJECT_ID
は、アプリの Cloud プロジェクトのプロジェクト ID に置き換えます。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);
}
});
制限事項
DriveOptions
のincludeDescendants
ブール値フィールドがtrue
の場合、イベントをトリガーしたファイルが Drive サブスクリプションに使用されるフォルダの何層も下にネストされている場合でも、共有ドライブとフォルダの Drive サブスクリプションは常にイベントをディスパッチします。- フォルダでサブスクリプションを作成しても、ユーザーまたはアプリケーションにアクセス権が付与されていない場合、ファイル階層内のすべてのイベントを受信できないことがあります。この場合、サブスクリプションは有効なままですが、アクセスできないリソースのイベントは受信されません。
- サブスクリプションは、すべてのファイルとフォルダのイベントでサポートされていますが、共有ドライブのルートフォルダではサポートされていません。サブスクリプションは、共有ドライブ内のファイルとフォルダでのみサポートされます。共有ドライブのルートフォルダに直接変更を加えても、イベントはトリガーされません。
- サブスクリプションを承認するユーザーには、登録するイベントに対応するファイルに対する権限が必要です。
- サブスクリプションは、ユーザーが Google Workspace アカウントまたは Google アカウントでアクセスできるリソースのイベントのみを受信します。