Headless Google Drive Uploads
Uploading files to Google Drive from the command line without any fancy agents, exotic libraries, dependencies should be simple. And here’s how it’s done…
First of all we need an Access Token for the Google Drive account we’re uploading to. This can be attained in many different ways. I’ve written a simple bash script to get Google API authentication and access tokens, which can be found here. Note: due to a bug somewhere, Google doesn’t seem to like drive
scopes, so I’m using the all-enveloping https://docs.google.com/feeds
for now.
Once you have you Access Token, calling the Google Drive API is simple using mere cURL. Multipart uploads allow you to inject metadata along with your file data in one request.
In short, you make a PUT or POST request to https://www.googleapis.com/upload/drive/v2/files/?uploadType=multipart, with an Authorization: Bearer $ACCESS_TOKEN
header, and a Content-Type: multipart/related; boundary=$BOUNDARY
content type.
The payload should look like so:
--randomboundary Content-Type: application/json; charset=UTF-8 { "title": "My document", "parents": [ { "id": "xxxxxxxxx" } ] } --randomboundary Content-Type: application/text DATA HERE, KTHNX! --randomboundary
The whole script can be found here: https://github.com/soulseekah/bash-utils/blob/master/google-drive-upload/upload.sh. As you can see, we feed the whole file from stdin
along with the necessary boundaries.
The “parents” argument “id” should be set to the ID of a folder in Google Drive. If left empty, the file will be uploaded to the root folder. You can get the ID from the URL in your Google Drive when visiting a folder. A list of mime-types for the file can be found in this stackoverflow answer.
Hope this helps folks out there that want to upload files to Google Drive from the command line.
I’m not able to get Access token. It says
Go to and enter to grant access to this application. Hit enter when done…
Access Token:
Refresh Token:
I’ve populated ID and SECRET with my google account and pw.
If you’re not getting the URL to go to with the code you need to enter then your ID and SECRET are incorrect. ID and SECRET are not your Google login and password, but actual API keys that you get through your development dashboard. See https://code.google.com/apis/console/?pli=1 for more information.
I had to create Developer account (?) and get an ID, etc. the problem is my grep doesn’t handle “\s” backslash s, and I have no clue what \K backslash K is!! So I think I’m going to really have to rewrite most of this script to work with my RHEL 5.5
Thanks this was helpful. Is there a similar trick to deleting files from Google drive?
Absolutely, read the docs here: https://developers.google.com/drive/v2/reference/files/delete
hi! what is $BOUNDARY? how should I specify it. I mean, is it just a random number or how does it effect the upload itself? Thank you for your time about my queries and I really appreciate it 🙂
Yes, Rizwan, it’s just a random, long-enough set of symbols that are highly unlikely to occur in the data itself. Read more about multi-part messages here: https://en.wikipedia.org/wiki/MIME#Multipart_messages
Hello,
I’ve been looking for such a script for a long time. Unfortunately when I tried to use it, I couldn’t. I don’t know how to create an API key from the link you provided because I don’t know which Development Platform I should choose.
I also tried your script, but it didn’t work. You have the output below:
Go to and enter to grant access to this application. Hit enter when done…
Access Token:
Refresh Token:
Do you have any suggestions?
Thank you
I managed to create the API key using your script (https://github.com/soulseekah/bash-utils/blob/master/google-oauth2/google-oauth2.sh) with the CLIENT_ID and CLIENT_SECRET generated from a “Native application”.
To get those, I went to “OAuth” > “Create new client ID”, I chose “Installed application”, then “Other”.
Glad you figured it out, Bogdan. I usually get API keys from the developer console at Google and pick the Server type keys.
Thanks for taking the time to put this together. I ran these scripts under a PHP wrapper, and cron which refreshes the token before it expires… can upload hundreds of thousands of files/day without any token issues… it’s so simple, and that’s what makes it so awesome!
Really appreciate your posting up your code.. it’s a great starting point to get a full app working.
Joe,
Can you (or anyone) explain how often to refresh this? I need it to upload 1 file each day as a backup, but I’m new to this and not sure how often to refresh the token.
Tokens are usually valid for a long long long time; we’re using tokens on a project that have been generated 2 years ago.
I may be completely missing something but I cannot seem to figure out what the [path] part of the argument should be, everything I try comes back with the following:
{
“error”: {
“errors”: [
{
“domain”: “global”,
“reason”: “notFound”,
“message”: “File not found: Work”
}
],
“code”: 404,
“message”: “File not found: Work”
}
}
I’m attempting to access the folder My Drive > Work, any help would be awesome.
All paths are actually IDs, you can get an ID from the URL when you’re in the drive. You can’t access them by directory name.
I couldn’t get this to work when leaving the [path] parameter empty. I got the “404 Not Found” error. To upload to the root folder of Google Drive it seems you need to specify “root”. For example:
./upload.sh $ACCESS_TOKEN foo.txt foo.txt root
You need to specify the path hash for the directory you’re uploading to, not sure if “root” works, it might.