google drive apiを使ってファイルをアップロードする方法は公式の解説ではgolangのドキュメントが貧弱だ. golangからサービスアカウントで認証し, 共有ドライブ(shared drive)へファイルのアップロードを行おうとするとGoogle APIs Client Library for Goを解読する必要がある. quickstartではOAuth 2.0認証を使ってマイドライブ(mydrive)のファイル一覧を表示するサンプルがある. 少し検索するとOAuth 2.0認証やサービスアカウントでマイドライブへファイルをアップロードする方法が見つかるが, 共有ドライブへのアップロード方法は見つけることができなかったのでその方法を紹介する.
準備
- shared driveにdirectoryを作成する(driveIdはhttps://drive.google.com/drive/folders/XXX のXXX部分)
- サービスアカウントを発行しcredential.jsonを保存する
- google driveの画面 > メンバーを管理 でサービスアカウントを追加し投稿者権限を付与する
サンプルコード
以下のコードはsample.txtをshared driveへアップロードする. driveIdを上の説明を参考に書き換えた後sample.txt, credential.jsonを同じディレクトリに置いて実行する. shared driveへファイルをアップロードするにはSupportsAllDrives(true)
とする必要があり, ここに辿り着くまでに時間がかかり面倒だった.
Code
package main
import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"os"
"google.golang.org/api/drive/v3"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
)
// ServiceAccount : Use Service account
func ServiceAccount(credentialFile string) *http.Client {
b, err := ioutil.ReadFile(credentialFile)
if err != nil {
log.Fatal(err)
}
var c = struct {
Email string `json:"client_email"`
PrivateKey string `json:"private_key"`
}{}
json.Unmarshal(b, &c)
config := &jwt.Config{
Email: c.Email,
PrivateKey: []byte(c.PrivateKey),
Scopes: []string{
drive.DriveScope,
},
TokenURL: google.JWTTokenURL,
}
client := config.Client(oauth2.NoContext)
return client
}
func main() {
filePath := "sample.txt" // file path
driveId := "XXX"
//use survice account
client := ServiceAccount("credential.json") // Please set the json file of Service account.
srv, err := drive.New(client)
if err != nil {
log.Fatalf("Unable to retrieve drive Client %v", err)
}
uploadFile, err := os.Open(filePath)
if err != nil {
log.Fatalf("Cannot find such file %v", err)
}
folderIdList := [] string{driveId}
f := &drive.File{Name: filePath, Parents: folderIdList}
_, err = srv.Files.Create(f).SupportsAllDrives(true).Media(uploadFile).Do()
if err != nil {
log.Fatalf("Upload Failed %v", err)
}
}
Back to top