Is there [or would it be] a way to dynamically load a GAS library server side?

87 views
Skip to first unread message

Faustino Rodriguez

unread,
Apr 8, 2019, 7:47:27 PM4/8/19
to Google Apps Script Community
Let's say I have a library [or a code file in general] with some extended functionality, that might even require an extra permission
- I would like to load and use that code, only if the end user opt-in for that functionality

Is that possible or would it be possible in the future?

Thanks, Fausto

Adam Morris

unread,
Apr 8, 2019, 11:50:21 PM4/8/19
to google-apps-sc...@googlegroups.com
I can't speak definitively about the future, but there is no such mechanism presently. Given the previous statement on here about expectations for libraries and remaining the same in terms of discoverability and mechanisms, it sounds like probably not short-term future-wise. 

--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-apps-script-community.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-apps-script-community/63a3eb5b-3136-43e8-9c73-1d39955cd5ac%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Clark Lind

unread,
Apr 9, 2019, 7:52:28 AM4/9/19
to Google Apps Script Community
This is how I would think about doing it.
Wherever you are storing your user's options on your side, (i.e., knowing they have opted in for that functionality), say in a sheet, or Firebase, or other service,
set an "opted-in" field to TRUE. If it only runs once, create another field like "Triggered" and set to FALSE (or something that knows when the extra functionality has run).

Then you could either have a simple trigger that runs the extra functionality each day (or on demand), checking for all users with "Opt-in" TRUE (and "Triggered" = FALSE for one-time runs. After successfully running, set "Triggered" to TRUE).

Something like that. Not sure if that is what you were asking...  I would think that as long as the "opted-in" field is stored outside the app and has to be looked up in another service/source, it should be secure enough.

Another way to implement which I believe most developers use today, might be to have two separate apps. A "Free" version, and a "Pro" version (or whatever labels you want to use). The second "Pro" version would include the additional functionality.

I'm guessing that is the 'cleanest' way to do it and keep it separate and unhackable (or at least harder to hack).

Stéphane Giron

unread,
Apr 9, 2019, 9:20:15 AM4/9/19
to Google Apps Script Community
Hi

I remember there was something like that in an old RoadMap of Apps Script. Have the same kind of incremental permission that you have in Android. But for now not possible.

Stéphane

Alan Wells

unread,
Apr 9, 2019, 10:20:50 AM4/9/19
to Google Apps Script Community
If you are setting scopes directly in the appsscript.json file, then I don't see how it would be possible to dynamically ask for a new scope authorization.  You'd need to add that scope to the appsscript.json file.  And even if that were possible, it would change the scopes for everyone who used the script.  You couldn't differentiate between who hadn't chosen the new capability and who had.

If you don't set the scopes directly in the appsscript.json file, then there might be a way to force the code to ask for a new scope, but then you've got a problem with the user needing to initially authorize broader scopes, which I would never want to do.  For example, unless you set the scopes directly in the appsscript.json file, then there is no way to specify the narrow scope to just send an email.  And if you don't do that, then you might have a problem with being asked to pay lots of money for a security assessment.

So, it seems to me, that no matter how you look at it, there would be a problem, unless your users don't mind giving the broadest authorization right up front.   But, if you're going to do that, then whats the point of asking for another permission later?

The way I would deal with it, is to have two different projects, and provide a way for the user to transfer their settings from one to the other.

It would be really helpful if there was a "built-in" way of doing this.

On Monday, April 8, 2019 at 7:47:27 PM UTC-4, fausto wrote:

Romain Vialard

unread,
Apr 9, 2019, 11:10:08 AM4/9/19
to Google Apps Script Community
On my side I tested the following approach for incremental permissions: to use a specific feature, people are required to accept additional permissions via the Oauth2 library and I call another script via the Execution API to answer the user's request. Both scripts (the main one and the one with the extra feature) share a single Cloud project (but permissions in the manifest files are different).

I also tested loading a different script inside an existing one. eg, mail merge add-on: user wants to fetch contacts from Salesforce: in the add-on UI, inside an iframe, I display a second UI powered by Firebase Hosting, ask people to grant new authorizations and make calls to another script via the Execution API. That way I can keep the code powering this extra feature outside of the main code base.

Alan Wells

unread,
Apr 9, 2019, 12:02:50 PM4/9/19
to Google Apps Script Community
What would the steps be to set this up?
  1. Create new stand alone apps script file - Or create a new project from the code editor (Two projects associated in the same file?)
  2. Go into GCP - Add the apps script ID to the GCP project 
  3. User can click something in a sidebar or dialog to authorize the second script
  4. When the code runs, the first script makes a URL Fetch call to the second script if added feature is needed
  • Does the second script use the quota of the account that authorized the permissions?
  • Would there be any issues getting this approved for use in an add-on?
  • Any chance that you could write up something on your site about how to implement?
Thank you for sharing your knowledge about this.

Faustino Rodriguez

unread,
Apr 9, 2019, 12:53:53 PM4/9/19
to Google Apps Script Community
Thanks @everyone for your feedback and insights
Combining some of the suggestions, I came up with a wild (and likely wrong) idea

My goals:
- Add a time-based trigger to a Sheets add-on to run a function unattended, every hour or so
- But only force the user to authorize the new scope (script.scriptapp) if/when the user opt-in for that extra feature

My premises and assumptions:
- If I set the scopes in the manifest.json and don't include this extra scope (script.scriptapp) there, the add-on script will fail only if/when running the code to create the trigger
- Then, when the user opt-in for the trigger, I would [magically] use the the Oauth2 library to provide that extra permission / authorization
- And the user would be able to set the trigger

+ Could that be possible ...?
+ If yes, how to use the the Oauth2 library for that purpose?

p.s. I have used the the Oauth2 library before, but my understanding around Oauth2 is limited

Riël Notermans

unread,
Apr 9, 2019, 2:32:53 PM4/9/19
to Google Apps Script Community
I think, technically, you can load the script contents via Drive API, and eval() it during runtime.
Be aware of the potential security risks, but I think if the script is not accessible to the end user, the risks are pretty limited. Eval() is genrerally not recommended but eventually you are evaluating a new set of generated code.

I think that is what you ask for?



--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-apps-script-community.

Alan Wells

unread,
Apr 9, 2019, 4:58:17 PM4/9/19
to Google Apps Script Community
Are there any size limits for eval()?  Are there performance issues?  Where is the original code going to be stored?

Riël Notermans

unread,
Apr 9, 2019, 6:16:52 PM4/9/19
to Google Apps Script Community
I guess size limit is your memory.
Performance issues I don't think so.
Original code could come from anywhere.  It is (temprorarily) stored in runtime memory.

Riël Notermans

Op woensdagen vrij • Zzapps B.V. • High Tech Campus 9, 5656 AE Eindhoven • T 040 711 41 94 • E ri...@zzapps.nl • www.zzapps.nl
WIJ MAKEN HET ONDENKBARE MOGELIJK


--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-apps-script-community.

Faustino Rodriguez

unread,
Apr 10, 2019, 8:35:18 AM4/10/19
to Google Apps Script Community
Thanks for the eval suggestion, that might be a choice
However, I am trying to find an approach within the GAS project, particularly because it'd introduce a new permission


On Tuesday, April 9, 2019 at 2:32:53 PM UTC-4, Riël Notermans wrote:

Romain Vialard

unread,
Apr 10, 2019, 9:01:42 AM4/10/19
to google-apps-sc...@googlegroups.com
@Faustino, calling a script via the Execution API after granting authorization via the OAuth2 library is usually a good method to request extra permissions... but not in your specific case. Indeed it's not possible to create triggers via the Execution API.

So the user would not be able to set the trigger. This specific scope must be included in your manifest (otherwise you would need to create your own replacement to triggers, a code outside Apps Script that would wake up / trigger the script when needed, for the desired user - something that you could do, still by using the Execution API and an OAuth2 library to generate a proper authorization token).

--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-apps-script-community.

Adam Morris

unread,
Apr 10, 2019, 9:26:22 AM4/10/19
to google-apps-sc...@googlegroups.com
Hi Romain,

I investigated this route (via Execution API) but ran into the requirement that the scripts have to share a common GCP project. Or is the trick in how to generate a proper authorization ticket? Is there a resource that can be consulted on how to do this? 

Adam


For more options, visit https://groups.google.com/d/optout.
--
————————————————————————————

Adam Morris | IT Systems & English Teacher | IGB International School
Jalan Sierramas Utama, Sierramas,
47000 Sungai Buloh, Selangor DE, Malaysia

t    +60 3 6145 4688
f    +60 3 6145 4600
w   www.igbis.edu.my
e    adam....@igbis.edu.my

————————————————————————————

Romain Vialard

unread,
Apr 10, 2019, 9:52:26 AM4/10/19
to Google Apps Script Community
If you want to reuse the authorization token generated by your main script (using ScriptApp.getOAuthToken()) indeed your second script needs to be attached to the same GCP project. This is not an issue as you can link multiple scripts to the same GCP project (via menu Resources > Cloud Platform project > Change Project).

If you are using the OAuth2 library, you can even have 2 different scripts linked to 2 different GCP projects (in the configuration of the OAuth2 library, you simply need to mention the proper client ID & secret: the ones from your second script).

Adam Morris

unread,
Apr 11, 2019, 4:02:40 AM4/11/19
to google-apps-sc...@googlegroups.com
I’m following and I see how this works, but in the case where you want to build a reusable, modular library, is there a way to programmatically do that project linkage? It seems to me that for every time you need to “import” a library you’d need to do some backend work. Yet if this were scriptable then you’d essentially be able to build a package manager.


On Wed, Apr 10, 2019 at 9:52 PM Romain Vialard <romain....@gmail.com> wrote:
If you want to reuse the authorization token generated by your main script (using ScriptApp.getOAuthToken()) indeed your second script needs to be attached to the same GCP project. This is not an issue as you can link multiple scripts to the same GCP project (via menu Resources > Cloud Platform project > Change Project).

If you are using the OAuth2 library, you can even have 2 different scripts linked to 2 different GCP projects (in the configuration of the OAuth2 library, you simply need to mention the proper client ID & secret: the ones from your second script).

--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/google-apps-script-community.

For more options, visit https://groups.google.com/d/optout.

Romain Vialard

unread,
Apr 15, 2019, 11:13:54 AM4/15/19
to Google Apps Script Community
In the case of a "reusable, modular library" I would encourage you to simply publish your library on npm.
Reply all
Reply to author
Forward
0 new messages