今天我們把的範例整理一下,首先先把操作Google Cloud的部分移到adapter
首先,我們在adapter建立資料夾google
,並建立oauth.go和drive.go
接著我們先定義一個結構體 GoogleOAuth
,包含一個 oauth2.Config
指標。NewGoogleOAuth
用於創建並返回一個 GoogleOAuth
實例,初始化一個 oauth2.Config
並將其指標賦值給 GoogleOAuth
的 Config
字段。NewGoogleOAuth
的參數會在server.go由NewGinLambda()
和StartNgrokServer()
,從AWS SSM或env代入。
// oauth.go
package google
import (
"context"
"log"
"net/http"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/drive/v3"
)
type GoogleOAuth struct {
Config *oauth2.Config
}
func NewGoogleOAuth(clientID string, clientSecret string, redirectURL string) *GoogleOAuth {
return &GoogleOAuth{
Config: &oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
Endpoint: google.Endpoint,
Scopes: []string{drive.DriveScope},
RedirectURL: redirectURL,
},
}
}
把目前會用到的function封裝起來
// oauth.go
func (oa *GoogleOAuth) OAuthLoginURL() (oauthURL string) {
oauthURL = oa.Config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
return oauthURL
}
func (oa *GoogleOAuth) UserOAuthToken(authCode string) (*oauth2.Token, error) {
token, err := oa.Config.Exchange(context.TODO(), authCode)
if err != nil {
log.Printf("Unable to retrieve token from web %v", err)
return nil, err
}
return token, nil
}
func (oa *GoogleOAuth) NewClientByUserToken(tok *oauth2.Token) *http.Client {
return oa.Config.Client(context.Background(), tok)
}
OAuthLoginURL
返回一個 Google OAuth 登入的 URL。oa.Config.AuthCodeURL
生成授權 URL,其中包括一個隨機的 "state-token" 和 oauth2.AccessTypeOffline
參數,用於支援 "refresh_token"。UserOAuthToken
用於交換授權碼(authCode)以獲取用戶的 OAuth 2.0 令牌。oa.Config.Exchange
進行令牌的交換,如果交換失敗,輸出並返回錯誤信息。NewClientByUserToken
根據給定的 OAuth 2.0 令牌創建一個新的 HTTP 客戶端。接著到drive.go,定義一個結構體 GoogleDrive
,包含一個 drive.Service
指標。
// drive.go
package google
import (
"context"
"fmt"
"log"
"net/http"
"google.golang.org/api/drive/v3"
"google.golang.org/api/option"
)
type GoogleDrive struct {
Service *drive.Service
}
func NewGoogleDrive(ctx context.Context, client *http.Client) (*GoogleDrive, error) {
srv, err := drive.NewService(ctx, option.WithHTTPClient(client))
if err != nil {
log.Printf("Unable to retrieve Drive client: %v", err)
return nil, err
}
return &GoogleDrive{
Service: srv,
}, nil
}
封裝ListFiles
// drive.go
func (d *GoogleDrive) ListFiles(pageSize int) (map[string]string, error) {
nameM := make(map[string]string)
r, err := d.Service.Files.List().PageSize(int64(pageSize)).
Fields("nextPageToken, files(id, name)").Do()
if err != nil {
log.Printf("Unable to retrieve files: %v", err)
return nil, err
}
fmt.Println("Files:")
if len(r.Files) == 0 {
fmt.Println("No files found.")
} else {
for _, i := range r.Files {
nameM[i.Id] = i.Name
fmt.Printf("%s (%s)\n", i.Name, i.Id)
}
}
fmt.Println("nameM:", nameM)
return nameM, nil
}
ListFiles
用於列出 Google Drive 上的文件。d.Service.Files.List()
來創建一個文件列表的查詢,設定頁面大小和要擷取的欄位。Do
來發送查詢,並得到文件列表的回應(*drive.FileList
)。nameM
中,最後印出後返回nameM
。那今天就先寫到這裡,明天再繼續,我們明天見~