Exporting Project on Google Drive using Golang Quickstart

Gists

This is a sample script for exporting a project on Google Drive to local PC using Golang Quickstart. A file with refresh token is saved to the same directory with this script as go-quickstart.json. Before you run this script, please enable Drive API on your Google API console.

Points for exporting project

  1. In order to export project, both drive.DriveScriptsScope and drive.DriveScope have to be included in the scope.
  2. The mimeType for exporting has to be “application/vnd.google-apps.script+json”.

If you already have the file with refresh token, at first, please delete it and run this script. By this, the scopes of refresh token and access token are updated.

Script :

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"

    "golang.org/x/net/context"
    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "google.golang.org/api/drive/v3"
)

func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
    cacheFile := "./go-quickstart.json"
    tok, err := tokenFromFile(cacheFile)
    if err != nil {
        tok = getTokenFromWeb(config)
        saveToken(cacheFile, tok)
    }
    return config.Client(ctx, tok)
}

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 code string
    if _, err := fmt.Scan(&code); err != nil {
        log.Fatalf("Unable to read authorization code %v", err)
    }

    tok, err := config.Exchange(oauth2.NoContext, code)
    if err != nil {
        log.Fatalf("Unable to retrieve token from web %v", err)
    }
    return tok
}

func tokenFromFile(file string) (*oauth2.Token, error) {
    f, err := os.Open(file)
    if err != nil {
        return nil, err
    }
    t := &oauth2.Token{}
    err = json.NewDecoder(f).Decode(t)
    defer f.Close()
    return t, err
}

func saveToken(file string, token *oauth2.Token) {
    fmt.Printf("Saving credential file to: %s\n", file)
    f, err := os.Create(file)
    if err != nil {
        log.Fatalf("Unable to cache oauth token: %v", err)
    }
    defer f.Close()
    json.NewEncoder(f).Encode(token)
}

func main() {
    ctx := context.Background()
    b, err := ioutil.ReadFile("client_secret.json")
    if err != nil {
        log.Fatalf("Unable to read client secret file: %v", err)
    }
    // Here, in order to export project, drive.DriveScriptsScope, drive.DriveScope have to be included in the scope.
    config, err := google.ConfigFromJSON(b, drive.DriveScriptsScope, drive.DriveScope)
    if err != nil {
        log.Fatalf("Unable to parse client secret file to config: %v", err)
    }
    client := getClient(ctx, config)
    srv, err := drive.New(client)
    if err != nil {
        log.Fatalf("Unable to retrieve drive Client %v", err)
    }

    // Export project
    res, err := srv.Files.Export(
        "### Script ID of project ###",
        "application/vnd.google-apps.script+json", // mimeType is this.
    ).Download()
    if err != nil {
        log.Fatalf("Error: %v", err)
    }
    result, _ := ioutil.ReadAll(res.Body)
    fmt.Println(string(result))
}

 Share!