Accessing & Reverting to Specific (preferablyNamed) Revision via Appscript in Google Sheets - google-apps-script

I'm not finding a way to interact with 'Named' versions of a Google Sheet using the Drive Rest Revisions methods. Or to move a specific revision to the head.
I'm trying to sort out how to move a named revision to the head after an editor makes edits and finishes. Upon a finish trigger, I want the script to (among other things) reset the sheet to the specific named revision for the next user. (ideally) or, assuming there's no support for named version, to move the specific Revision to the head by RevisionID.
I've only played around with the 'Try it' feature on Google's Reference page for the various Revisions methods and have not found a way there to move a revision to the head or interact in any way with revisions by Version Name.

Related

Can one iterate through bound scripts and edit their manifest files via a script?

I am building an application that will have many users, each of whom will have many Google documents. Each doc will have a custom menu and that custom menu will invoke a library script. I may need or want to change the coding in that library script from time to time.
As changes to a library script must be "saved" as a new version in order for the changed version to be passed on to client scripts (in my case, the scripts bound to Google Docs), I need a way that users can "batch" update the version number in their docs' bound script appsscript.json
file.
I have researched this issue and there seems to be two general alternatives: set the client scripts' library mode to "Developmental" or use an add-on.
The problem with the former is that it won't work unless the users are all granted edit mode access to the library script (which seems particularly a bad idea as the users may well not even be known to me).
The problem with the later is essentially complication and cost. If I make the add-on private, it only works for users in the same domain which means I have to create a G-Suite domain (and pay at least (as of this writing) $72 per year per user—a non-starter for this project).
If I make the add-on public, in addition to the complication, I have to sign up to the Google Cloud Platform and the costs for that require one to navigate a veritable maze of choices and alternatives such that at this point, I really have no idea what the cost per service or user would be.
Below I present some "mock-up" code that should at least indicate the direction I am trying to go.
function upDate() {
var version = 23
var scripts = "https://script.google.com/u/0/home"
//while (scripts.hasNext()) {
//var script = files.next();
//Note: All of the script's have the same name as they commence life bound to a template, which template is duplicated to create the rest of the user's docs
if( scriptName = ScriptName){
//set.dependencies.enabledAdvancedServices[].version
}
}
I don't even know if it's possible to step through bound scripts the way one step's through files in a Google Drive, so that is the first question. Then, the second question is whether, assuming you can step through the scripts one by one, you can change a manifest value—in this case, the version number.
One cannot step through container-bound scripts as they are (no longer) located in one's Google Drive. Moreover, despite Google's documentation about using a "stable" value in the version section of the manifest, that documentation appears erroneous. Finally, one cannot programmatically edit standalone scripts.
However, there is a workaround. What I ended up doing was writing a script that steps through all of the involved Google Docs and copies them to a blank template (i.e., in effect, duplicates them all). That blank template has the bound script installed in it with the new version number of the library. Then, delete original docs (via the same script) and voilà, batch update to all of the target docs is accomplished. (One drawback of this is: if Google Doc revision history is important to you, be advised this gambit jettisons that (unless you keep the original versions).

How can I revert back to a specific revision in Apps Script?

I am trying to revert to a specific revision of Google Sheet with Apps Script. I tried a couple of approach but none of them work.
Got some info about revisions here
https://developers.google.com/apps-script/advanced/drive#listing_revisions
I also tried as following different approaches
Drive.Revisions.remove("xxxxxxxxxxxxxxxxxxxx", 658);
Drive.Revisions.update(resource, "xxxxxxxxxxxxxxxxxxxxxxxx", 657);
Drive.Revisions.update(resource, "xxxxxxxxxxxxxxxxxxxxxxxx", 657);
None of the above works. Can anybody suggest what I am doing wrong or I am missing something ?
I assume here that you are talking about an older version of the script file that is attached to the spreadsheet. The script file can be thought to consist of various individual files eg main.gs, indexi.html etc, If you need to you can access older versions of each of the individual files within the script file but not the script file itself. Go.to the script file choose the individual files you want to recover and then select file -> see revision history and choose the version you would like to recover.

Google Drive SDK: Programatically pin a Google Doc revision

The Google Drive API v2 Drive.revisions.update method allows the setting of a pinned parameter so that the particular revision is never automatically purged. However as the documentation says, this does not apply for Google Docs. How can we pin a revision so it is never deleted? I have an app that depends on tracking and retreiving certain revisions at a later point in time.
Any suggestions on how this can be done?
Google docs (as well as all native google formats like spreadsheet) does NOT get any revisions deleted automatically, thus there is no need to pin revisions.
If you were referring to .doc, those aren't Google docs.
I couldn't find a reference inside the documentation, but I did find an official reference in their marketing page:
https://apps.google.com/intx/en/products/docs/ says:
Unlimited revision history
Track changes made to your documents and undo anything you choose. Previous versions are kept indefinitely and they don't count toward your storage.
It seems that Google is clear about this.
pinned - This will only be populated and can only be modified on files with content stored in Drive which are not Google Docs.
Try converting your revision files to pdf (non Google Doc). You can then keep the revisions using pinned = true.

Remove Revision History

I'm using Google Apps Script to run an encryption on data in a spreadsheet. It's working fine, but that handy revision history in the spreadsheet makes it a bit of a moot point as you can simply view a version prior to the encryption.
Is there a way to delete revision histories, or to simply keep them from being created all together?
No.
The Drive API for accessing revision history specifically does not delete entries on Google sheets.
Something to note revision history is only viewable by those with edit rights. View or comment only rights cannot see revision history.
One solution is to have users submit data to a very narrowly shared sheet via Google forms and set up a trigger to copy the non sensitive meta/aggregate data that you are leaving unencrypted to a more public sheet for access by untrusted users and scripts. the cell formula IMPORTRANGE() would also work it gets access permission from the person entering the formula and can therefore move data from a restricted spread sheet to a less restricted one without compromising the original sheet.
A second solution that is slightly more cumbersome, but closer to your ask, is to provide users and external scripts with access to a drive folder containing the sheet. With the ID of the folder scripts can then search for the sheet by name via the drive api, users use their eyes to find it by name. Your encryption script, once done encrypting, copies the spreadsheet using SpreadsheetApp.copy(name)which will copy all of the formulas, formatting, data, even scripts, but not the revision history. Pass copy() the same name as the original sheet, drive file names do not have to be unique. Use the drive api to move the new spreadsheet to the folder, it should inherit the sharing of the folder by default. Again with the drive API delete the original spreadsheet. Because all users and scripts were looking for a file named X in a specific folder ID everything is still exactly where they expect to find it, but the revision history is gone.
Unfortunately Google Apps Script doesn't provide a method to remove items from the revision history.
Copy all spreadsheet, restore to the first version and then, paste de spreadsheet :)
For Google Documents I managed to get rid of the revision history by making a copy of the document. Not sure if that will work for spreadsheets too.

Is it possible to have one script for multiple spreadsheets?

I have one master spreadsheet and a number of copies. This master spreadsheet uses some scripting.
Is it possible to link all the copies of this master spreadsheet to the same script as in the master spreadsheet?
Objective:
changes in the scripting in the master spreadsheet are automatically used by the copies
aka: low maintenance
amleczko is right: you should use the new library feature in Google Apps script.
However, as of today, you won't be able to do exactly what you want (using the same script for several spreadsheets). What you can do instead is save a version of your script (Files > Manage Versions...), in order to create a library. Then, import this library in the other spreadsheets (Resources > Manage Libraries...). Switch on the "development mode" so every change made do the library will immediately take affect in the spreadsheets using this library. Otherwise, you will have to save a new version of the library for every change, and manually update the version number of the library in every spreadsheets using it.
The problem is, you need to write a script in every spreadsheets using your library, with skeleton functions like this:
function doSomething(){
myLibrary.doSomething();
}
best way is to publish as add-on, then install the add-on, it will appears in every spreadsheet you open. and you can publish as private, which only seen by yourself.
I think this has changed. According to Issue 40 starting from 22 May 2012 there is such a possibility. Please check:
https://developers.google.com/apps-script/guide_libraries
https://developers.google.com/apps-script/guide_versions
http://googleappsdeveloper.blogspot.it/2012/05/introducing-versions-and-libraries-in.html
It's not possible in this way that you're thinking. At least, not yet (see issue 40).
But, depending on your script usage, you may connect them "the hard way" or even better, use only one script. The script on the master spreadsheet can open the other spreadsheet files and do its job "remotely". It's not required that script to be hosted on a spreadsheet to interact with it (read/write on it). You only need a script hosted on the spreadsheet if you're going to use spreadsheet events triggers i.e. on-open, on-edit and on-form-submit.
Maybe you can develop a nice UI for the script on the master sheet and publish it as service. Then only have a link on the copies to access the same UI on a different browser tab. Adding parameters to the link the script UI can even adapt to the particular spreadsheet that is "triggering" it.
Well, that's all I can imagine now. But, unfortunately, there's some use cases that just don't fit this nice "workarounds". For those, one can only star issue 40 (to kind of vote and keep track of updates) and hope it's developed soon.
The solution I put in place in this context was to have a Google Site, where the Master Script is embedded, and where the Spreadsheet is embedded too
Then, the script, refering to a dedicated spreadsheet, looks for the Google Site Page's name, looks in the Master spreadsheet and get the ID of the spreadsheet which is embedded in the Page.
I have solved this problem when using a script which auto generates spreadsheets.
Typically, I will add a sheet to any spreadsheet with a script called "Info." I'll use that to store information that it important to the script. In my script which auto generates more spreadsheets, I keep track of the ID of the created sheet. This way, I can then quickly call up all of the "linked" sheets, and interact with them with using the same script. It might even be worth writing the script in one sheet, and keeping it totally separate from your Master sheet or it's children.
Take a look at this function, it might give you some ideas.
SpreadsheetApp.openById(id)