A documented restriction with document and sheet add-ons is that Apps Script cannot tell what a user does outside of the add-on. This tantalizing tip is given:
It is possible to poll for changes in a file's contents from a sidebar's client-side code, although you'll always have a slight delay. That technique can also alert your script to changes in the user's selected cells (in Sheets) and cursor or selection (in Docs).
Sadly, this isn't shown in any of the demo code. How can I do it?
The polling is done from the html code in your add-on's User Interface, calling across to server-side Apps Script functions using
google.script.run
.Using jQuery simplifies this, and we can even start with the answers from jQuery, simple polling example.
The basic idea can work for Google Apps Script, if we replace the ajax calls with the GAS equivalents.
Here's the skeleton of the poll function that you would use in your html file:
Add-on Example, Document Poller
This is a demonstration of the jQuery polling technique calling server-side Google Apps Script functions to detect user behavior in a Google Document. It does nothing useful, but it showcases a few things that would typically require knowledge of the user's activity and state of the document, for instance context-sensitve control over a button.
The same principle could apply to a spreadsheet, or a stand-alone GAS Web Application.
Like the UI App example in this question, this technique could be used to get around execution time limits, for operations with a User Interface at least.
The code builds upon the example add-on from Google's 5-minute quickstart. Follow the instructions from that guide, using the code below instead of that in the quickstart.
Code.gs
Sidebar.html
Polling Interval
The
setTimeout()
function accepts a time interval expressed in milliseconds, but I found through experimentation that a two-second response was the best that could be expected. Therefore, the skeletonpoll()
has a 2000ms interval as its default. If your situation can tolerate a longer delay between poll cycles, then provide a larger value with the onLoad call topoll()
, e.g.poll(10000)
for a 10-second poll cycle.Sheets
For a sheet example see How do I make a Sidebar display values from cells?