I have a google script presently that uses the basic time-based triggers, and runs once a day. The code works and the trigger runs when it is supposed to, but I want to enhance my script to run when a file is uploaded to my drive. Right now, I use a lot of logic to determine if any file has been uploaded since the last run, but I really want to get it so that the script runs if a file has been uploaded.
My question is, is that possible, and if so, can someone direct me to some links on how to make this a reality?
Thanks,
Related
I’ve created a Google Sheet – kind of like an app – using script. It’s a number of blank cells where once added some information, it creates a string with that information in the right order. I created this to help some colleagues. We are using free accounts.
I face 2 problems:
The app is supposed to be used by only one person at a time, but I’m sure at some point two or more people will want to use it at the same time. Is there a way to allow this without they interfering with each other? I’ve read you can share a link that creates copies of your doc, but that wouldn’t work in this case because I intend to keep updating it regularly.
The changes people make to the sheet will stay there. Right now I have a onOpen function that just rewrites everything, but if someone accesses the document while someone is using it they’ll rewrite everything and ruin their work.
Any ideas on how to solve these two problems? Thank you so much in advance!
I think that you have to find another way to implement your "app" because Google Sheets not a good tool for limiting that only one user edit a spreadsheet a time, but if for any reason you decide to keep with it,...
... you need to implement a workflow like the following
Save the active user email on PropertiesService.getUserProperties().
This should be done by each user by running a script themselves. The most user-friendly will be by using a macro, custom menu or button (a drawing with an assigned Google Apps Script function). You might use an open installable trigger to validate that the active user have already done this.
You might have to make the function that clears the data a "smart" function.
You might have to consider additional cases, like if the owner of the spreadsheet opens it when there is an editor working on the spreadsheet.
Use installable triggers to manage the sharing settings.
Use an open trigger to remove all the editors except the active user
Use a time-driven trigger to add again the editors. To make this work effectively should define how the time-driven trigger will know that the last editor have finished their session, i.e. you might use DriveApp.getFileById(SpreadsheetApp.getActiveSpreadsheet().getId()).getLastUpdated()
The above should help you with both problems, as long you as the owner do not open the spreadsheet as is used by someone else.
Other alternatives that might work better is to create an add-on or a web application.
Related
Determine current user in Apps Script
Last modified date in Google App Script GAS sheets
I have a script that runs on a Google Sheets that is fed by a Forms entry. Basically, when I fill out a form, it creates an entry on the sheet. From that entry, a new document is created by my script that "prettifies" the fields on the sheet for distribution.
This sheet is located on a Team Drive, but in order to have the resulting document created in my drive, I had to place the unbounded script in my drive and reference the sheet. If I have it bounded to the sheet, it will always put the newly created document in the Team Drive -- which I don't want.
When it was bounded to the sheet, I had a trigger that would automatically create the document when the form was submitted. Now that the script is on my drive, triggering on submission is not an option. The only options I have are time based or calendar based, and neither of these really work -- unless I only want to get the document once a month or every single minute.
So now, the only way I know to execute the script is to do it manually every time, which is a major hassle and requires multiple steps no matter how you go about it.
Is there a way to trigger this script on command without having to open the Script editor, click the script I want, and then click run?
Why are there no keyboard shortcuts in Apps? I know about Ctrl+R -- but this only works if you already have the script you want highlighted in the top action bar. If I type Ctrl+R without it already highlighted, nothing happens. Nothing happens with Alt+R or Alt anything, really. I have tried simply tabbing 187 times to get to where I need, but the tab never seems to focus "in" the script menu area. It just bounces around the address bar, the shortcuts bar, etc.
NOTE: I do not want to make major changes to THIS script. It took forever to get this working right and I don't want to jack it up. I just want to be able to trigger it without having to go through 18 steps to do so.
There is no way to execute a standalone script project's function with a keyboard shortcut from within the Apps Script Editor. If your script was bound, you would have the option of keyboard shortcuts from the container Google Sheets file (as a google-sheets-macro), but macros have some restrictions.
However, you are not without options. Two of them:
Publish the script project as a webapp and use a page visit as the trigger.
Open the page / click a bookmark -> execute the function via your doGet().
Convert your script to a 'polling' style that processes any number of form responses, and use a time-based trigger (e.g. hourly, daily) to automate the whole process.
(Include a "did I process this response yet" flag to prevent reprocessing a response)
There are more elaborate configurations (e.g. Apps Script API + local cron job) but those are unlikely to be simpler than the above two options.
As I mentioned in my comment, you more than likely just needed an extra step for the original bound script to create the file in your Google Drive and not the host Team Drive. If you're interested in that avenue, you'll want to ask the appropriate (read: new) question.
This is a workaround not an answer.
I use the Alt/ menu to efficiently look up functions by name (For me, its faster than using a cursor to work thru the nest of menus). If you design your function names so they differ from the built-in function names, the lookup may take only a few keystrokes)
I wrote short script for numbering of document sections. But every time when I want to use it in new document I must create new copy of that. I tryed to publish the script by option "Deploy as web app..." but it is not clear how to connect it in new document. Is it possible? I have few documents in Google Drive and few copies of same script for each of document. Can I connect every document to one script? Thanks a lot!
This is not possible for now, there is an open enhancement request that you could star to mark your interest and be informed if something new comes up...
I had a similar problem.
The leaner solution that I was able to imagine is to keep the function in a saparate, shared script file. In the spreadsheet script, you will use the shared script file as a library.
In this way, your logic remains in a single copy, the actual part of the logic that is copied several time is only a call to a shared function.
I have a script which adds new rows and changes the sheet in some ways.
I'd like to lock this sheet so it cannot be edited manually, but allow the script to be run.
Is there a way to do this?
Yes, it's not the most easier thing to do, but it's possible.
But before we start it's important to understand how Google spreadsheet/sheet protection works.
There's no way to protect a sheet or range from the file owner. So, if you also want to protect a file from yourself (assuming you're the owner). Then the only solution available now (I do hope they change this in the future) is to change the ownership of the file to another account. What most people do is use another Google account that they don't use actively (you can create a bogus easily if you don't already have one).
Then, after you have transferred the file to another account, you can easily lock changes to ranges, sheets or the whole spreadsheet using the regular GUI.
Ok, now to the script. When a script runs, it's always using the authorization of a specific account, and it can do everything that this account can. For example, when someone runs a script directly from the script editor, or clicking on a custom menu or image: it runs under the account of who's clicking. But if you set a installable trigger, then the script always runs under the account of who setup the trigger in the first place (not who's performing the action that actually triggers it). Simple event triggers run as who's triggering the action (you can think anonymously), but they can't do much, it's a security feature (read the link for a better understanding).
Lastly, when one is publishing a script as a web-app, then there's a selection box to choose if the script runs as the developer or the user. Very simple.
Back to the problem. Since we have locked out everybody from the desired sheet/range. For a script to make changes to this locked area, it must run as the file owner!
If the changes you do are automatic, e.g. via a installable trigger, then you're good. Just setup the trigger using the file owner account and that's it. Also, if your users are accessing the script "externally", that is, via a web-app. Then that's easy to, just setup the web-app to run as the developer (the file owner).
The most complicated scenario is if you need to run the script from a custom menu, which will then run under the privileges of who's clicking on it, which themselves can not make changes to the protected area. The solution to this is to deploy the script as web-app running as the developer, and have the function running from the button click to call the deployed url using UrlFetch, possibly passing some parameters to designate what needs to be done. Then, since the webapp runs as the developer (which is the file owner), it can make any changes required, and return (if there's something to return) any value (usually a JSON) to the calling function (which is running as the user and is associated with his session), so you can show him a message on a popup or toaster, etc.
It's kind of tricky but works great, and you can do all that on the same script contained in the spreadsheet. But if you're concerned that your users may access the script editor and change the code (which is possible), than you should separate the web-app part on a different file, that you don't need to share with them.
Yes but only for others not for the script owner. Just use 2 accounts one as the owner and the other one as the reader.
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)