Skip to content

Instantly share code, notes, and snippets.

@tanaikech
Created August 27, 2017 02:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tanaikech/29d2d31cbe6e0d9bd662aedb121384f0 to your computer and use it in GitHub Desktop.
Save tanaikech/29d2d31cbe6e0d9bd662aedb121384f0 to your computer and use it in GitHub Desktop.
Exporting Project on Google Drive using Golang Quickstart

Exporting Project on Google Drive using Golang Quickstart

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))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment