Simple Go Google Drive API for free webhosters (e.g. Heroku) which the sole purpose is to store generic files such as images and pdf/docs input by users. But as of now it can only store image files (jpg, jpeg, png).
This package doen't use goroutine for running api requests because I just learned Go in general. I would probably update this package in the future once I learned deep into it. I would appreciate if anyone can add them here 😉
Install package.
$ go get github.com/muktiwbw/gdstorage
There are couple of preparations to do before you can use it.
- Create a new project in GCP dashboard
- Go to Navigation menu > APIs & Services > Credentials
- Create credentials and choose Service account, fill in the Service account details (you can skip the optionals)
- Click the service account you just created
- Go to Keys tab, click Add key > Create new key, you will get a JSON file containing your service account data
APP_NAME
, your app name, it will be used for your storage root directory nameGOOGLE_ACCOUNT_SERVICE_JSON
, paste the content of the JSON file you just downloaded earlier as a string (make sure to remove the spaces just in case)DRIVE_APP_DIR_ID
, the ID of your storage root directory (you will get it after creating one, will be explained later)DRIVE_ORGANIZER_EMAIL
, your personal email so that you can organize files and folders from your drive's Shared with meGOOGLE_PROJECT_ID
, no need to set it yourself, it will be set automatically once you create a service instance
APP_NAME="Super Cool App"
GOOGLE_ACCOUNT_SERVICE_JSON=
DRIVE_APP_DIR_ID=
DRIVE_ORGANIZER_EMAIL=example@gmail.com
Create a service to access functions.
func main() {
// Load .env
if err := godotenv.Load(); err != nil {
log.Fatalf("Error loading .env: %v\n", err)
}
// Create a Google API service
srv, err := gdstorage.NewStorageService()
if err != nil {
log.Fatalf("Error creating storage service: %v\n", err)
}
gds := gdstorage.New(srv)
// List all of your app storages in current GCP project
storages, err := gds.GetAppStorages()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(storages)
// ...
}
List all of your app storages in current GCP project
storages, err := gds.GetAppStorages()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(storages)
Will output something like this
[
{
"id": "xxxxxxxxxxxxxxxx",
"name": "storage_super-cool-app_Super Cool App",
"url": "https://url-to-storage.dir/xxxxxxxxxxxxxxxx",
"mimeType": "application/vnd.google-apps.folder",
"createdAt": "timestamp"
},
{
"id": "yyyyyyyyyyyyyyyyy",
"name": "storage_semi-cool-app_Semi Cool App",
"url": "https://url-to-storage.dir/yyyyyyyyyyyyyyyyy",
"mimeType": "application/vnd.google-apps.folder",
"createdAt": "timestamp"
},
{
"id": "zzzzzzzzzzzzzzzzz",
"name": "storage_generic-app_Generic App",
"url": "https://url-to-storage.dir/zzzzzzzzzzzzzzzzz",
"mimeType": "application/vnd.google-apps.folder",
"createdAt": "timestamp"
}
]
Create a storage root directory for current GCP project.
storage, err := gds.CreateAppStorage()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(storage)
It will give you the directory id
which you need to assign to DRIVE_APP_DIR_ID
environment variable. Before you run it make sure to set APP_NAME
because your storage name will need app name in it.
{
"id": "xxxxxxxxxxxxxxxx",
"name": "storage_super-cool-app_Super Cool App",
"url": "https://url-to-storage.dir/xxxxxxxxxxxxxxxx",
"mimeType": "application/vnd.google-apps.folder",
"createdAt": "timestamp"
}
Creating a root directory also gives writer
permission to google account with DRIVE_ORGANIZER_EMAIL
email address. From now on you can create folders or put static files in it.
For folders, you might want to switch ownership with your service account email since those folders will be populated by your app.
Returns a directory by its id
. It can be used to check if certain parent directory exists or not.
parentID := "xxxxxxxxxxxxxxxxxx"
storage, err := gds.GetDirectory(parentID)
if err != nil {
fmt.Println(err.Error())
return
}
// You can check if it exists or not
if storage.ID != "" {
fmt.Println(fmt.Sprintf("Directory with id %s exists.", storage.ID))
} else {
fmt.Println(fmt.Sprintf("Directory with id %s does not exist.", storage.ID))
}
fmt.Println(storage)
{
"id": "xxxxxxxxxxxxxxxx",
"name": "storage_super-cool-app_Super Cool App",
"url": "https://url-to-storage.dir/xxxxxxxxxxxxxxxx",
"mimeType": "application/vnd.google-apps.folder",
"createdAt": "timestamp"
}
Returns files by query. It can be used to check if certain files exist or not.
query := "name contains 'user_69_' and mimeType='image/jpeg'"
files, err := gds.GetFilesByQuery(query)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(files)
[
{
"id": "xxxxxxxxxxxxxxxx",
"name": "user_69_image_89sudj9fjs9fd8",
"url": "https://url-to-file.dir/xxxxxxxxxxxxxxxx",
"mimeType": "image/jpeg",
"createdAt": "timestamp"
},
{
"id": "yyyyyyyyyyyyyyyyy",
"name": "user_69_image_sdf89y48w98grg",
"url": "https://url-to-file.dir/yyyyyyyyyyyyyyyyy",
"mimeType": "image/jpeg",
"createdAt": "timestamp"
}
]
Store a single file to parent directory.
fileName := "test-file"
parentID := "xxxxxxxxxxxxxxxxxx"
// file is *multipart.FileHeader
fileID, err := gds.StoreFile(&gdstorage.StoreFileInput{Name: fileName, FileHeader: file}, parentID)
if err != nil {
fmt.Println(err.Error())
return
}
// You can get the direct URL using gdstorage.GetURL(id), this is what you want to save in DB
fmt.Printf("Successfully created file. The URL is: %s", gdstorage.GetURL(fileID))
Store a single file to parent directory.
fileInputs := []*gdstorage.StoreFileInput{}
// files is []*multipart.FileHeader
for i, file := range files {
fileInputs = append(fileInputs, &gdstorage.StoreFileInput{Name: fmt.Sprintf("test-multiple-file-%d", i), FileHeader: file})
}
parentID := "xxxxxxxxxxxxxxxxxx"
fileIDs, err := gds.StoreFiles(fileInputs, parentID)
if err != nil {
fmt.Println(err.Error())
return
}
fileURLs := []string{}
for _, fileID := range fileIDs {
fileURLs = append(fileURLs, gdstorage.GetURL(fileID))
}
fmt.Printf("Successfully created multiple files. The URLs are: %v", fileURLs)
Delete a file by id.
fileID := "xxxxxxxxxxxxxxxxxx"
if err := gds.DeleteFile(fileID); err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("Successfully deleted file with id: %s", fileID)
Delete multiple files by ids.
fileIDs := []string{"xxxxxxxxxxxxxxxx", "yyyyyyyyyyyyyyyyyyyyyy", "zzzzzzzzzzzzzzzzzzz"}
if err := gds.DeleteFiles(fileIDs); err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("Successfully deleted files with ids: %v", fileIDs)
Get direct file URL to be displayed in your web.
url := gdstorage.GetURL(fileID)
fmt.Println(url)