0
votes

I have a backend service and some users with data in their Google Sheets. I want my service to fetch and modify data in those sheets on behalf of their owners. So I've written a two-part solution:

The Script editor code containing doGet and doPost functions The Library imported into that Script. This Library actually does all the heavy lifting. A simplified version of the Script:

function doGet(req) {
  // Let Mylib handle this
  return Mylib.handleGET(req);
}
function doPost(req) {
  // Let Mylib handle this
  return Mylib.handlePOST(req);
}

A user exposes his Spreadsheet to the world via Publish -> Deploy as web app... and provide the resultant Web App url to my service.

This works pretty much good, except that I don't want to bother my users to update version of the Library and then redeploy the app every time I release an update to the Library. So I thought that implementing the Library as an Editor Addon would be an elegant solution for my case, but I can't seem to reach the Addon's handleGET and handlePOST functions from the Editor script now.

Any ideas how can this be still implemented? Or maybe there is a better way?

1
AFAIK, Not possible. Your add-on should do all the work(if possible). There's no merging of scripts with add-on scripts. - TheMaster
Thanks for the answer. I started thinking about that too. But today I thought I could solve the problem by creating an Addon of a Script editor code and load my Library via the manifest file as a dependency. I've also specified the webapp parameters in the manifest in order to publish web app with Addon installation. As it turned out, the web app was not deployed individually for every Spreadsheet a user enables this Addon in. Apparently, the Web App was deployed only once globally as the ScriptApp.getService().getUrl(); always showed the same url no matter what user installs the Addon. - cyxou
Another option I am now considering is loading the Library code into the Script editor via a FetchURL and evaluating. Not that elegant, but this way I won't have to bother my users with emails to update the Library and deploy new version of the Web App. - cyxou
Makes sense. Add-on is considered a single script used by many users(like a web-app used by many clients). - TheMaster
eval is a potential security loop hole. If someone was able to intercept urlFetch/change link, it'll be a nightmare. - TheMaster

1 Answers

0
votes

Having tested different options, I've decided to go the eval way:

var libUrl = 'https://example.com/my-lib-url.js';
// Load My Library from server
function loadLibrary(url: string) {
  // This line is needed only to auto detect Auth scope required for the
  // fetched library. Without this we'd have to provide the required
  // scope in the appscript.json manifest file.
  SpreadsheetApp.getActiveSpreadsheet();

  const key = 'my-lib-contents';
  const cache = CacheService.getScriptCache();
  let lib = cache.get(key);
  if (lib == null) {
    console.log('Fetching library...');
    lib = UrlFetchApp.fetch(url).getContentText();
    cache.put(key, lib, 3600); // cache for 60 minutes
  }
  eval(lib);
}

function doGet(req: any) {
  if (!Mylib.handleGET) loadLibrary(libUrl);
  return result(AccountsManager.handleGET(req));
}

function doPost(req: any) {
  if (!Mylib.handlePOST) loadLibrary(libUrl);
  return result(AccountsManager.handlePOST(req));
}