מדריך למתחילים

במדריכים למתחילים מוסבר איך להגדיר ולהפעיל אפליקציה שקוראת ל-Google Workspace API.

כדי לטפל בפרטים מסוימים בתהליך האימות וההרשאה, המדריכים למתחילים של Google Workspace משתמשים בספריות לקוח ה-API. אנחנו ממליצים להשתמש בספריות הלקוח של האפליקציות שלכם. המדריך למתחילים משתמש בגישת אימות פשוטה שמתאימה לסביבת הבדיקה. בסביבת ייצור, מומלץ ללמוד על אימות והרשאה לפני לבחור את פרטי הכניסה שמתאימים לאפליקציה.

יצירה של אפליקציית שורת הפקודה Go ששולחת בקשות אל Google Drive Activity API.

מטרות

  • הגדרת הסביבה.
  • מגדירים את הדוגמה.
  • מריצים את הדוגמה.

דרישות מוקדמות

  • חשבון Google.

הגדרת הסביבה

כדי להשלים את המדריך למתחילים, צריך להגדיר את הסביבה.

הפעלת ה-API

כדי להשתמש ב-Google APIs, צריך להפעיל אותם בפרויקט ב-Google Cloud. אפשר להפעיל ממשק API אחד או יותר בפרויקט אחד ב-Google Cloud.
  • במסוף Google Cloud, מפעילים את Google Drive Activity API.

    הפעלת ה-API

אם אתם משתמשים בפרויקט חדש ב-Google Cloud כדי להשלים את המדריך למתחילים, צריך להגדיר את מסך ההסכמה של OAuth ולהוסיף את עצמכם כמשתמשי בדיקה. אם כבר השלמתם את השלב הזה בפרויקט Cloud, דלגו לקטע הבא.

  1. במסוף Google Cloud, נכנסים לתפריט > APIs & Services > מסך ההסכמה של OAuth.

    מעבר למסך ההסכמה של OAuth

  2. בהגדרה סוג משתמש, בוחרים באפשרות פנימי ולוחצים על יצירה.
  3. ממלאים את טופס ההרשמה לאפליקציה ולוחצים על שמירה והמשך.
  4. בינתיים, אפשר לדלג על הוספת היקפים וללחוץ על שמירה והמשך. בעתיד, כשיוצרים אפליקציה לשימוש מחוץ לארגון ב-Google Workspace, צריך לשנות את סוג המשתמש לחיצוני ואז להוסיף את היקפי ההרשאות שנדרשים לאפליקציה.

  5. לבדוק את הסיכום של רישום האפליקציה. כדי לבצע שינויים, לוחצים על עריכה. אם הרישום של האפליקציה נראה בסדר, לוחצים על Back to Dashboard (חזרה למרכז השליטה).

אישור פרטי כניסה לאפליקציה בשולחן העבודה

כדי לאמת משתמשי קצה ולגשת לנתוני המשתמשים באפליקציה, צריך ליצור מזהה לקוח אחד או יותר של OAuth 2.0. מזהה הלקוח משמש לזיהוי אפליקציה יחידה לשרתי OAuth של Google. אם האפליקציה פועלת בכמה פלטפורמות, צריך ליצור מזהה לקוח נפרד לכל פלטפורמה.
  1. במסוף Google Cloud, נכנסים לתפריט > APIs & Services > Credentials.

    כניסה לדף Credentials

  2. לוחצים על יצירת פרטי כניסה > מזהה לקוח OAuth.
  3. לוחצים על סוג האפליקציה > אפליקציה למחשב.
  4. בשדה שם, מקלידים שם לפרטי הכניסה. השם הזה מוצג רק במסוף Google Cloud.
  5. לוחצים על יצירה. מופיע המסך של לקוח OAuth שנוצר, ומוצגים בו מזהה הלקוח וסוד הלקוח החדשים.
  6. לוחצים על אישור. פרטי הכניסה החדשים שנוצרו מופיעים בקטע מזהי לקוח ב-OAuth 2.0.
  7. שומרים את קובץ ה-JSON שהורדתם בתור credentials.json ומעבירים אותו לספריית העבודה.

הכנת סביבת העבודה

  1. יצירה של ספריית עבודה:

    mkdir quickstart
    
  2. מעבר לספריית העבודה:

    cd quickstart
    
  3. מפעילים את המודול החדש:

    go mod init quickstart
    
  4. קבלו את ספריית הלקוח של Google Drive Activity API Go ואת חבילת OAuth2.0:

    go get google.golang.org/api/driveactivity/v2
    go get golang.org/x/oauth2/google
    

הגדרת הדוגמה

  1. בספריית העבודה, יוצרים קובץ בשם quickstart.go.

  2. מדביקים את הקוד הבא בקובץ:

    drive/activity-v2/quickstart/quickstart.go
    package main
    
    import (
    	"context"
    	"encoding/json"
    	"fmt"
    	"log"
    	"net/http"
    	"os"
    	"reflect"
    	"strings"
    
    	"golang.org/x/oauth2"
    	"golang.org/x/oauth2/google"
    	"google.golang.org/api/driveactivity/v2"
    	"google.golang.org/api/option"
    )
    
    // Retrieve a token, saves the token, then returns the generated client.
    func getClient(config *oauth2.Config) *http.Client {
    	// The file token.json stores the user's access and refresh tokens, and is
    	// created automatically when the authorization flow completes for the first
    	// time.
    	tokFile := "token.json"
    	tok, err := tokenFromFile(tokFile)
    	if err != nil {
    		tok = getTokenFromWeb(config)
    		saveToken(tokFile, tok)
    	}
    	return config.Client(context.Background(), tok)
    }
    
    // Request a token from the web, then returns the retrieved token.
    func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
    	authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
    	fmt.Printf("Go to the following link in your browser then type the "+
    		"authorization code: \n%v\n", authURL)
    
    	var authCode string
    	if _, err := fmt.Scan(&authCode); err != nil {
    		log.Fatalf("Unable to read authorization code: %v", err)
    	}
    
    	tok, err := config.Exchange(context.TODO(), authCode)
    	if err != nil {
    		log.Fatalf("Unable to retrieve token from web: %v", err)
    	}
    	return tok
    }
    
    // Retrieves a token from a local file.
    func tokenFromFile(file string) (*oauth2.Token, error) {
    	f, err := os.Open(file)
    	if err != nil {
    		return nil, err
    	}
    	defer f.Close()
    	tok := &oauth2.Token{}
    	err = json.NewDecoder(f).Decode(tok)
    	return tok, err
    }
    
    // Saves a token to a file path.
    func saveToken(path string, token *oauth2.Token) {
    	fmt.Printf("Saving credential file to: %s\n", path)
    	f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
    	if err != nil {
    		log.Fatalf("Unable to cache oauth token: %v", err)
    	}
    	defer f.Close()
    	json.NewEncoder(f).Encode(token)
    }
    
    // Returns a string representation of the first elements in a list.
    func truncated(array []string) string {
    	return truncatedTo(array, 2)
    }
    
    // Returns a string representation of the first elements in a list.
    func truncatedTo(array []string, limit int) string {
    	var contents string
    	var more string
    	if len(array) <= limit {
    		contents = strings.Join(array, ", ")
    		more = ""
    	} else {
    		contents = strings.Join(array[0:limit], ", ")
    		more = ", ..."
    	}
    	return fmt.Sprintf("[%s%s]", contents, more)
    }
    
    // Returns the name of a set property in an object, or else "unknown".
    func getOneOf(m interface{}) string {
    	v := reflect.ValueOf(m)
    	for i := 0; i < v.NumField(); i++ {
    		if !v.Field(i).IsNil() {
    			return v.Type().Field(i).Name
    		}
    	}
    	return "unknown"
    }
    
    // Returns a time associated with an activity.
    func getTimeInfo(activity *driveactivity.DriveActivity) string {
    	if activity.Timestamp != "" {
    		return activity.Timestamp
    	}
    	if activity.TimeRange != nil {
    		return activity.TimeRange.EndTime
    	}
    	return "unknown"
    }
    
    // Returns the type of action.
    func getActionInfo(action *driveactivity.ActionDetail) string {
    	return getOneOf(*action)
    }
    
    // Returns user information, or the type of user if not a known user.
    func getUserInfo(user *driveactivity.User) string {
    	if user.KnownUser != nil {
    		if user.KnownUser.IsCurrentUser {
    			return "people/me"
    		}
    		return user.KnownUser.PersonName
    	}
    	return getOneOf(*user)
    }
    
    // Returns actor information, or the type of actor if not a user.
    func getActorInfo(actor *driveactivity.Actor) string {
    	if actor.User != nil {
    		return getUserInfo(actor.User)
    	}
    	return getOneOf(*actor)
    }
    
    // Returns information for a list of actors.
    func getActorsInfo(actors []*driveactivity.Actor) []string {
    	actorsInfo := make([]string, len(actors))
    	for i := range actors {
    		actorsInfo[i] = getActorInfo(actors[i])
    	}
    	return actorsInfo
    }
    
    // Returns the type of a target and an associated title.
    func getTargetInfo(target *driveactivity.Target) string {
    	if target.DriveItem != nil {
    		return fmt.Sprintf("driveItem:\"%s\"", target.DriveItem.Title)
    	}
    	if target.Drive != nil {
    		return fmt.Sprintf("drive:\"%s\"", target.Drive.Title)
    	}
    	if target.FileComment != nil {
    		parent := target.FileComment.Parent
    		if parent != nil {
    			return fmt.Sprintf("fileComment:\"%s\"", parent.Title)
    		}
    		return "fileComment:unknown"
    	}
    	return getOneOf(*target)
    }
    
    // Returns information for a list of targets.
    func getTargetsInfo(targets []*driveactivity.Target) []string {
    	targetsInfo := make([]string, len(targets))
    	for i := range targets {
    		targetsInfo[i] = getTargetInfo(targets[i])
    	}
    	return targetsInfo
    }
    
    func main() {
    	ctx := context.Background()
    	b, err := os.ReadFile("credentials.json")
    	if err != nil {
    		log.Fatalf("Unable to read client secret file: %v", err)
    	}
    
    	// If modifying these scopes, delete your previously saved token.json.
    	config, err := google.ConfigFromJSON(b, driveactivity.DriveActivityReadonlyScope)
    	if err != nil {
    		log.Fatalf("Unable to parse client secret file to config: %v", err)
    	}
    	client := getClient(config)
    
    	srv, err := driveactivity.NewService(ctx, option.WithHTTPClient(client))
    	if err != nil {
    		log.Fatalf("Unable to retrieve driveactivity Client %v", err)
    	}
    
    	q := driveactivity.QueryDriveActivityRequest{PageSize: 10}
    	r, err := srv.Activity.Query(&q).Do()
    	if err != nil {
    		log.Fatalf("Unable to retrieve list of activities. %v", err)
    	}
    
    	fmt.Println("Recent Activity:")
    	if len(r.Activities) > 0 {
    		for _, a := range r.Activities {
    			time := getTimeInfo(a)
    			action := getActionInfo(a.PrimaryActionDetail)
    			actors := getActorsInfo(a.Actors)
    			targets := getTargetsInfo(a.Targets)
    			fmt.Printf("%s: %s, %s, %s\n", time, truncated(actors), action, truncated(targets))
    		}
    	} else {
    		fmt.Print("No activity.")
    	}
    }
    

הרצת הדוגמה

  1. בספריית העבודה, יוצרים ומריצים את הדוגמה:

    go run quickstart.go
    
  1. בפעם הראשונה שמריצים את הדוגמה, מוצגת בקשה להעניק הרשאת גישה:
    1. אם עדיין לא נכנסתם לחשבון Google, נכנסים כשמוצגת בקשה לעשות זאת. אם נכנסת לכמה חשבונות, צריך לבחור חשבון אחד שישמש לצורך הרשאה.
    2. לוחצים על אישור.

    האפליקציה שלך ב-Go מפעילה את Google Drive Activity API ומתקשרת אליו.

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

השלבים הבאים