There are some new problems to do with the accessibility of functions in the global space which depend on a number of factors such as the order of declaration, and whether they are in a namespace as well as changes to the scope of ‘this’  in v8. When you access a server side function from client side in an add-on or indeed any htmlservice, you’ll be using google.script.run, which takes this format.

and of course relies on ‘theFunction’ being in the global space and correctly available. It is also unable to execute things in libraries or in namespaces, for that same reason. Previously I’ve deployed workarounds using a provoke function – for example in this Using promises to orchestrate Html service polling  , but these techniques are now unreliable with V8

Problem into opportunity

With every problem comes and opportunity, so in the post we’ll look at a better way to –

  • Promisify google.script.run
  • Introduce whitelisting – limit what can be run from the client side
  • Run anything, whether or not it’s in the global space
  • Abstraction of the how from the what

The KeyStore class

In  Apps Script V8: Keystore for global space  I introduced the keystore class to help overcome some of the global space challenges arriving in V8, and it will play a key role in this new method. You’ll need the class to use on the Server side. Here’s the library reference.

The whitelist

The core concept is that you no longer reference function names from the client side. Instead you reference them by a key in the keystore which knows how to execute them and is available globally in your server side project. So first you make a whitelist like this.

This whitelist is going to allow access to all  these kinds of functions, ranging from Apps Script services through to library functions.

Running from the whitelist

The idea here is that all requests to run things Server side pass through a single function that knows how to access the whitelist.

Running from Server side

Before we head over to the client side, don’t forget you can use this same methodology to expose any function globally to your project, without having to actually put them in the global space. To show that we can test all these functions server side like this.

Running from Client side

To run one of these functions using google.script.run – it would look like this

Better, but let’s promisify that, so we can run them like this.

or if you prefer

Provoke namespace

Here’s the code for the provoke namespace

Summary

This approach is a good way to get over the v8 global space problem, indeed getting everything out of the global space is a good strategy anyway, it abstracts and secures by placing everything runnable in a whitelist, gets rid of those untidy callbacks and allows you to access all manner of services and libraries from the client side. Here’s the steps as a reminder

On the server side
  • include the keystore
  • make a WhitelistedActions namespace
  • include the runWhitelist function in the global space
On the client side
  • use the provoke namespace to call actions on the whitelist