עבודה עם אירועים מ-Google Drive

בדף הזה מוסבר איך לקבל אירועים מ-Google Drive דרך Google Cloud Pub/Sub.

אירוע ב-Drive מייצג פעילות או שינוי במשאב ב-Drive, כמו קובץ חדש בתיקייה. אתם יכולים להשתמש באירועים כדי להבין מה קרה ואז לפעול, או כדי להגיב בצורה משמעותית למשתמשים.

ריכזנו כאן כמה דוגמאות לשימוש באירועים:

  • לצפות בשינויים בקובץ, בתיקייה או באחסון שיתופי ולהגיב להם, למשל כשקובץ נערך או כשמעלים גרסה חדשה.

  • כדאי לעקוב אחרי שינויים בקבצים כדי לשפר את הביצועים של האפליקציה.

  • ביקורת על פעילויות כמו שיתוף קבצים, העברת קבצים ומחיקות עוזרת לזהות דליפות פוטנציאליות של נתונים וגישה לא מורשית.

  • התובנות האלה עוזרות לכם להבין איך המשתמשים מנהלים את הקבצים שלהם, וכך לזהות תחומים שבהם אפשר לשפר את ניהול התוכן.

  • מעקב אחרי שינויים בקבצים כדי לוודא שהם עומדים בדרישות הרגולטוריות או במדיניות האבטחה.

  • ניתוח הפעילות ב-Drive באמצעות מוצרים אחרים של Google Cloud, כמו Eventarc,‏ Workflows ו-BigQuery.

איך אירועים פועלים

בכל פעם שמשהו קורה ב-Drive, נוצר, מתעדכן או נמחק משאב של Google Drive API. ‫Drive משתמש באירועים כדי לספק לאפליקציה מידע על סוג הפעילות שהתרחשה ועל משאב Drive API שהושפע.

ב-Drive, האירועים מסווגים לפי סוג. סוגי האירועים עוזרים לכם לסנן ולקבל רק את סוג המידע שאתם צריכים, ולטפל בפעילויות דומות באותו אופן.

בטבלה הבאה מוצגות הפעולות ב-Drive וההשפעה שלהן על משאב קשור ב-Drive API, וסוג האירוע שהאפליקציה שלכם ב-Drive מקבלת:

פעילות Drive API resource סוג אירוע
משתמש מוסיף קובץ לתיקייה או לאחסון שיתופי. נוצר משאב File. קובץ חדש
משתמש יוצר הצעה לגישה לקובץ. נוצר משאב AccessProposal. הצעה חדשה לגישה

קבלת אירועים מ-Google Drive

באופן מסורתי, אפליקציית Drive יכלה לאתר אירועים דרך Drive API או Google Drive Activity API. הוספנו אירועים של Drive ל-Google Workspace Events API, ועכשיו יש שלוש שיטות לקבלת אירועים:

בטבלה הבאה מוסבר ההבדל בין הרשמה לאירועים לבין שליפת נתונים של אירועים, ומוצגות הסיבות להירשם לאירועים.

הרשמה לאירועים ב-Google Workspace הרשמה לקבלת עדכונים על אירועים ב-Drive API שאילתה לאירועים ב-Drive Activity API
תרחישים לדוגמה
  • לסיים את הטיפול באירועים או להגיב להם בזמן אמת.
  • כדאי לעקוב אחרי שינויים במשאבים כדי לשפר את הביצועים של האפליקציה.
  • לקבל נתוני אירועים מובנים דרך Pub/Sub ולהשתמש במוצרי Google Cloud כמו Cloud Run.
  • זיהוי שינויים במטא-נתונים של קבצים ומעקב יעיל אחרי שינויים בפריטים ספציפיים באמצעות התראות בזמן אמת.
  • תומך בכתובת URL של קריאה חוזרת (callback) של webhook כדי להימנע משליחת בקשות חוזרות ונשנות לנקודות הקצה של ה-API.
  • אחזור היסטוריה מפורטת של כל הפעילויות, כולל מידע גרנולרי על כל אירוע.
  • אחזור פעילויות מדויקות שכוללות מידע על ActionDetail, Actor ו-Target למשימות ספציפיות כמו ביקורות.
API Google Workspace Events API Drive API Drive Activity API
מקור האירועים קבצים, תיקיות ותיקיות אחסון שיתופי changes.watch וגם files.watch DriveActivity
אירועים נתמכים
  • File
  • AccessProposal
רשימה של סוגי האירועים הנתמכים מופיעה בקטע סוגי אירועים ליצירת מינויים במסמכי העזרה של Google Workspace Events API.
Channel

רשימה של סוגי האירועים הנתמכים מופיעה במאמר הסבר על אירועי התראות ב-Google Drive API במסמכי התיעוד של Drive API.
Action

רשימה של השדות הנתמכים מופיעה במאמרי העזרה בנושא משאב Action ב-Drive Activity API.
פורמט האירוע הודעת Pub/Sub, בפורמט לפי מפרט CloudEvent. פרטים נוספים מופיעים במאמר בנושא מבנה האירועים ב-Google Workspace. משאב Drive API‏ (Channel) ‫Drive Activity API (Action)
נתוני אירוע מחרוזת בקידוד Base64 עם נתוני משאבים או בלי. דוגמאות למטענים ייעודיים (payload) זמינות במאמר בנושא נתוני אירועים. מטען ייעודי (payload) של JSON שמכיל נתוני משאבים. דוגמה למטען ייעודי (payload) מופיעה במאמר Channel במאמרי העזרה. מטען ייעודי (payload) של JSON שמכיל נתוני משאבים. דוגמה למטען ייעודי (payload) אפשר לראות בגוף התגובה של activity.query במאמרי העזרה.

תחילת העבודה עם אירועים ב-Drive

במדריך הזה מוסבר איך ליצור ולנהל מינוי לאירועים ב-Google Workspace במשאב Drive. כך האפליקציה יכולה לקבל אירועים דרך 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.

מסוף Google Cloud

  1. במסוף Google Cloud, פותחים את הפרויקט ב-Google Cloud של האפליקציה ומפעילים את Google Workspace Events API,‏ Pub/Sub API ו-Drive API:

    הפעלת ממשקי ה-API

  2. מוודאים שמפעילים את ממשקי ה-API בפרויקט הנכון ב-Cloud ולוחצים על הבא.

  3. מוודאים שמפעילים את ממשקי ה-API הנכונים ולוחצים על הפעלה.

gcloud

  1. בספריית העבודה, נכנסים לחשבון Google:

    gcloud auth login
  2. מגדירים את הפרויקט לפרויקט ב-Cloud של האפליקציה:

    gcloud config set project PROJECT_ID

    מחליפים את PROJECT_ID במזהה הפרויקט של פרויקט Cloud עבור האפליקציה.

  3. מפעילים את Google Workspace Events API,‏ Pub/Sub API ו-Drive API:

    gcloud services enable workspaceevents.googleapis.com \
    pubsub.googleapis.com \
    drive.googleapis.com

הגדרת מזהה לקוח

במאמר בנושא יצירת פרטי כניסה של מזהה לקוח OAuth מוסבר איך ליצור מזהה לקוח OAuth 2.0.

יוצרים נושא 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, משתמשים ב-method‏ subscriptions.create() של Google Workspace Events API כדי ליצור משאב 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: ערך בוליאני שמציין אם המינוי כולל נתוני משאבים במטען הייעודי (payload) של האירוע. המאפיין הזה משפיע על משך המינוי. מידע נוסף על נתוני אירועים

    • True: כולל את כל נתוני המשאבים. כדי להגביל את השדות שייכללו, מוסיפים את fieldMask ומציינים לפחות שדה אחד למשאב ששוּנה. רק מינויים לתמיכה במשאבים ב-Chat וב-Drive כוללים נתוני משאבים.

    • False: לא כולל נתוני משאבים.

  • INCLUDE_DESCENDANTS: שדה בוליאני ששייך ל-DriveOptions. האפשרות הזו זמינה רק אם targetResource הוא קובץ ב-Drive או אחסון שיתופי שסוג ה-MIME שלו מוגדר כ-application/vnd.google-apps.folder. אי אפשר להגדיר את ההגדרה הזו בתיקיית הבסיס של 'האחסון שלי' או באחסון שיתופי.

    • True: המינוי כולל את כל הקבצים ב-Drive שמופיעים ברשימת האירועים.

    • False: המינוי נוצר לקובץ בודד או לאחסון שיתופי שצוין כ-targetResource.

  • TOPIC_NAME: השם המלא של נושא ה-Pub/Sub שיצרתם בפרויקט שלכם ב-Cloud. נושא Pub/Sub הזה מקבל אירועים למינוי. הפורמט הוא projects/PROJECT_ID/topics/TOPIC_ID. בשדה notificationEndpoint מציינים את נושא Pub/Sub, וזה המקום שבו המינוי מספק אירועים.

בדיקת המינוי ל-Drive

כדי לבדוק שאתם מקבלים אירועים ב-Drive, אתם יכולים להפעיל אירוע ולשלוף הודעות למינוי Pub/Sub. מידע נוסף זמין במאמר בנושא בדיקת המינוי ל-Google Workspace.

עיבוד אירועים ב-Drive באמצעות 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);
  }
});

מגבלות

  • כשהשדה הבוליאני includeDescendants ב- DriveOptions הוא true, מינויים ל-Drive בתיקיות ובתיקיות אחסון שיתופי תמיד שולחים אירוע, גם אם הקובץ שהפעיל את האירוע נמצא ברמה נמוכה יותר בתיקייה שמשמשת למינוי ל-Drive.
  • יכול להיות שיצרתם מינוי לתיקייה, אבל לא תקבלו את כל האירועים בהיררכיית הקבצים כי יכול להיות שלא ניתנה למשתמש או לאפליקציה גישה אליהם. במקרה כזה, המינוי יישאר פעיל אבל לא תקבלו אירועים לגבי משאבים שאין לכם גישה אליהם.
  • המנויים נתמכים לאירועים בכל הקבצים והתיקיות, אבל לא בתיקיית הבסיס של אחסונים שיתופיים. אפשר להירשם לעדכונים רק לגבי קבצים ותיקיות באחסון שיתופי. שינויים שמתבצעים ישירות בתיקיית הבסיס של תיקיות באחסון השיתופי לא יפעילו אירועים.
  • למשתמש שמאשר את המינוי צריכה להיות הרשאה בקובץ שמתאים לאירועים שהוא נרשם לקבלת עדכונים לגביהם.
  • המינוי מקבל רק אירועים של משאבים שהמשתמש יכול לגשת אליהם דרך חשבון Google Workspace או חשבון Google שלו.