Go クイックスタート

クイックスタートでは、 Google Workspace API

Google Workspace クイックスタートでは、API クライアント ライブラリを使用して 認証と認可のフローの詳細を確認できます。おすすめの方法 独自のアプリ用のクライアント ライブラリを使用します。このクイックスタートでは、 テストに適したシンプルな認証アプローチ できます。本番環境では、Terraform の IAM 構成の 認証と認可 次の日付より前 アクセス認証情報の選択 選択することもできます

アプリケーションに対してリクエストを行う Go コマンドライン アプリケーションを作成する。 Google Drive Activity API。

目標

  • 環境を設定する。
  • サンプルを設定します。
  • サンプルを実行します。

前提条件

  • Google アカウント

環境の設定

このクイックスタートを完了するには、環境を設定します。

API を有効にする

Google API を使用する前に、Google Cloud プロジェクトで有効にする必要があります。 1 つの Google Cloud プロジェクトで 1 つ以上の API を有効にできます。
  • Google Cloud コンソールで、Google Drive Activity API を有効にします。

    API の有効化

このクイックスタートを完了するために新しい Google Cloud プロジェクトを使用する場合は、 OAuth 同意画面を開き、自分自身をテストユーザーとして追加します。すでに 完了している場合は、次のセクションにスキップしてください。

  1. Google Cloud コンソールで、メニュー に移動します。 > API とサービス > OAuth 同意画面

    OAuth 同意画面に移動

  2. [ユーザーの種類] で [内部] を選択し、[作成] をクリックします。
  3. アプリ登録フォームに入力し、[保存して次へ] をクリックします。
  4. 現時点では、スコープの追加をスキップして [保存して次へ] をクリックします。 将来的に、 [ユーザーの種類] を [外部] に変更してから、 アプリに必要な認証スコープを追加します。

  5. アプリ登録の概要を確認します。変更するには、[編集] をクリックします。アプリが 問題がなければ、[ダッシュボードに戻る] をクリックします。

デスクトップ アプリケーションの認証情報を承認する

エンドユーザーを認証してアプリでユーザーデータにアクセスするには、次のことを行う必要があります。 OAuth 2.0 クライアント ID を作成します。クライアント ID は Google の OAuth サーバーに送信します。アプリが複数のプラットフォームで動作する場合 プラットフォームごとに個別のクライアント ID を作成する必要があります。
  1. Google Cloud コンソールで、メニュー > [API と[サービス] > [認証情報] に移動します。

    [認証情報] に移動

  2. [認証情報を作成] > [OAuth クライアント ID] をクリックします。
  3. [アプリケーションの種類] > [デスクトップ アプリ] をクリックします。
  4. [名前] フィールドに、認証情報の名前を入力します。この名前は Google Cloud コンソールにのみ表示されます。
  5. [作成] をクリックします。OAuth クライアントの作成画面が表示され、新しいクライアント ID とクライアント シークレットが表示されます。
  6. [OK] をクリックします。新しく作成された認証情報が [OAuth 2.0 クライアント ID] に表示されます。
  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. サンプルを初めて実行すると、アクセスの承認を求められます。 <ph type="x-smartling-placeholder">
      </ph>
    1. Google アカウントにまだログインしていない場合は、ログインを求められたらログインします。条件 複数のアカウントにログインしている場合は、承認に使用するアカウントを 1 つ選択してください。
    2. [Accept] をクリックします。

    Go アプリケーションが実行され、Google Drive Activity API が呼び出されます。

    認証情報はファイル システムに保存されるため、次回サンプルを実行する際に 承認を求められることはありません。

次のステップ