Google Drive for hosting JSON post 'host' discontinuation (August 2016) - json

While it appears that we will still be able to use google drive to host images for websites (when load speed is less of an issue than users being able to add things when they do not know any html). I have been using google apps scripts to generate JSON files that are then loaded to build webpages (This way I could have people add images to a folder, and lines on a spreadsheet and the page builds automatically). I noticed a couple of other people asking questions about this, so it is not only going to effect me. However with Google ending their 'host' feature in August, has anyone come up with a solution other than just make a small server that grabs the JSON file occasionally and hosts it in a way that allows cross domain access?

Well I found a work around inside google apps script for anyone interested. There is one large problem with it. It does not work on any safari browsers due to a known, but triaged bug. (https://code.google.com/p/google-apps-script-issues/issues/detail?id=3226) This is something I should have thought of before, as I have used it as a trick in the past:
function doGet() {
var myFile = DriveApp.getFileById('<FILE_ID>');
var str = myFile.getBlob().getDataAsString();
return ContentService.createTextOutput(str).setMimeType(ContentService.MimeType.JSON);
}
Once you have your id set up go to Publish->Deploy as Web App, set things to Execute as me, and anyone even anonymous can access. The URL https://script.google.com/macros/s//exec will allow cross domain grabs at this point.
This, I believe, will have a quota that could in theory be overwhelmed, but you can always choose to pay for more access. In my case I will just add direct access to the JSON generated by the original script so I will not hit google drive quotas, but this should work fine for any reasonably small project that does not need Safari access...

Related

Limiting downloading, copying and printing for EDITORS in Google drive

I am looking to find out if it is POSSIBLE to restrict EDITORS from downloading, copying or printing a Google sheet or other documents in a Google Drive. We share sheets/documents with our customers so they can fill in the details. For that we need to make them EDITORS (so they can edit and even invite others to the party). I know that we can restrict COMMENTERS and VIEWERS from downloading, but in our case we need to prevent EDITORS.
We have a LOT of intellectual property in our sheets (custom formulas and approaches), and we would like to be able to prevent people from simply downloading it. As I understand it this SHOULD be possible using the Google Drive API, but I have not been able to figure out how to do it, yet. Looking at the API it obliquely says it MAY be possible, but it is not clear :-(
Direction, or sample code, would be VERY much appreciated.
TIA
It's not possible to restrict editors from downloading files. The documentation mentions that only commenters and viewers can be prevented from this. Then in the API docs concerning permissions and their definitions you will see that there's nothing controlling downloads either. This is just a UI change.
If you think about it, the reason is clear: Even if you manage to stop direct downloads, to anyone with at least read access to the file or API this is just a minor inconvenience. They can still read all the content and metadata from the API and replicate the file perfectly. Even viewers with copy disabled can still read the formulas from the formula bar. Sharing the Sheets file is inherently unsafe if you have confidential data in it, since a determined attacker can still get all your trade secrets easily. You're only supposed to share these files with trusted users.
My suggestion is to take a different approach. Do not share the Sheets file at all and use something else as intermediary to request data from your customers. For example:
Create a Google Form to save the responses to a Sheet. Your customers will only need to fill out the form and the sheet will be filled with data that you can handle on your side.
If you need the users to also view some information in the Sheet before filling out their info you can build an Apps Script Web App that displays only the plain data that you need to show them. With this you can hide the formulas and other sensitive information. Using templates and server functions you can allow the users to interface with the Sheet data similarly to how they do it now, but with a more restricted view. You could even allow them to edit only the data you want them to. This requires more work and is starting to delve into web development, but It's much easier than a fully fledged website since the hosting and interfacing with APIs is handled by Apps Script.
You could just create your own application and use the Sheets API to read and write data from the Sheet. This is pretty much the previous suggestion but much harder, though in the end it will give you more flexibility.
The bottom line is that sharing your Sheet in any way is akin to giving your users full database read or write access, and there's no single setting that can prevent that. Your best bet is to avoid sharing these files and use a different method to request user data.

Google apps script cannot get url parameter from page on new Google site

My current site (Golf League) uses several scripts to allow players to schedule whether they are playing, display various results pages etc. It seems as though the New Google Sites implementation does not allow a parameter to be passed in the page url and get picked up by an embedded Google Web App (published from my script)
This link shows an example https://sites.google.com/site/kitchenergaffers/home/general-gaffers-information/publish/directory-of-results?display=directory
There is my webapp (built from a GAS) that does a doGet(e). The "display" parameter tells this script which page to format and display which it gets by extracting the e.queryString. I use a similar approach for players scheduling their absences. Another url parameter identifies the player who may be changing their availability.
It seems as though this ability is not going to be supported in the New Google Sites, so I am looking for an alternative (and free) web building facility where I can launch GAS web apps and access the page url parameters the same (or similar) way. Wordpress, Wix etc may be candidates, but it is difficult to tell from their introductory info whether it can be done. If someone has already found a site facility and methodology I would appreciate the guidance.
Just in case anyone finds this in a search, I have found a workaround.
What I had missed is that a script can be the target of a URL and will execute in a browser on its own. It does not need a "hosting" page. So to achieve what I need to do, instead of sending the link with the Google sites page, I can send a link with the script directly and it will happily execute in its own browser environment. In some cases, I may need to add a bit of text to the html returned by the script to replace that which was on the Sites page
So this link (below) achieves what I needed. Be aware that the links displayed by the script, are currently still to the original sites page.
https://script.google.com/macros/s/AKfycbxichdoGrHbImuudkJbuhhD00GpHvVvc-Ph_BTpSI4863pMevVx/exec?display=directory

Given a script URL, how do I determine the actual document?

I was experimenting with Webextensions earlier this year connecting to scripts in my Google account, but now I cannot determine which script I was connecting to.
So I have the script URL. It looks like a normal script URL, e.g.:
https://script.google.com/macros/s/jG5dForTySatijhf-nmG49F64j62RzkgH6dFgr4SalpUyvF/dev
But I cannot work out which script that URL belongs to! Given a script URL, how do I determine the script in my Google Drive?
UPDATE:
I think I can phrase my question a little better now, and I cannot imagine I am the first person to have this problem so I imagine there must be some solution.
I have the web app URL (like the one above) for a published script. But I cannot remember which actual script (in my Google Drive) it is associated with.
Given a web app URL, how do I determine which file in my Google Drive it is associated with? I know it's one of them but I don't know how to determine which one!
Perhaps I can suggest an alternative approach. This would be particularly useful if you have been experimenting with scripts, as you suggest, and have not created a lot of projects.
All your projects can be found on Google at:
https://script.google.com/home
The metadata for each project includes the name of the container, and you open the container from that screen

Calling a Google Drive SDK from Google App Script application

i have been going around in circles here and have totally confused myself. I need some help.
I am (trying to) writing an application for a client that in concept is simple. he want a google write document with a button. the google drive account has several folders, each shared with several people. when he drops a new file in one of the folders, he wants to be able to open this write file, this file is the template for his email. he clicks the button, the system calls the changes service in the Google Drive SDK https://developers.google.com/drive/manage-changes, gets the list of files that have been added since the last time it was checked, then pull the list of people that the file has been shared with, and use the write file as a template to send that list of people an email saying their file is ready.
SO, easy enough, right?
I started by looking at the built in functions in the Google App Script API. I found this method, https://developers.google.com/apps-script/class_docslist#find in the DocsList class. problem is the description for the query simply says "the query string". So at first i tried the Drive SDK query parameters, which are
var files = DocsList.find("modifiedDate > 2012-12-20T12:00:00-08:00.");
it didn't work. that leads me to believe it is a simple full text search on the content. Thats not good enough.
That lead me into trying to call a Drive SDK method from within an App Script application. Great, we need an OLap 2 authentication. easy enough. found the objects in the script reference and hit my wall.
Client ID and Client Secret.
you see, when i create what this really is, a service account, the olap control in apps script doesn't know how to handle the encrypted json and pass it back and forth. Then when i tried to create and use an installed applications key, i get authentication errors because the controls again, don't know what to do with the workflow. and finally, when i try to create a web app key, i can't because i don't have the site host name or redirect URI. And i can't use the application key ability because since im working with files OLap 2 is required.
i used the anonymous olap for a while, but hit the limit of anonymous calls per day in the effort of trying to figure out the code a bit, thats not going to work because the guy is going to be pushing this button constantly thru the day.
i have been pounding my head on the desk over this for 5 hours now. i need some help here, can anyone give me a direction to go?
PS, yes, i know i can use the database controls and load the entire list of files into memory and compare it to the list of files in the database. problem being, we are talking tens of thousands of files. bad idea.
I wouldn't use DocsList anymore - DriveApp is supposed to be a more reliable replacement. Some of the commands have changed, so instead of find, use searchFiles. This should work more effectively (they even use a query like yours as an example).

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.