快速入門導覽課程說明如何設定及執行會呼叫
Google Workspace API
Google Workspace 快速入門導覽課程會使用 API 用戶端程式庫
驗證和授權流程的詳細資訊建議做法
您為自己的應用程式使用用戶端程式庫本快速入門導覽課程會使用
適合用於測試的簡易驗證方式
環境。在正式環境中,建議您瞭解
驗證與授權
再
選擇存取認證
挑選適合您應用程式的語言版本
建立 Go 指令列應用程式,向
Google Drive Activity API。
目標
必要條件
設定環境
如要完成本快速入門導覽課程,請設定環境。
啟用 API
您必須先在 Google Cloud 專案中啟用這些 Google API,才能使用這些 API。
您可以在單一 Google Cloud 專案中啟用一或多個 API。
如要使用新的 Google Cloud 專案完成本快速入門導覽課程,請設定
將自己新增為測試使用者。如果您已
為 Cloud 專案完成這個步驟,請直接跳到下一節。
-
在 Google Cloud 控制台中,前往「選單」圖示 menu
> API 與服務
>「OAuth 同意畫面」。
前往 OAuth 同意畫面
- 在「使用者類型」部分選取「內部」,然後按一下「建立」。
- 填寫應用程式註冊表單,然後按一下「Save and Continue」。
您現在可以略過新增範圍的步驟,然後按一下「儲存並繼續」。
日後您可以製作並使用應用程式
Google Workspace 機構,您必須將「使用者類型」變更為「外部」,
新增應用程式所需的授權範圍。
- 查看應用程式註冊摘要。如要修改資訊,請按一下「編輯」。如果應用程式
註冊看起來沒有問題,請按一下 [返回資訊主頁]。
授權電腦版應用程式憑證
如要驗證使用者及存取應用程式中的使用者資料,您必須:
建立一或多個 OAuth 2.0 用戶端 ID。用戶端 ID 可用來識別
單一應用程式傳送至 Google 的 OAuth 伺服器。如果您的應用程式在多個平台上運作
您都必須為每個平台分別建立用戶端 ID。
-
在 Google Cloud 控制台中,依序點選「選單」圖示 menu > 「API 與」「服務」 >「憑證」。
前往「憑證」
- 依序點選「建立憑證」>「OAuth 用戶端 ID」。
- 依序按一下「應用程式類型」>「電腦版應用程式」。
- 在「名稱」欄位中輸入憑證的名稱。這個名稱只會顯示在 Google Cloud 控制台中。
- 點選「建立」。系統隨即會顯示已建立 OAuth 用戶端的畫面,並顯示您的新用戶端 ID 和用戶端密鑰。
- 按一下「OK」(確定)。新建立的憑證會顯示在「OAuth 2.0 用戶端 ID」之下。
- 將下載的 JSON 檔案儲存為
credentials.json
,然後移動
檔案複製到工作目錄
準備工作區
建立工作目錄:
mkdir quickstart
切換至工作目錄:
cd quickstart
初始化新模組:
go mod init quickstart
取得 Google Drive Activity API Go 用戶端程式庫和 OAuth2.0 套件:
go get google.golang.org/api/driveactivity/v2
go get golang.org/x/oauth2/google
設定範例
在工作目錄中,建立名為 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.")
}
}
執行範例
在工作目錄中建構並執行範例:
go run quickstart.go
-
第一次執行範例時,系統會提示您授予存取權:
-
如果尚未登入 Google 帳戶,請在系統提示時登入。如果
您已登入多個帳戶,請選取一個用於授權的帳戶。
- 然後點選 [Accept]。
Go 應用程式會執行並呼叫 Google Drive Activity API。
授權資訊會儲存在檔案系統中,因此下次您執行範例時
這樣系統就不會提示您授權
後續步驟