How do you load/include a Google Script inside another script in the same Project?
D'oh! You don't have to, all scripts in a project are loaded when any function is run.
You can use Script Libraries. Write a script and publish a version of it. In the second script, you can access functions of the first, by adding it as a library in Resources --> Manage Libraries.
See the documentation for full details on creating and accessing a library.
Related
I have a couple of script files that are currently being used inside a Sheet bound script via libraries. However, when a user that does not have access to the independent script files tries to open the spreadsheet and utilize it, he is not able to. For this reason, I am trying to deploy the code as an add on, instead of as a library.
Is it possible to get access to the functions inside the independent scripts via the add-on, just as I would do with a library? Would this solve the permissions issue? Is there a better alternative?
Thank you for your time!
I want to programmatically create a macro and call the same from another stand-alone app script project.
One of the approaches I have used is to create the project using the projects.create API and called the function in that project using scripts.run.
The problem with this approach is that I've to manually set the GCP project for the newly created project, as the script and calling application must share the same GCP project as mentioned here.
I couldn't find any resource to perform it programmatically.
Basically, I want to execute the App script code provided by the user dynamically from my existing Google Sheets add-on.
Any suggestion or help would be great.
Thanks.
Not sure I understand correctly, but lets assume you want to do the following:
Create a Function (your Macro) in a Apps Script Project
Use the Function in the above Project from multiple Google Spreadsheets
In that case you can do multiple things, my suggestions would be
Create a Apps Script Project
Enter your Function (your Macro) in that Project
Use that Project as a Library
Wherever (in a Spreadsheet) you need this Function (your Macro), add the Library and create a Function which calls the Library Function.
One alternative, if you really want a App which runs as Addon, then see here the reference for that.
Reference
Library
Need help using a google script across all google spreadsheets without copying script to each sheet. I've converted the script project to a cloud-managed platform and enabled all the APIs that I think are required.
I've deployed the script as add on and I see it on the add ons menu in sheets but I can't call my functions, etc.
Within one project you can have several different script files (You can create them by going to File>New>Script file). I suggest you distribute your functions and your logic across them the way you most prefer. Afterwards, any of those functions can be accessed by any of the other files declared in the project, so you should have no issue on calling them from i.e. your Add-on.
Additionally, you can use libraries. To do so:
Create a new Project (which will serve as a library). It may have multiple gs files, with multiple functions.
From the guest script, the one that will use the library, go to Resources>Libraries. There, insert your library project's id, and the identifier that will be used (variable name) to reference it. For the example below, I have set it to be MyMathLibrary (see example usage in Invoicing.gs).
Example project:
Project link: https://script.google.com/d/1kNeHHS7M19ILwcbbootMfZFNtg0NdE27WtkElXFBgOVR6haUUKPYqOBL/edit?usp=sharing
Library link:
https://script.google.com/d/12x33E1q3Uk2dgx5SfVTllVel8PeHcudQ-Czwhnu7aJPU5-tFpICuEcMM/edit?usp=sharing
I have read all Google documentation on managing and creating libraries, yet I still do not know if they are an appropriate option for the problem I am trying to solve.
I know how to save a version of a standalone script. I know how to add the library to a spreadsheet via the script editor. But I don't understand, very simply, how to trigger the library script within the new spreadsheet.
I have a spreadsheet that serves as an often-copied template within my organization. The template contains a script that (onOpen) accesses data on a separate spreadsheet (a master database) and sets those values on a tab called "admin." The desired result is to have a copy of the master database living within the template sheet (and every subsequent copy of the template sheet). At this point, there are thousands of copies of the template sheet, each running that same script.
Whenever I have to change the script, I have to change it within thousands of sheets. Can I use a library instead? I'd like to be able to create a new version of the script in the library and have all sheets connected to that library experience the change. I understand that the library needs to be in development mode (within each sheet) to do this. I also understand that in order to make this switch, I will probably still have to go into each sheet to add the library. I'm just hoping it will be the last time I have to do such a tedious task.
Any advice or links to solid info is appreciated.
besides making an add-on (already covered in another answer) I will answer your libraries question. They will work for you. What you are missing is the "connect" part.
For this you want to trigger the library code from say, onOpen. The onOpen in the library is not enough and not detected by apps script. Instead each of your spreadsheet's script needs an onOpen(e) which just calls yourlibrary.onOpen(e).
since those "hook" calls rarely change, specially once you stabilize your library api, and using it in "development" mode will let you modify just the library.
whenever one of those hooks needs to change (say a callback from an html GUI needs a new parameter) you need to update all the spreadsheets. to avoid this, make all your callbacks receive a single json object instead of multiple parameters.
Sorry if I am repeating other answers, but I would like to sum up and add something:
You can access your library functions as follows:
From the app using the library you go to the Resources/Libraries. You can see the library name under "Identifier". On the same line where you can select Development mode.
Library name found in resources
Now in your library you have for example a function
function onOpen(e)
{
Browser.msgBox("HELLO!");
}
In the spreadsheet app you wish to access it you use the library name found in the resources, for example "testlibrary"
function onOpen(e)
{
testlibrary.onOpen(e);
}
Now if you have development mode on, the modifications to functions in the library update automatically to your application (spreadsheet) as long as the user using the application has edit access in your library script.
If anyone using your spreadsheet has a restricted access to your library script (meaning only view access) or development selection is off in the application, you have to go to the application's script, Resources/Libraries and select the most recent version of your library to be used in the app everytime you update the library and save a new version of it.
Still, especially if you are using mostly only the onOpen function , I would recommend using the library rather than copy-pasting the function to the script of each spreadsheet, as it is easier to track which scripts are up to date and it is easier to avoid errors and differences between the scripts.
Even in the more restricted case, if you update function in library - as long as you are already calling it in the app - all you have to do is select the new version of the library used.
I hope I had anything to give in this conversation and my language was appropriate, this was my first answer..
A good question Melly. I've been through a bunch of the documentation and some tutorials on this subject but haven't tried adding any libraries yet. My understanding is that once you are connected to a library all you have to do is call the applicable functions. That once a library is connected the functions in the library become an extension of all the other Apps Script classes available in the script editor.
I'm creating a spellchecker using the Google Docs API in an Apps Script (just a script that extends the functionality of a Google Doc), and I wan't to make this service available to users whom download it as a Web App. Problem is that when I've made my (Container-bound) script in the script editor, it is only available in the Google Document through which I created it - that is, if i open a new document, I cannot use the script.
If I "Deploy as Web App", make it available to everyone and paste the given URL, I get an error message saying that the script needs a function called doGet(), which is not in my script.
How do I go about to publish my script as a regular web app?
I would proceed by creating two scripts:
the core functionality would be deployed as a Web App and a simple container-bound script would offer an interface to call the Web App.
Since the Web App is not bound to a document you may want to follow this scheme:
function doGet(e){
if(e.parameter.docId){
doStuff(DocumentApp.openById(e.parameter.docId));
}
}
Now when you deploy the app you will get a link that gives you access to the functionality.
From the container-bound script you can add some UI (e.g. an Anchor element in a side-panel) that links to the web app with the appropriate parameters
ScriptApp.getService().getUrl() + "?docId=" + DocumentApp.getActiveDocument().getId()
or use UrlFetchApp to get the results and display them in the UI.
Unfortunately this is not the same as adding the functionality across all your documents automatically, but rather a way to install only a relatively lightweight hook in each document where you want to add the functionality, instead of the full script.
I am not aware of any method that can achieve that. Note that when you make a copy of a document, the copy will contain all its scripts so you can create a template for documents that need the additional functionality. This can get ackward though if you wish to mix and match multiple scripts.
The advantage of my method is that if you modify the core functionality, the change is immediately available to all your documents making use of it, with no need to update their scripts. On the other hand if the container-script needs to interact heavily with the UI it may get complicate and reduce the usefulness of separating it in two scripts.
The answer is in your question : the main function of your script (the one that builds the UI) must be called doGet() (this is the conventional entry point of any GAS webapp, the function that you implicitly call when opening the webapp url)... but I'm afraid this will not solve your problem...
Even if I don't know what is in your script and how you wrote it I guess that it refers to the doc in which you bound it as the "active document" and that will probably be the most important issue since a webapp has no document attached to it.
Beside that, how would a spell checker work as a standalone app ? could you explain more clearly what you want to do ?