My app requests the 'https://www.googleapis.com/auth/drive.readonly' permission from a user. When the app gets a Google access token, a url is built to access a user selected Google Slides presentation preview, something like:
https://docs.google.com/presentation/d/1WADAfZShdqdYKgae8C9LdpYlPgf2qjoZD2jjKln4F3M/embed?rm=minimal&access_token=ya29.....
This works great to view the presentation, but if a video is used on a slide, then follow error shows:
Since my app is requesting full read access to a user's Google Drive, and the video in question is in the user's Google Drive, why is this happening?
This is happening because you still have to let other users have access to your video itself, therefore you need to share it to them like you would do it with any other kind of file inside your Drive.
To do it programmatically, you will need to use the Drive API and build a request in the Files: update enpoint like this:
[
{
'type': 'user',
'role': 'writer',
'emailAddress': 'user#example.com'
}, {
'type': 'domain',
'role': 'writer',
'domain': 'example.com'
}
]
Edit
For what I could understand now. To be able to see the video, do the following:
1) Right-click on the video.
2) Click Share.
3) Click "Advanced" (It is in the right-bottom corner).
4) Click "Change...".
5) Choose "On -Anyone with the link" and set the access as "Can Edit".
When you use the "access_token" query parameter Google Slide is going to search for the video's URL in the Driver, which you have to set shareable permissions to the video.
Images can be accessible from anyone who has access to the presentation as the doc says:
An URL to an image with a default lifetime of 30 minutes. This URL is
tagged with the account of the requester. Anyone with the URL
effectively accesses the image as the original requester. Access to
the image may be lost if the presentation's sharing settings change.
Videos have to have the sharing settings configure as the doc says:
An URL to a video. The URL is valid as long as the source video exists
and sharing settings do not change.
Notice the difference between the two here: Anyone with the URL effectively accesses the image as the original requester.
Update
I am updating my answer because I came across this, which states authorizing your requests through the access token query parameter to connect to the Drive API will be deprecated starting January 1, 2020.
Therefore your requests now will need to be made using an HTTP header.
My answer should be considered a workaround because it will be deprecated soon.
Docs
You can find more info about the Slides API and Drive API in the following links:
Drive API v3.
Share files, folders and drives.
Slides API.
Pages, Page Elements, and Properties.
Although you have stored your video in the same drive location alongside your presentation, I guess it might not be accessiable when it is "embedded within your slides".
However, you would be able to access the video if you use the same access token to see the video alone.
It would be better to store videos separately, embedded them in your presentation and then access them using their respective scopes instead.
if you choose to take this route then,
I think you need to allow the following scopes as well to access your video from the presentation viz drive.photos.readonly, youtube.force-ssl respectively. Alongside your other drive scopes, provided you have stored videos in either of the 2 ways mentioned below.
Hence, at the time of access_token request, use the relevant scopes and get the access token and use the same for accessing your resources at a later point in time.
2 options,
When using Drive API
https://www.googleapis.com/auth/drive.photos.readonly
View the photos, videos and albums in your Google Photos
When using Youtube
https://www.googleapis.com/auth/youtube.force-ssl
See, edit, and permanently delete your YouTube videos, ratings, comments and captions
Google API documentation -
https://developers.google.com/identity/protocols/googlescopes
Related
I'm writting Web application to display content of Google Drive images and files, using API.
Currently, I can only see thumbnails of images/files (without login to Google drive).
If I want to preview the file, I need to be logged into Google drive and then I can use link returned by "webViewLink" and actually see the file.
I know I can click on folder or file on Drive and Share it, but I'm afraid that my customers will not be able to do that and it is complicated, anyway.
I already displaying Google dialog to customer where customer need to allow access to upload,delete etc. of files and now he can not preview the file???
Application is designed to display image/whatever to customer only, inside app only and not to sharing. With other words, I want to display images which he can see anyway if he is logged to Drive.
Is there any other option to allow customer to preview the file, if he already allowed full access previously?
Thanks.
Authorizing with OAuth does not automatically log you in. Users use their credentials to give their permission to create an access token, which needs to be used in any API calls. It does not imply that a browser session was created, that's a separate process.
You'll notice that the webViewLink is just the regular Drive URL with /view at the end. It's a page that requires the user to be signed in:
"webViewLink": "https://drive.google.com/file/d/<FILE-ID>/view?usp=drivesdk",
I'm not aware of any methods to sign in the user at the same time they use OAuth, but if you send your access_token in an Authorization: Bearer <access_token> header when trying to access the above URL you can see the preview without having to sign in. Depending on your platform I think implementing this would be tricky, and maybe not possible in Apps Script alone.
My recommendation as a workaround is to just use a full thumbnail. Don't know if you're aware of this, but the thumbnail URL has a =s parameter at the end that defines its height in pixels:
"thumbnailLink": "https://lh5.googleusercontent.com/<THUMB-ID>=s220",
You can change the default =s220 at the end to a higher size or remove it completely to get pretty much the full size of the image or PDF page. This may be enough for your users to figure out what the file is.
I want to add Google Drive integration to a browser add-on I developed. Basically I want to share user settings between devices, and the settings files are too big to fit inside the 100KB limit for the storage.sync API.
But when I go to my API console and try and activate permissions for the Drive API, I get this:
Browser apps (and Android apps) aren't allowed to access app data. That's not just a warning, you actually can't continue the process until you choose a different platform. Weirdly, I can go ahead if I select "User data" (so user data is less sensitive than app data??)
What I like about app data over user data is that, if I understand correctly, app data goes in a hidden folder uniquely tied to your app, whereas user data goes in the actual user's drive. I don't want my app to have access to the broader drive, I don't want to risk messing their data up and I don't want them to see my app's config files every time they access their drive.
How can I get this "hidden folder" behavior from a browser addon?
Try the solution from this related SO post.
To be able to use your Application Data folder, request access to the following scope:
https://www.googleapis.com/auth/drive.appdata
UPDATE: I have found a solution. This doesn't necessarily address every case, so I will leave the question open for a short time in case someone can enlighten me more. I solved it by changing the format of the url: Google Drive allows this format for downloading files:
https://docs.google.com/uc?export=download&id=FILE_ID
So I don't know if this is a problem for other URL's; nor actually exactly why the .getDownloadUrl() doesn't work ... maybe someone can explain. But for now this seems to work in the browsers that I can test ...
I have a simple WebApp script which I run on a Google Site by adding the Apps Script gadget. The gadget runs exactly as the Forms example on:
https://developers.google.com/apps-script/guides/html/communication#forms
The gadget is designed to do the following: when the page is loaded, a form is returned, and the user must enter a license key to get a link to download a product. My code serves the form OK, and gets the form submit OK; and it then validates the key, and if valid, sends back a link to download. All that works fine; and the problem is that no matter what I try to return for the download link, the caja iframe wrapper is preventing the click on the link from actually downloading the file.
My preferred URL to return is in fact via the Drive API: the download file is on the Google Drive, and I get the download link like so:
DriveApp.getFileById(downloadFileId).getDownloadUrl()
But when the returned link is clicked inside that caja iframe generated for the WebApp gadget, nothing happens. I have tried a few other URL formats pointing to that file on the Drive, but nothing is working for a download.
Is this possible?
.getDownloadUrl() method returns a temporary URL that can be used to download the file. This URL is valid only for a short period of time, after which it expires and does not return the file any more - that is probably why the links in your web app do not work. Can't remember exactly how long the URL is valid for, but I think it could be as short as 5 minutes.
Permanent download URL is stored in another file property: webContentLink. However, this property is not (yet) available through Google Apps Drive Service - you must use Advanced Drive Service to access it. You can enable Drive API under Advanced Google services in your script. After it is enabled, you can use it like so:
var file = Drive.Files.get(FILE_ID_HERE);
var dlUrl = file.webContentLink;
This will return the link just like the one you found and posted in your update. An advantage of using the Drive API to get the link, instead of hard-coding it, is that if Google ever changes the format of that URL, your code using Drive API to get the link will continue to work, while hard-coded links will not.
Full Drive Web API reference (what Advanced Drive Service uses) is at https://developers.google.com/drive/v2/reference/.
I have a website that has a web page with a html5 video-tag, and the user can supply a URL, and it will play in the video-tag.
The webpage uses JavaScript commands that control the video-tag - for instance, it can pause the video, move to a different point in the video, etc.
It works fine with the cloud. Videos stored on Microsoft Azure can be used, for instance (Azure gives you a way to get a URL to any video on your cloud storage, and streams it too).
However, I have users that store videos on Google-drive, and also on Microsoft One-Drive.
From what I can see, I can play these videos, but only in a page (probably with Google's own player in it) on their site.
It seems that there is no way to get a URL to these videos that I can put in a video tag.
Without the ability to do that, I can't use the javascript commands that work with the html5 video-tag.
Is there any workaround?
Or am I missing something?
Thanks.
For playing videos that are stored in google-drive using your app:
you need oauth2 credentials to access the user's drive, but assuming you have the oauth part covered :
you can create a drive application as a google appengine app and deploy it in a part of your website.
enable the drive-sdk and set the open-url to your website (that you have verified)
-> basically this tells drive to redirect towards your website whenever the user clicks on the video (from his drive)
when drive redirects to your website a json file will be sent, you'll have informations such as fileId from there i think you can execute the method files().get() to retrieve the necessary information for you to play the video
I advise you to take a look at this course in codeschool.
I'm looking for some clarification on accessing Google docs/Drive SDK via a Service Account.
I have everything set up in the API Console and I can successfully generate an access token via the JWT process and indeed I can issue requests to either drive SDK or the Docs List API to get a listing of documents. However, the document listing is always empty, I was expecting to see all the documents in my Google Drive. I am obviously not understanding fully what a service account gives you. If I upload a document via the Service Account then it does show up correctly, but is not visible in my Google Drive, it's as if the Service Account is a totally separate black box.
The reason I want to use Service Accounts is that I have a service running that needs to upload documents to various clients Google Docs accounts, without them having to go through the OAuth dance as there will be no UI interaction at all. Is this possible with Google docs. I was hoping that they could just send my the client_email and the certificate with the private key and I would be able to upload documents to that account.
Many thanks for your consideration
-Marshall
Not sure whether you need the answer anymore, but I just faced with the same issue, came to this post. Found one solution which works in my case, so sharing with everyone here.
The only integration point towards GoogleDrive in my case is document listing.
When I first created my service account, it didn't work as well (just empty list all the time).
What did I do to fix it:
Go to MyDrive UI https://drive.google.com/#my-drive
Checked all the documents I want to see on my website
In the top menu clicked "More"->"Share..."->"Share..."
In "Add people" section (new window "Sharing settings (N items)") I added service account email (format is "XXXXXX##developer.gserviceaccount.com")
Run document listing once again and got it working.