Skip to content

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.

Notifications You must be signed in to change notification settings

muktiwbw/gdstorage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Google Drive Storage API

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 😉

1. Installation

Install package.

$ go get github.com/muktiwbw/gdstorage

2. Configurations

There are couple of preparations to do before you can use it.

Google Cloud Project

  1. Create a new project in GCP dashboard
  2. Go to Navigation menu > APIs & Services > Credentials
  3. Create credentials and choose Service account, fill in the Service account details (you can skip the optionals)
  4. Click the service account you just created
  5. Go to Keys tab, click Add key > Create new key, you will get a JSON file containing your service account data

Environment Variables

  1. APP_NAME, your app name, it will be used for your storage root directory name
  2. GOOGLE_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)
  3. DRIVE_APP_DIR_ID, the ID of your storage root directory (you will get it after creating one, will be explained later)
  4. DRIVE_ORGANIZER_EMAIL, your personal email so that you can organize files and folders from your drive's Shared with me
  5. GOOGLE_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

3. Service Initialization

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)
  
  // ...
}

4. Storage Functions

GetAppStorages

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"
  }
]

CreateAppStorage

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.

alt text

For folders, you might want to switch ownership with your service account email since those folders will be populated by your app.

alt text

GetDirectory

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"
}

GetFilesByQuery

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"
  }
]

StoreFile

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))

StoreFiles

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)

DeleteFile

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)

DeleteFiles

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)

GetURL

Get direct file URL to be displayed in your web.

url := gdstorage.GetURL(fileID)
fmt.Println(url)

About

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.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages