Google Drive API downloadUrl does not work - google-drive-api

I have some audio recordings on Google Drive
the files are "viewable by anyone with the link"
I have created a podcast feed that links to these files
In order for a podcast client to download the files, it needs a direct download link. The Google Drive API returns two fields in a file's metadata that can play this role:
webContentLink is intended to be used in a browser. It allows my podcast client to download files less than 25MB; unfortunately, over this amount Google requires user confirmation since the file is not virus-scanned. This user-confirmation step prevents my podcast clients from downloading the file if it is over 25MB.
downloadUrl is what you're supposed to use, but I cannot get it to work at all. If I copy-paste a downloadUrl directly into my browser's address bar, I get nothing. Similarly my podcast client can't download anything with a downloadUrl.
This issue seems unresolved and suggests this is still broken, but I have a few questions:
should I need to submit an API key with the downloadUrl request? No key is needed for webContentLink.
is there a workaround for this issue?

When requesting the file with the downloadUrl you must specify the following authorization in your request header:
"Authorization: Bearer $token"
Where $token is the access_token returned by gapi for the user like this:
gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse().access_token;
So if you were using curl the request would be something like this:
curl -o download -H "Authorization: Bearer $token" $downloadUrl

Related

Google Drive API failing - Unusual traffic from your computer network

The Google Drive API GET query started to fail (we are using this api in one of our client service):
https://www.googleapis.com/drive/v3/files/1ke4Yoxxxxxxxxxxxxxx?alt=media&access_token=ya29.ImG9BwT.....
We're sorry...
... but your computer or network may be sending automated queries. To protect our users, we can't process your request right now.
See Google Help for more information...
"Unusual traffic from your computer network"
Everything was ok till today.
Just made a couple of tests with curl:
HTTP GET with access_token inside HTTP header:
curl -H "Authorization: Bearer ya29._valid_access_token" https://www.googleapis.com/drive/v3/files/1r5BT2WPrulQ6FyhT8RcqV51TVOThEmhK?alt=media
Result: success, file downloaded.
HTTP GET with access_token as a part of HTTP request:
curl https://www.googleapis.com/drive/v3/files/1r5BT2WPrulQ6FyhT8RcqV51TVOThEmhK?alt=media&access_token=ya29._valid_access_token
Result: error
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
Note that the Google API project approved by Google and has a Production state!!!
Hi Google team, any ideas why it is happening?
Thank you
Posting this just for documentation purposes. As per the reference provided by Tanaike, since January 1, 2020:
download calls to files.get, revisions.get and files.export endpoints which authenticate using the access token in the query parameter will no longer be supported.
Only requests that download media content (alt=media) are affected by this change.
The access token should be provided in the HTTP header, like Authorization: Bearer oauth2-token or, if that's not possible, follow the workarounds provided in the referenced documentation:
For file downloads, redirect to the webContentLink which will instruct the browser to download the content. If the application wants to display the file to the user, they can simply redirect to the alternateLink in v2 or webViewLink in v3.
For file exports, redirect to the export link in exportLinks with the desired mime type which will instruct the browser to download the content.
Reference:
Changes in authorization to Google Drive API
Authorization via HTTP header
Posting an addition to the documentation of iamblichus specific for application data in Google Drive.
My App uses the Google Drive API in the backend to store the documents of my users on their own Drive. Importantly, I store the data in an application data folder such that the users can't accidently delete the data.
To let the users retreive their documents I used to redirected the user to the
downloadUrl: https://www.googleapis.com/drive/v2/files/id?alt=media&source=downloadUrl&access_token=ya29.** where I added alt=media and access_token to the query. This worked fine till January 1, 2020. As confirmed above. However, now the request fails with the message:
We're sorry... ... but your computer or network may be sending
automated queries. To protect our users, we can't process your request
right now.
GET request downloadUrl failing
In my efforts to find a solution to this problem I've tried the workarrounds provided by Google but they are in my experience not working for documents in an application data folder.
I tried the webContentLink with the access_token query in v2 but it fails with an 401 Unauthorized error.
The alternateLink in v2 and the webViewLink in v3 fail with the error:
The desired file does not exist.
I can't use the exportLinks because that's only for Google Documents.
The solution I found was to first download the file to the server using the Google Drive PHP SDK and then serve it to my users using a Content-Dispostion header. Such as described here. It is a lot less elegant in my opinion because the end users doesn't download the document directly from the Google Drive API but it works.
It's a shame that Google didn't update their documentation nor notified their users..

Access Google Drive REST without google sdk

I have a lightweight node.js module that needs to pull from google drive. They have a REST/HTTPS interface but AFAICT it's only accessible via their SDK. I want to use REST/HTTPS so I don't have to use an SDK. Is this possible for file download? For file find (file:list e.g. https://developers.google.com/drive/v3/reference/files/list)?
I don't understand why you think it's only accessible using an SDK. The link you posted clearly shows the URL endpoint, lists the optional parameters and gives the format of the JSON response.
If you click "Try it now" and open your browser console, you will see the http request and response which you can mirror in your app.
The only thing you also need to consider is that before making a REST request to Google, you must obtain an Access Token and set it in an Authorization: Bearer xxxxxxxx header, or provide it as a query parameter as &access_token=xxxxxxxxx

Box API get shared file results in 404

Already looked at How to use box-api to get the Shared item? and Box Developers documentation https://developers.box.com/docs/#shared-items. I have tried doing a request to https://api.box.com/2.0/shared_items in .NET code, in Firefox Poster and using curl. They all resulted in 404. I have verified that my file's shared link is open to anyone with a link. Here's my curl code (sanitized):
curl https://api.box.com/2.0/shared_items -H "Authorization: Bo
xAuth api_key=xxxxxxxxxxxxxxxxxxxxx" -H "BoxApi: shared_link=https://
app.box.com/s/yyyyyyyyyyyyyyyyyyyyyyyyyyyy"
{"type":"error","status":404,"code":"not_found","help_url":"http:\/\/developers.
box.com\/docs\/#errors","message":"Not Found","request_id":"196207167555469c3017
14b"}
What might be the problem? I tried a wrong api_key and got back 401 so I know the whole setup is correct.
Your API key shouldn't be included anywhere in the request. I believe that form of authorization was used in the old v1 API and is now deprecated. There's a cURL example in the docs you linked to that shows what your authorization header should look like:
curl https://api.box.com/2.0/shared_items
-H "Authorization: Bearer ACCESS_CODE"
-H "BoxApi: shared_link=SHARED_LINK"
For more info on how to obtain the access token that goes into the authorization header, take a look at the OAuth tutorial.
The reason why authentication is required is because the API will return info about the item within the context of the caller's permissions. For example, if the creator of the shared link makes the API call, then private information (such as the item's full path within their account) will be returned. If another user makes the call, then that private information will be omitted.
That being said, you're still able to anonymously download an open shared link by navigating to it directly. You only need to use the API if you want more information about the item that the link points to.

Future of Google Location History API

Google will be retiring Latitude soon, along with Latitude's API. But they say on their blog that Location History will still be stored and users will be able to access their history on Google Maps' Location History Dashboard. Do you know if there will be any API for receiving that location history, as there was for Google Latitude?
I've discovered that I can dynamically load my location history for any date using the following url:
https://maps.google.com/locationhistory/b/0/kml?startTime=1373666400000&endTime=1373752800000
by changing timestamps in "startTime" and "endTime" parameters. Unfortunately it's in .kml and no granularity data is included. Come on, Google - Latitude has some devoted users who relay on it on daily basis, don't kill it :(
In case you want the data as JSON with accuracy and not just the locations, you can just make the same request that the website makes. Looking at the inspector shows that it makes a request to https://maps.google.com/locationhistory/b/0/apps/pvjson?t=0. You can replay the same request with cURL (or any other way to make a POST request).
curl 'https://maps.google.com/locationhistory/b/0/apps/pvjson?t=0' -H 'origin: https://maps.google.com' -H 'accept-encoding: gzip,deflate,sdch' -H 'x-manualheader: [SOME STRING]' -H 'accept-language: en-GB,en;q=0.8,en-US;q=0.6,de;q=0.4,pt;q=0.2' -H 'cookie: GDSESS=[COOKIE DATA]' -H 'x-client-data: [ANOTHER STRING]' -H 'user-agent: [UA STRING]' -H 'content-type: application/x-www-form-urlencoded;charset=UTF-8' -H 'accept: */*' -H 'cache-control: max-age=0' -H 'referer: https://maps.google.com/locationhistory/b/0' -H 'dnt: 1' --data '[null,[BEGIN],[END],true]' --compressed
I left out my private cookie data and some details (in [..]) but you can google chrome ask to generate this for you in the developer console (right click on request -> copy as cURL). Just adapt the begin adn end times and download your location history as JSON. However, you need to download ranges of a couple of days and not everything at once. I'll leave this as an exercise for the reader.
I too am searching for an alternative solution to get my location back from Google.
Here are some facts:
Latitude will be replaced with location sharing on Google+
Android devices will continue to report location data to Google
Latitude will be removed (API, friends, website ...)
If devices will still be sending location data, Google should give us an API to fetch that data.
I've been looking into it and my location is shown on my G+ profile, but no info about granularity or timestamp.
It just says "Current location: [geocoded city]".
Reverse geocoding that address isn't very accurate. If I click on the address, Google Maps is opened in a new tab with coordinates, which seem to be pretty accurate.
So, if my location is on G+, I should be able to get it via the G+ API, right?
Well..
The only thing I've been able to find was this:
https://developers.google.com/+/api/latest/people
"currentLocation": string,
As you can see, the location data is returned as a string. I haven't tried it yet, but I would bet money that it would return the same as on my profile, just the name of the city, but not more accurate than that.
Right now it sucks. I want to get my location info, if the device is already sending it.
Installing a 3rd party app on my phone to feed my location on another service is redundant. And let's not forget about the additional battery drain and mobile data usage.
The logical step would be to put all of the latitude functionality to Google+.
We'll see, I doubt it.
Right now it just seems that they will be feeding on our privacy without us having any control or insight into it. :(
You can also download the data from Google Takeout. I know that this isn't an API, per se, but even a manual import is probably better than nothing.
https://google.com/takeout/

GET/POST requests Google Drive API

I learning currently Google Drive API and developing program in Qt C + + (using OAuth2), so I need to build queries, but I'm not found how to do it.
For example, if I make a request - https://www.googleapis.com/oauth2/v1/userinfo?access_token=MY_ACCESS_TOKEN, everything is working OK - I get the reply.
Question is: how to make a SIMILAR request for the Google Drive?
1) how can I get a list of folders and files
2) how can I create a folder / file
etc.
For example, in a POST request
"https://www.googleapis.com/drive/v1/files&title=pets&mimeType=application/vnd.google-apps.folder"
I get
"error": {
"errors": [{
"domain": "global",
"reason": "parseError",
"message": "Parse Error"
}
],
"code": 400,
"message": "Parse Error"
}
}
how to get a list of folders and files, for example, etc., I do not understand
Any opinions/examples are welcome!
thanks in advance
Unfortunately, the Drive API doesn't let you list folders or files. The only way to retrieve a file is by integrating with the Drive web UI or showing a Google Picker to your user (web app only).
Once you have a File ID, you can simply send an authorized GET request to the drive.files.get endpoint:
GET https://www.googleapis.com/drive/v1/files/id
To insert a file (or a folder), the File's metadata is to be included in the request body, not as query parameter:
POST https://www.googleapis.com/drive/v1/files
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
...
{
"title": "pets",
"parentsCollection": [{"id":"0ADK06pfg"}]
"mimeType": "application/vnd.google-apps.folder"
}
In the example above, the mimeType specifies that the resource being inserted is a folder. Change the mimeType to your application MIME type when inserting a file.
You should use google docs API for that
Retrieving a list of collections - Google Documents List API version 3.0
In OAuth 2.0 Playground just select both Documents List and Google Drive
And you will get full list of operations:
List FolderContent
GET https://docs.google.com/feeds/default/private/full/{folderResouceId}/contents
Don't forget to add the ?v=3 query parameter to the Document list URI or adding
GData-Version: 3.0
header, otherwise it will return "Invalid request URI".
You advise you to look at the google drive api reference docs in
https://developers.google.com/drive/v3/reference/files/list
i succeeded using many api functions following link above and using curl. But actually i recommend you trying to do http requests with a tool like postman. Anyway after getting access code following the steps link below
list google drive files with curl
try to make following command in the command line.
curl -H 'GData-Version: 3.0' -H "Authorization: Bearer $ACCESS_TOKEN" \
https://www.googleapis.com/drive/v2/files?maxResults=$100