이 페이지에서는 Google Cloud Pub/Sub에서 Google Drive 이벤트를 수신하는 방법을 설명합니다.
Drive 이벤트는 폴더의 새 파일과 같은 Drive 리소스의 활동 또는 변경사항을 나타냅니다. 이벤트를 사용하여 발생한 상황을 파악한 다음 조치를 취하거나 사용자에게 의미 있는 방식으로 응답할 수 있습니다.
다음은 이벤트를 사용하는 방법의 몇 가지 예시입니다.
파일이 수정되거나 새 버전이 업로드되는 경우와 같이 파일, 폴더 또는 공유 드라이브의 변경사항을 관찰하고 이에 대응합니다.
파일 변경사항을 모니터링하여 앱 성능을 개선합니다.
파일 공유, 파일 이동, 삭제와 같은 활동을 감사하여 잠재적인 데이터 유출 및 무단 액세스를 감지합니다.
사용자가 파일을 관리하는 방식에 관한 유용한 정보를 제공하여 콘텐츠 관리를 개선할 수 있는 영역을 파악하는 데 도움이 됩니다.
파일 변경사항을 추적하여 규제 요구사항 또는 보안 정책 준수 여부를 확인합니다.
Eventarc, Workflows, BigQuery와 같은 다른 Google Cloud 제품을 사용하여 Drive 활동을 분석합니다.
이벤트의 작동 방식
Drive에서 어떤 일이 발생할 때마다 Google Drive API 리소스가 생성, 업데이트 또는 삭제됩니다. Drive는 이벤트를 사용하여 발생한 활동의 유형과 영향을 받은 Drive API 리소스에 관한 정보를 앱에 제공합니다.
Drive는 유형별로 이벤트를 분류합니다. 이벤트 유형을 사용하면 필요한 정보 유형만 필터링하고 수신할 수 있으며 유사한 활동을 동일한 방식으로 처리할 수 있습니다.
다음 표에서는 Drive의 활동이 관련 Drive API 리소스에 미치는 영향과 Drive 앱이 수신하는 이벤트 유형을 보여줍니다.
활동 | Drive API 리소스 | 이벤트 유형 |
---|---|---|
사용자가 폴더 또는 공유 드라이브에 파일을 추가합니다. | File 리소스가 생성됩니다. |
새 파일 |
사용자가 파일에 대한 액세스 제안을 만듭니다. | AccessProposal 리소스가 생성됩니다. |
새 액세스 제안 |
Google Drive에서 이벤트 수신
기존에는 Drive 앱이 Drive API 또는 Google Drive Activity API를 통해 이벤트를 찾을 수 있었습니다. Google Workspace Events API에 Drive 이벤트가 추가됨에 따라 이제 이벤트를 수신하는 세 번째 방법이 있습니다.
개발자 프리뷰: Google Workspace Events API를 사용하여 이벤트를 구독하여 이벤트가 발생할 때 이벤트를 수신합니다. 자세한 내용은 Google Drive 이벤트 구독을 참고하세요.
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 응답 본문
을 참고하세요.
|
Drive 이벤트 시작하기
이 가이드에서는 Drive 리소스에서 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 프로젝트에서 사용 설정해야 합니다. 단일 Google Cloud 프로젝트에서 하나 이상의 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 서비스 계정(drive-api-event-push@system.gserviceaccount.com
)을 참조해야 합니다.
Drive 구독 만들기
구독 주제 (또는 주제 계층 구조 아래의 다른 파일)가 변경되면 클라우드 이벤트가 디스패치됩니다. 예를 들어 공유 드라이브에서 구독을 만들고 해당 공유 드라이브의 여러 하위 폴더 내에 중첩된 파일이 변경되면 이벤트가 생성됩니다. 지원되는 리소스 및 Drive 이벤트 유형은 구독 생성 이벤트 유형을 참고하세요.
다음 Node.js 애플리케이션은 콘텐츠 변경 이벤트를 수신 대기하기 위해 파일 또는 폴더에 Drive 이벤트 구독을 만듭니다. 자세한 내용은 Google Workspace 구독 만들기를 참고하세요.
이 예시를 실행하려면 Node.js와 npm이 설치되어 있어야 합니다. 이 예제를 실행하려면 필요한 종속 항목이 설치되어 있어야 합니다.
# Install needed dependencies
$ npm install googleapis @google-cloud/local-auth axios
Drive 구독을 만들려면 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
: 구독의 각 이벤트 유형을 지원하는 하나 이상의 OAuth 범위입니다. 문자열 배열로 형식이 지정됩니다. 여러 범위를 나열하려면 쉼표로 구분하세요. 앱이 작동할 수 있는 가장 제한적인 범위를 사용하는 것이 좋습니다. 예를 들면'https://www.googleapis.com/auth/drive.file'
입니다.TARGET_RESOURCE
: 구독 중인 Google Workspace 리소스입니다. 전체 리소스 이름으로 형식이 지정됩니다. 예를 들어 Drive 파일 또는 폴더를 구독하려면//drive.googleapis.com/files/FileID
를 사용합니다.EVENT_TYPES
: 대상 리소스에서 구독할 하나 이상의 이벤트 유형입니다.'google.workspace.drive.file.v3.contentChanged'
와 같은 문자열 배열로 형식을 지정합니다.RESOURCE_DATA
: 구독이 이벤트 페이로드에 리소스 데이터를 포함하는지 여부를 지정하는 불리언입니다. 이 속성은 구독 기간에 영향을 미칩니다. 자세한 내용은 이벤트 데이터를 참고하세요.True
: 모든 리소스 데이터를 포함합니다. 포함되는 필드를 제한하려면fieldMask
를 추가하고 변경된 리소스의 필드를 하나 이상 지정합니다. 리소스 데이터를 포함하는 것은 Chat 및 Drive 리소스 구독만 지원합니다.False
: 리소스 데이터를 제외합니다.
INCLUDE_DESCENDANTS
:DriveOptions
의 일부인 불리언 필드입니다.targetResource
이 Drive 파일이거나 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 구독 테스트하기
Drive 이벤트를 수신하는지 테스트하려면 이벤트를 트리거하고 Pub/Sub 구독으로 메시지를 가져오면 됩니다. 자세한 내용은 Google Workspace 구독 테스트하기를 참고하세요.
Cloud Functions를 사용하여 Drive 이벤트 처리
드라이브 이벤트는 사용자가 만든 구독의 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 계정을 통해 액세스할 수 있는 리소스의 이벤트만 수신합니다.