Using Google Drive API with Ruby

German Reynaga
3 min readDec 30, 2020

--

A few weeks ago I was looking for a way to implement Google Drive in one of my personal projects but the only thing I found was a dark documentation and no useful stackoverflow answers to solve my problem. After some hours I managed to decrypt the documentation and decided to print my own “how to use the Google Drive API with Ruby”.

The project

The idea behind my problem is to create an interface to store and retrieve big quantities of files like student photos, school grades, and almost anything. With that in mind I look for an S3 (which results a litle expensive for my needs), and also for a self-managed storage using minio, but avoiding the cost of storage results in an equally expensive cost for a server, so the right answer for my needs was to use Google Drive which has a good daily margin of get and upload requests.

The solution

As I said I used Google Drive to solve my problem, and I did it through google_drive gem which give us an interface to connect the API and make the get and upload requests we need.

First we have to deal with authentication, which commonly is the biggest problem when we try to use any external APIs but in this case it results really easy but I will not go into the details, just follow this guide using service account to authenticate will give you a resulting json file to download which we are going to use for configuration. Once you have the file save it where you like, I usually save this kind of things into a config folder

main/
...project scripts
downloads/
...Will contain our downloaded files
config/
|__ config_file.json # actually this file will have kinda ID name but we will refer to it as config_file.json

With the file already saved we can start to create our scripts. For educational purposes only I will show you how to upload and retrieve a file.

Upload Script

I created a class which will make the interface work to use Google Drive

require 'google_drive'class GoogleDriveService
# First we build the session using the config file
def self.get_session
GoogleDrive::Session.from_service_account_key(File.join(__dir__, 'config', 'config_file.json'))
end
# next we can upload a file by passing the file_path
def self.upload_file(file_path, file_name)
session = get_session
session.upload_from_file(file_path, file_name, convert: false)
end
end

and as easy as that we can upload a file, now let me explain what is going on here.
First we have a get_session method which builds a session by passing our config_file.json path, then we use that session on the upload_file method, which receives a file_path in absolute or relative form and the name we want it to have in google drive as the second parameter, so if we want to upload the ./files/tomato.txt and we want it to have the name “tomato_file.txt” in Google Drive we can do it in the following way

file_path_to_upload = File.join(__dir__, 'files', 'tomato.txt')
file_name = 'tomato_file.txt'
GoogleDriveService.upload_file(file_path_to_upload, file_name)

And that’s all we need to upload a local file

Get Script

Okay, I know, now we want to check if the file really uploaded, and we can achieve that by adding the following method to our existent class

class GoogleDriveService
Existent Code...
def self.download_file(file_name)
session = get_session
file = session.file_by_title(file_name)
blank_file = File.write(File.join(__dir__, 'downloads', file_name), nil)
file.download_to_file(blank_file.path)
end
end

Yeah, it’s easy as that. Now we have to explain it. This new download_file method will receive a file_name as its unique argument and this file name must be the one with which we saved it in Google Drive, in this case it is “tomato_file.txt” what this method will do is to find a file in the storage with that name, then we gonna need a container, which is just a blank file we can create on the go, that will receive the file data and we can use this as the following

file_name = 'tomato_file.txt'
GoogleDriveService.download_file(file_name)
# Will result on a new file saved on our downloads folder
downloads/
|__ tomato_file.txt

And that’s it, we can complement this with a loop through some specific folder filesif we need to make a massive upload as I said.

I hope you find this useful if it is what you were looking for.

--

--

German Reynaga

Full Stack web developer, passionate with education and constantly improving my background.