Using Google App Scripts to share documents - google-apps-script

I have so many documents that I need to manage due to the amount of people that have access to them, and when someone needs to be added or removed, it can become a real pain and time consumer.
I'm curious, is there a script that you can set across multiple documents that give edit or view access.
I'm aware that there is this, "addEditor(emailAddress)", but from what I have gathered, you have to do a script for each document which defeats the purpose of productivity.
Basically, I need one script that gives access to a particular set of documents, and when I need someone removed, i just delete their name and run the script and removes edit/view access from those documents.
Ax example of a script, or rather what I'm trying to achieve. (Not actually a script):
//Human Resources//
addEditor(emailAddress) to BBM1 - Membership Tracker, "https://docs.google.com/spreadsheets/d/1gb8T1K74cRR_6qSyByqrtiphujrchceLP_QsMunoras/edit#gid=0"
//Administrator//
addEditor(emailAddress) to BBM1 - Membership Tracker, "https://docs.google.com/spreadsheets/d/1gb8T1K74cRR_6qSyByqrtiphujrchceLP_QsMunoras/edit#gid=0"
//Moderator//
addViewer(emailAddress) to BBM1 - Membership Tracker, "docs.google.com/spreadsheets/d/1gb8T1K74cRR_6qSyByqrtiphujrchceLP_QsMunoras/edit#gid=0"
So basically, I can just add emails to that, run the script, and it gives them edit access. But, I just don't know how to create a script that actually works for that and also to have a script across multiple documents.
Many Thanks,
Shaun.

Take a look on folder api. You can put all those files into a folder, and then everytime you run the script you can loop through all files in the folder and set correct permissions.
Example (untested):
var folderName = "My auto-managed documents";
var folderIterator = DriveApp.getFoldersByName(folderName);
while (folderIterator.hasNext()) {
var folder = folderIterator.next();
var fileIterator = folder.getFiles();
while (fileIterator.hasNext()) {
var file = fileIterator.next();
// Do things with the file:
// file.addEditor('my-email#example.com');
}
}

Related

Gapps returns undefined for getParents()

I'm running an Add-on for spreadsheets where users can create a document.
This document will be places inside a folder of the current year at the location of the spreadsheet.
This has worked some time but for some reason (I can't find why, or I'm searching in the wrong places) it stopped working.
To find the folder I use this code:
const ss = sa.getActiveSpreadsheet();
var documentID = ss.getId();
var DriveID = DriveApp.getFileById(documentID);
var parents = DriveID.getParents();
console.log(parents.hasNext());
var parent;
while(parents.hasNext()){
parent = parents.next();
console.log(`next parent = ${parent.getName()}`);
}
When I run this part on my own account the parents.hasNext() returns true and I've got a name in the While loop.
But when I run the same script on a test account i get false en that's it, no while loop.
First thing I thought that it was the issue with sharing within drive, but it's set that Everyone of my company has access (read/write) to that folder, subfolder and folder above, so I am kinda running out of ideas what this might be.
Who can tell me what I'm doing wrong here.
The most probable cause I can think is that your test account doesn't have access to the folder this file is in. Because of that, your script cannot get it. Sharing the entire folder should solve the issue (remember that it may take a while to fully propagate after sharing).

Finding differences in two text files from DriveApp

I'm making a script that copies the contents of a Google Doc into a text file and stores it on Google Drive. The user then edits the document and when they are finished it copies a new version to drive in a separate file. I have this part done, but now I need to know how to make the script automagically compare the differences in the text and then change the color of these differences in the doc. Any ideas?
The only thing I've tried is asking my friend who knows a lot more than me when it comes to programming, haha. He couldn't help me.
function copyQuestions() {
var body = DocumentApp.getActiveDocument().getBody();
var getquestions = body.getText()
DriveApp.createFile('tempquestions.txt', getquestions);
DocumentApp.getUi()
.alert('Questions have been copied to a new file on Google Drive. Get to work, and be sure not to delete the file!')
}
function copyAnswers() {
var body = DocumentApp.getActiveDocument().getBody();
var getanswers = body.getText()
DriveApp.createFile('tempanswers', getanswers);
DocumentApp.getUi()
.alert('Coloring answers...')
}
The script creates files with copies of the document's contents. I need to know how to compare the differences between the two of those now. Thank you!
Sounds like you need a Diff engine. You can attempt to write your own by leveraging well-known algorithms such as Levenshtein Distance or Dice's Coefficient but if you're not so inclined you can try looking for an existing javascript library that's compatible with Apps Script.
Did a quick search and found a few open-source repos. I can't vouch for their compatibility with Apps Script, but at least one of them seems viable (JSDiff supports EcmaScript 3 where Apps Script supports up to EcmaScript 5):
JSDIFF
Source (web-packed) : http://incaseofstairs.com/jsdiff/diff.js
Github : https://github.com/kpdecker/jsdiff
NODE-DELTA
Github : https://github.com/znerol/node-delta

How to log a the creation date of a google drive folder in a spreadsheets script?

This is my first google apps script and the original plan was to do something way more comlplicated, but I got stuck in the very beginning.
Now, I just want to log the creation date of my folder, and I can't.
When I press ctr+enter there's nothing to see in the logs window.
Why is this happening? I am not trying to build a rocket here...
Here's my code :
fetchFiles();
function fetchFiles() {
var folder = DriveApp.getFoldersByName("Aff Comm");
Logger.log(folder.next().getDateCreated());
}
Your code, just tested in my Script, works. But:
you need to save your script (extremely important). If there is the red asterisk a in the image below you have not saved your code
you need to select fetchFiles in the dropdown menu (the one in the red rectangle in the image below, if you did not save, the function may be unavailable in the dropdown menu)
at the first run you agree with the permission request from google
You may improve your code in this way:
function fetchFiles() {
var folders = DriveApp.getFoldersByName("Aff Comm");
while (folders.hasNext()) {
var folder = folders.next();
Logger.log(folder.getDateCreated());
}
}

Algorithm to process all files and folders across multiple runs

I note the new Docslist Token and get*ForPaging() options available now but I am still struggling with an algorithm to process "all files and folders" for arbitrarily large file/folder trees.
Assume a Google Drive based web file system with n files and folders. It will take multiple runs of 6 minutes to get through with a Google Apps Script. Nightly I need to process all files older than 30 days in trees of subfolders beneath a starting folder. I need to process each file once only (but my functions are idempotent so I don't mind if I run against files again).
I have my recursive algo working but the thing that I am missing is a way to have a placeholder so that I don't have to start at the top of the folder tree each time I invoke the script. In six minutes I get through only a few hundred folders and a few thousand files.
My question is what index can I store and how do I start where I left off the next time through?
I have thought about storing Tokens or the last completed folder path "/mytop/sub4/subsub47/" but how would that help me on another invocation? If I started there it would falsely just work down the tree from there and miss siblings and ancestor folders.
I have thought about the "find" methods and using a "before:2012/10..." style search but there's no way to limit that to files in my tree (only a single folder).
I am not pasting my code as it's just standard recursive getFolders/getFiles and not actually relevant to the core of the question.
I'd create an array of the folders that I have to work on and save it all for a future run.
Since you said it's no problem to work on some files/folders repeatedly, you don't even need to put a fake stop to your function. You can let it timeout every time.
Something like this:
var folders = null;
//call this to start the process or set the property manually
function start() {
folders = ['id-of-the-starting-folder'];
work();
}
//set this to run on the trigger
function work() {
if( folders == null )
folders = ScriptProperties.getProperty('folders').split(',');
while( folders.length > 0 ) {
workOnFolder(folders[0]);
folders.shift(); //remove the 1st element
ScriptProperties.setProperty('folders', folders.join());
}
//remove the trigger here
}
function doFolderLater(folder) {
folders.push(folder.getId());
}
function workOnFolder(id) {
var folder = DocsList.getFolderById(id);
folder.getFolders().forEach(doFolderLater);
folder.getFiles().forEach(workOnFile);
}
function workOnFile(file) {
//do your thing
}

Google script DocsList service query string not working

I'm making a little script to automatically organize some autogenerated spreadsheets. The goal is to archive the spreadsheets in a directory based on their name (all of them start with the same name but end in a pattern I'm using to organize them). The problem I have is with the function:
lstFile = DocsList.find('type:spreadsheet title:"PROG_GRAL_CENTRE"');
The function doesn't have the query options specified in the docs, but I'm using it on another script and is working fine! I've also tried putting only:
lstFile = DocsList.find('PROG_GRAL_CENTRE');
which should find 200 documents, but none is found! Actually, if I type PROG_GRAL_CENTRE into the search box of my google Drive, all the documents are found, so I don't know what's wrong with my search filter.
Any thoughts?
The method find(query) looks for a string in file content, not only on file name... so even it it worked normally (meaning without the issue you mentioned) I'm not sure it would be a good solution for your use case since there would be a risk that some filename could be found inside another doc with another name (as a reference for example...).
Why don't you try getting all filenames in an array and search into this array instead ?
This can be done very easily and would bring an elegant solution to your problem wouldn't it ?
I'm working on this very same type of script right now ;-) here is the part that gets my files (just an example if ever you are interested):
var doclist=DocsList.getRootFolder().getFilesByType("document",0,2000);
var names = new Array();
for (nn=0;nn<doclist.length;++nn){
if(doclist[nn].getName().match("IMPRESSION_")=="IMPRESSION_"){
names.push([doclist[nn].getName(),doclist[nn].getId()]);
}
}
after that I sort the array the way I want and show the result in a list UI.