I want to be able to run a google apps script as a "macro" with params.
For example, I navigate to script.google.com, that'll show me which scripts are available. I click one of them, then hit "Run" to run it. When I run it, I want to have the script prompt me for some input, and then it'll run some code to create a folder in Drive, some files, give permissions to those files, etc.
In terms of getting input from the person running the script, I don't care if they can pass it in somehow (like cmd line args) or if the code can just prompt the user for the input (console input is fine).
What's the best way to do this?
The Run command form the Google Apps Script editor can't open a user interface from stand alone scripts. You might use a Google Workspace Editor file (document, form, slide or spreadsheet) as a container of your script, then display a prompt, dialog or sidebar on the corresponding web application. For details see https://developers.google.com/apps-script/guides/dialogs
Also you might create your own web application. For details see https://developers.google.com/apps-script/guides/web
Also you might call your Apps Script function from other place by using Google Apps Script API. For an overview see https://developers.google.com/apps-script/api
Also you might use a CLI by using CLASP.
But maybe the simpler way is to create a function to set the values of the parameters and to call the parametrized function. In order to reduce the number of function on the IDE dropdown you set the parametrized functions as private functions (add a _ at the end of the function name)
Related
How can I test a trigger function in GAS?
Related
I'm working in a Google Script that runs on a a Google Spreadsheet and creates an onEdit() trigger on it.
I would like to know if this script is somehow visible (through Google's interface or any kind of source code inspection) to the users that access the table with readonly permissions.
From my understanding users would not be able to access such a script, since they are suppose to run on Google's server side and not on the client browser. I couldn't find anything about that on App Scripts documentation.
Regarding the use of a web browser developers tools (like right click and selecting Inspect) over a spreadsheet they will not the script code if you do right clic over an spreadsheet but it might show the name of functions called by a custom menu or image with an assigned function, not the code of the onEdit function.
User with view access can't view the code but, if you didn't disable disabled make a copy, they see the code if they made a copy of the spreadsheet.
An alternative to limit users to make a copy of the spreadsheet is to publish your script as an add-on.
Related
How to protect the Apps Script code in a Google spreadsheet?
First of all I am after 3hours of reading docs about google cloud, publishing, projects and so on. After many tries i realized that i am missing something so here is my question.
I have two spreadsheets, lets, call it "prices" and "costs". What i want to achieve is that they share same app scripts and if I change one script, since it is shared by both it will automatically change in secons.
So i did create an app script that returns a string (just for simplicity) in a cell and called it STRINGFUNCTION(); Is is created in PRICES spreadsheet. My goal is to have it working in COSTS file without typing it manually.
I expected that if i click Resources > Cloud Platform Project and add both app scripts from both spreadsheets to the same project it will work automatically. Well, it wont - if i write in a cell =STRINGFUNCTION() in PRICES it works fine, and in COSTS - it says that function in not known.
How can I achieve that so it works between my both files and they share same function if they are both in same project?
You can do this by putting your code in a standalone script and use it as a Library.
https://developers.google.com/apps-script/guides/libraries
Here's how to do this:
Go to https://script.google.com/ and create a new project
Replace the code with the code for your custom functions and save
Click "Untitled Project" and give it a name to use for accessing the library
Click the blue Deploy button and choose New Deployment
Click the gear beside Select type and choose Library
Enter a description and click Deploy (this is what makes your Library available from other scripts)
Go to Project Settings and copy the script ID
Go back to your Spreadsheet, open the script for your sheet, click + beside libraries and paste the script ID and click Add
Remove the code for the custom functions if necessary and you're going to create functions to pass through the library functions
If your function is called STRINGFUNCTION(), create a function in the local apps script like this:
function STRINGFUNCTION(parameter) {
return libraryName.STRINGFUNCTION(parameter);
}
Do that for each function you want to use from the Library and save your code. You will need to authorize permission for the script if you haven't already. Now the custom functions should be available in your spreadsheet. Copy and paste this "pass through" script to each sheet where you want to be able to access the custom functions from the Library.
Custom functions inside a Library cannot be called directly from a sheet. You only have to set up this local script to pass through the functions, once. Now if you update the script in the Library, the updated functions will be available to the sheet. You will need to do the deploy set each time you make a change to the Library to publish the changes. If the changes aren't working in the sheet, click on the Library in the local script and make sure the version is Head or the latest version you published.
You can only bind a Google Apps script file to one document at a time. Apps script doesn't allow you to edit the contents of a .gs file on the cloud from inside another Apps script file, as trying to fetch:
var data = DriveApp.getFileById('script-id').getAs('application/vnd.google-apps.script');
will return the error:
No item with the given ID could be found, or you do not have permission to access it.
You could however bind the script to one spreadsheet, for example say the 'COSTS' spreadsheet, and create a second sheet within the spreadsheet for 'PRICES' with all the relevant function calls. In the separate 'PRICES' spreadsheet you could then use the build-in IMPORTRANGE formula to get the data from the 'PRICES' range from the first spreadsheet that has the bound script.
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'm coding a script for a spreadsheet. This script creates a menu.
Then by choosing an option in this menu a function (which uses API) will run in order to filter some columns and hide others.
The problem is:
This sheet is protected (because shared with coworkers) but I want to allow people to run the script, which is impossible without the permission.
I already looked at different solutions:
Using a trigger: Doesn't work because a trigger can't correctly call a function which uses API (yes, my functions use API).
Web App: When the script is run from the spreadsheet, the script is run as the current user, not the script editor. (the web app is efficient if the user uses the HTML page.)
Remove protection -> run the function -> Re-add protection: Can't modify the protection without permission, which is logical.
Add the current user in the list editor -> run the function -> Remove the current user from the list editor: Can't modify the editor list without permission, which is logical.
How can I solve this problem?
This is a pain that I have not seen a good workaround. Google should know that in a collaborative environment that the owner would create script and want users to be able to run those scripts while at the same time not messing with formulas or cells that you desire to protect. The only way I have found to solve this on the sheet itself is to Unprotect and then Protect the cell or range you are making modifications to during the script run. Do be mindful that if the script fails in the middle (after you have unprotected it) the cell remain unprotected. Might want to run within a "try" script.
Are you the spreadsheet owner?
If no, you are not authorized to bound an apps script on it.
But you can make a copy of the spreadsheet by duplicate it and save in your drive.
If the spreadsheet is created by you yourself, maybe you created it by another username. If it does, log in by that user and change the sharing option to allow the specific user can edit it.
I have created a standalone Apps Script from Google Drive, but when I try to access it from a Google Spreadsheet, I don't see a way to access the script (even though when I created the script, I created it as a spreadsheet script).
In the spreadsheet, the "Tools->Script manager..." menu item doesn't show my script, nor does the "Tools->Script editor...". The latter has a section for 'recent projects', but it doesn't list my newly created script, nor its associated project.
If I create a new script from inside the spreadsheet (i.e .Tools->Script editor...) and cut and paste the code from the standalone script, it works fine. However, this can only be used in the single spreadsheet -- to use it from another one, I have to cut and paste / go through auth again.
Is there a way to do this without publishing the script to the gallery, which I assume makes it public (I don't have a problem making it public, but it seems like there must be a better way)? The script is here -- it is world readable with the link. It adds a menu to a google spreadsheet that lets you run a query in BigQuery and dumps the results into your spreadsheet.
The behavior you describe is exactly how it is intended to work... the script you wrote can only work if it is bounded to a spreadsheet.
The fact that you wrote it in an independent script makes it indeed a standalone app but it can only be executed from within the script editor and in this context an onOpen function like the one you wrote doesn't make sense (it runs on opening a document/spreadsheet, not the script).
For now a script can only be bounded to a spreadsheet by copy/pasting the code, at least a script that you want to use as you do (with a menu and direct function calls and activeSheet calls), maybe one day Google will expand the concept of libraries to make your script function available from different document directly (read also the doc about libraries).
There are actually 2 types of standalone Apps Scripts, the one you tried that runs only from within the editor and webapps that are deployed and run in a browser window by themselves. The latter are always build around a doGet function that represents an entry point for the application. You should read the documentation on the subject to get all the details.
To summarize : if you want to access your spreadsheet using getActiveSpreadsheet() and similar methods then you have to write (or paste) the script in the script editor bounded to the spreadsheet.
If you want to have a standalone script you can also interact with spreadsheets (and other document as well) but you have to access them by their ID and the spreadsheet will only be viewable from another browser window, without link between them, and there will be no "active spreadsheet" nor "active sheet"...
A webapp can of course also do that with the advantage of a user interface that you can adapt to your needs but this is becoming a bit too far from the scope of your question.
Hoping I've made it (a bit) more clear, at least I tried to make it simple ;-)
I worked this out with Jordan, following the instructions here:
https://developers.google.com/apps-script/guide_libraries
First, he had to share his standalone script with me, so I had read access to it (probably setting the script as public read would work too).
Then he told me his project key.
I took his project key and inserted it in "Find a Library", in the "Manage Libraries" menu.
For this to work, Jordan had to export "a version" of his library - so third parties can rely on stable code and upgrade at their own rhythm.
As Jordan's script runs automatically on onOpen(), my code had to define a function onOpen() that called his script onOpen(). To do this, the library manager gave me an identifier for the imported library.
Sample code once the library is imported and the library manager gives you an identifier for the library:
function onOpen() {
GivenLibraryIdentifier.onOpen();
}
You can also use installable triggers. If you install an installable trigger (such as onOpen) from your standalone script into the document, it gets similar privileges as if it were a simple trigger.
And better yet, when the installable trigger calls its function from your standalone script, it executes WITHIN your standalone script! So it can call any other function in your standalone script. Its Logger.log() entries can even be viewed from your standalone script, even though it was executed from your sheets document.
So basically, if your script installs an onOpen() trigger tied to one of its functions, it's as good as if your Sheets document had required() your whole standalone script file.
(Assuming the owner of the script has edit privileges to the file.)