Google Drive “Share” dialog not showing for "writer" - google-drive-api

We've incorporated Google Drive “Share” dialog into our web application which creates its own files, and it works perfectly thanks to the answer to another question, but only for document owner.
Even though "writers" can easily share documents from Google Drive, that seems to be not possible externally, i.e. in our app.
This is the code which works for "owners" but fails for "writers":
var s = new gapi.drive.share.ShareClient(appId);
s.setItemIds(fileId);
s.showSettingsDialog();
Curiously, the error in JS console is the same as one can see when the script is launched from a wrong URL:
Refused to display 'https://drive.google.com/share?id=0B....' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'
We haven't found anything related to possibility to share docs by various user roles in the documentation, so we wonder if that's a bug or undocumented restriction. Any ideas are welcome.
UPDATE
The issue seems to have gone - it looks like Google have changed something their end.

Your app should be checking the value of the writersCanShare attribute. If it's false, only owners can modify the file ACLs.

Related

Embedded Script (Tasks List API Sample) throws "'Tasks' is not defined" error (works when run in Scripts)

When attempting to embed Google’s sample provided for the Tasks API (code found here) into Google's Classic Sites I get the dreaded “script.google.com refused to connect”. The logging error is "Tasks" is not defined at getTasksLists(simpleTasks:15). Details:
When I embed this same script into Google's New Sites, the UI does show, but the drop-down continues to display “Loading…” (see screenshot below), however if I click on the link provided to view my “Google Tasks” it does go to my Tasks in a new window.
This runs successfully directly from Google Apps Scripts, showing the “Authorization required” pop-up and allowing me to sign in and accept permissions. However, when embedded into both New and Classic sites, it does not request any authorization.
Steps I've taken embedding into Classic Sites (where it needs to be):
from URL provided above: copied code exactly as is into a new Scripts project (nothing altered or added).
from Scripts: deployed it as a Web App, copied the URL provided (the code provided in the link above has not been altered in any way by me)
from Scripts: enabled Tasks API though Resources, Advanced Google Services
from Sites: edit page, Insert Apps Script, pasted URL (i.e. https//script.google.com/macros/s/...5Ym41qn/exec)
Other things I've tried:
from Sites: embedding URL as an iFrame gadget (same results)
solution given here: How to add Google Drive Scripts project into Google Sites? (same results)
days of research into Google's documentation (for Sites, APIs, Scripts, Cloud Platform, you name it)... (various results but nothing productive)
I am very new to working with Sites, Scripts, the Cloud Platform, etc. so apologies if I am missing some obvious steps here. Any guidance would be truly appreciated!
Leora
UPDATE [03-21-19]:
I was able to get this working finally! Although not posting as answer just yet as I haven't figured out the exact change that was brought success.
I thought it was by changing the option within Sites' Publish / Deploy as web app... / Execute the app as: from 'ME' to 'USER' (after doing that it worked), but when I changed it back to make sure that was it, it still worked?
I will play around with it more this weekend and update when I come to a definitive solution.
Thanks to anyone who took the time to help me out here, and if anyone does have any guidance on what's happening here, I'd love to know.

google drive ui integration - is it possible to open "google types"?

Some time ago I developed simple webapp and integrated it with Google Drive UI with option "Allow users to create new documents using this application". Now I'm trying to modify it for user to be able right click on any file in his google drive and open it with my app (I only need id of selected files). I thought I need to write list of all types in "secondary MIME types", but when I write any google built-in type, like "application/vnd.google-apps.document" when I'm saving changes I only got error "Sorry, there’s a problem. If you entered information, check it and try again. Otherwise, the problem might clear up on its own, so check back later."
Am I missing something obvious, like maybe it's not possible to use google built-in types?
It seems that it is a limitation on Drive API v3.
Folder mime type (application/vnd.google-apps.folder) is working fine, though.

Unable to serve download links in google apps script

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/.

Launching the Google Drive sharing dialog in an app. What should be the APP_ID value?

I'm following this article, trying to add a sharing dialog in a web app.
I got the button working in opening the modal popup, but it just prints this error in the console:
Refused to display 'https://drive.google.com/share?id=SOME_LONG_ID&foreignService=explorer&shareService=explorer&shareProtocolVersion=2&command=init&subapp=10&popupWindowsEnabled=true&shareUiType=default&rand=1386925457304&theme=2&client=postMessage&appId=MY_APP_ID&embedOrigin=http%3A%2F%2Fmy_app.appspot.com'
in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'.
And the modal itself just shows the message "Sorry, sharing is unavailable at this time. Please try again later."
For the checklist at the bottom of the article:
The user is signed in to Google True
The user has installed your app False How do I ask them to install?
The URL of the page that launches the dialog must have the same origin as the Open URL registered for the app. True
So I have 2 questions:
How do I ask them to install my app? It's supposed to be a web app, where there's 1 button to select Drive files via the Picker API (which is now working), and then another button which will sow this Drive sharing dialog to set the permissions of the selected files. There's no need for installation. Will it work for this setup?
What should be the value for the APP_ID? I'm guessing it's the ID in the "Drive SDK" section of the Cloud Console? The console is so confusing and there's so many values for keys, ids, etc. that I have no idea which to use. Here's a screenshot of what I mean by the ID and what I'm trying to use.
(1) Installing means you have to get the user to accept the drive.install scope - instructions here. This will integrate your app with the "open with" menu in Google Drive. But before that can work you will need to tell the Google Cloud Console what url to go to when the user clicks "open" - more instructions. In your case, since you don't actually want to allow the user to open files from Drive you won't be defining any file types, so in reality there won't actually be any visible integration with Drive.
Note that the share dialog will only work on the one page which has the url you specify as the target for "open" (the instructions say this and from experience it seems to be true).
(2) Client ID You can find this in the Google Cloud Console - see above. Mine is a 12 digit number, so yours will probably be too.
I had the same problem. The iFrame error shows up when you call setItemIds if your app_id is wrong. No idea why. Anyway, it started working for me when I used the right app_id -- the one that shows up like in your screenshot.

How to make a copy of a file between users of different domains?

I would like to make a copy of a Google Spreadsheet file between users that are not on the same domain. The source file has a sharing setting of Anyone with the link can edit.
I created a Web App (with execution permissions set to User accessing the web app) that call an install function:
I was hoping the code would read the source file which is open to everybody and make a local copy to the Google Drive of the user running the Web App (of course assuming the user accept to run the script). The behavior works when it's me running it (because I am the owner of the source) but do not work if the user is from another domain.
Any suggestions on how to achieve this?
function doInstall() {
// The source file is readable by everybody with the link;
var file = DocsList.getFileById('0AlVPTKz1xoevdHc1ZTQ2OGFMXXXXXXXYYYYZZZZ');
file.makeCopy('Test Copy Spreadsheet');
}
I had a different but similar use case and problem. Like you, my source file was accessible to anyone with the link and my domain settings allowed users to share content outside my domain. It worked for me but not for them.
This might work for you, it has for me (so far):
Assuming you have your original script...
Create a separate script for 'Script as web app'.
Write a function (e.g. loadFileIds()) to store the necessary fileIds using ScriptDb. Run the loadFileIds() function.
Write another function (e.g. getFileId()) in the same project that returns your desired file Id from ScriptDb.getMyDb when called. Avoid using DocsList in this function. I originally thought that because getFileId() would 'run as me' that it would be OK but it was always the DocsList line that caused failures when other users triggered the script.
In File > Manage Versions: Save a version of the project.
Under Publish: Deploy that version of your project as a web app. Choose Execute the app as "me(me#mydomain.com)" and set Who has access to the web app to "Anyone".
In your original project go to Manage Resources and enter the Project Key of the web app, choose a version and copy the identifier.
Write a function that calls yourIdentifier.getFileId() and - hopefully - returns the fileId.
In my experience so far external users have been able to access files that they could not when DocsList methods returned null. But there is one more thing to add... You might find you have to share your web app script with your users. I haven't quite made certain that's necessary but I've encountered bugs when I don't. I untick the option to email them the link.
I learned how to do this from examples in the documentation, this video and of course StackOverflow.
As you can see, I'm still working this out myself and testing of the system has so far been just me simulating other users. So no promises. Good luck! I'll star your issue.