12

I am trying to upload a zip file to Google drive account using curl.

The file is uploaded successfully but the filename is not getting updated. It gets uploaded with default filename i.e. "Untitled".

I am using below command.

curl -k -H "Authorization: Bearer cat /tmp/token.txt" -F "metadata={name : 'backup.zip'} --data-binary "@backup.zip" https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart
Tanaike
  • 181,128
  • 11
  • 97
  • 165
Saran Brar
  • 147
  • 1
  • 1
  • 8
  • Do you need to do it using just curl? If don't, you can use 'gdrive' command (http://olivermarshall.net/how-to-upload-a-file-to-google-drive-from-the-command-line/) – Igor Uchôa Aug 25 '17 at 11:57
  • I am running this on router which doesn't have space to install gdrive. Thus made my custom script to do this – Saran Brar Aug 25 '17 at 16:44
  • Take a look on this comment of this forum: https://gist.github.com/deanet/3427090#gistcomment-1253229. Maybe you need to set some variables according with this post. – Igor Uchôa Aug 25 '17 at 20:36
  • 1
    Thanks for your reply but I tried this and looks like Google Drive has changed the way it handles uploads from command line. Post you have mentioned is very old created 5 years ago. – Saran Brar Aug 25 '17 at 21:05

2 Answers2

28

You can use Drive API v3 to upload the zip file. The modified curl code is as follows.

curl -X POST -L \
    -H "Authorization: Bearer `cat /tmp/token.txt`" \
    -F "metadata={name : 'backup.zip'};type=application/json;charset=UTF-8" \
    -F "file=@backup.zip;type=application/zip" \
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"

In order to use this, please include https://www.googleapis.com/auth/drive in the scope.

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • Thanks a Ton Tanaike!!! You Rock.. and by the way V2 also worked with the same code – Saran Brar Aug 26 '17 at 03:09
  • @nbuser Welcome. Thank you, too. – Tanaike Aug 26 '17 at 08:27
  • can you please comment on how to upload file in a specific folder with same above code. Thank you. – Saran Brar Aug 26 '17 at 08:43
  • @nbuser Please include ``parents: ['### folder id ###']`` to ``metadata``. – Tanaike Aug 26 '17 at 08:59
  • Thanks for so quick reply. Solved problem by adding below code parents : [{kind:'drive#parentReference',id:'folderid'}]} – Saran Brar Aug 26 '17 at 11:05
  • It works, thanks. I did not have to specify the content-type of the payload though, e.g `curl -v -H 'Authorization: Bearer tokenGoesHere' -F 'metadata={"name": "test2.jpeg"};type=application/json' -F file=@example.jpg 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart'` It is detected automatically – zakaria amine Jan 16 '19 at 14:34
  • @Tanaike I get a 401. Is Bearer the same as `api key` that we create in the google developer console? – Ashwin Sep 13 '19 at 04:19
  • @Ashwin The access token is different from API key. – Tanaike Sep 13 '19 at 05:08
16

The answer above works fine and was the command I used in uploading my file to Google Drive using Curl. However, I didn't understand what scope was and all of the initial setup required to make this command work. Hence, for documentation purposes. I'll give a second answer.

Valid as at the time of writing...

Visit the Credentials page and create a new credential (this is assuming you have created a project). I created credentials for TVs and Limited devices, so the work flow was similar to:

Create credentials > OAuth client ID > Application Type > TVs and Limited Input devices > Named the client > Clicked Create.

After doing this, I was able to copy the Client ID and Client Secret when viewing the newly created credential.

NB: Only the variables with double asterisk from the Curl commands should be replaced.

Next step was to run the Curl command:

curl -d "client_id=**client_id**&scope=**scope**" https://oauth2.googleapis.com/device/code

Scope in this situation can be considered to be the kind of access you intend to have with the credential having the inputted client_id. More about scope from the docs For the use case in focus, which is to upload files, the scope chosen was https://www.googleapis.com/auth/drive.file.

On running the curl command above, you'll get a response similar to:

{ "device_code": "XXXXXXXXXXXXX", "user_code": "ABCD-EFGH",
"expires_in": 1800, "interval": 5, "verification_url": "https://www.google.com/device" }

Next step is to visit the verification_url in the response in your browser, provide the user_code and accept requests for permissions. You will be presented with a code when all prompts have been followed, this code wasn't required for the remaining steps (but there may be some reasons to use it for other use cases).

Next step is to use the Curl command:

curl -d client_id=**client_id** -d client_secret=**client_secret** -d device_code=**device_code** -d grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code https://accounts.google.com/o/oauth2/token

You will get a response similar to:

{ "access_token": "XXXXXXXXX", "expires_in": 3599,
"refresh_token": "XXXXXXXXX", "scope": "https://www.googleapis.com/auth/drive.file", "token_type": "Bearer" }

Now you can use the access token and follow the accepted answer with a Curl command similar to:

curl -X POST -L \
    -H "Authorization: Bearer **access_token**" \
    -F "metadata={name : 'backup.zip'};type=application/json;charset=UTF-8" \
    -F "file=@backup.zip;type=application/zip" \
    "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
HAKS
  • 419
  • 4
  • 9
  • 1
    thank you for the detailed, step-by-step answer. for all those dumb smart people like me, this is a life-saver! – liltitus27 Sep 08 '20 at 13:04
  • clientid/secret for TVs and Limited devices are just for that type of clients. Curl to https://oauth2.googleapis.com/device/code returns: invalid_client Only clients of type \u0026#39;TVs and Limited Input devices\u0026#39; can use the OAuth 2.0 flow for TV and Limited-Input Device Applications. Please create and use an appropriate client. – JRichardsz Jan 24 '22 at 01:16