Build a real-time dashboard (web app) using google.script.run API
Polling is bad, period. Falling short of integrating web sockets, this solution comes close to streaming live data.
specifically, that's google.script.run.withSuccessHandler
& it would be unfair to talk about this without hyping up the setInterval
function (you’ll see) 😊
google.script.run
is an asynchronous client-side javascript api available in html-service pages that can call server-side apps script functions.
more about it can be found here.
context
if you’re a data buff (or are anal retentive about any kind of information), you’d also have the urge to access that information, as fast as possible. i started exploring ways to display data in real-time while solutioning* a way to show incoming-call related stats in real-time (viz. # of calls that are queued, # of agents who’re engaged/busy on a call, the # of agents who’re free to receive more/new calls etc.).
from what i was able to gather, on a typical web-server and with the usual coding languages, one could simply open live connections via web sockets on the client &/or server side to stream changes, as and when they occur. i don’t yet know if we could achieve a similar architecture with google apps script but afaik, there isn’t one.
prior reading
architecture
server-side
i know this sounds fancy but its simply your code.gs
file 😛 where you configure the functions you require, that are able to fetch data from whatever sources you’re storing them in (if any); say - sheets, bigquery etc.
client-side
its the code that runs from your *.html
file and, post loading, on your web browser.
client-side setup is rather a tricky one as you'd need to take into account the throttling limitations of external apis (if you're using any) and that of google's itself (i'm yet to figure out what that is, as there haven't been any relevant errors which could point me in that direction).
in my demo script, i've invoked google.script.run.withSuccessHandler
twice - one that runs every 10 seconds and the other, every 1 second.
codebase
you can access the entire script on my github repository here or make a copy from the original script - here.
in this dummy setup, i'm fetching random quotes from thesimpsonsquoteapi (thanks to jason luboff's post on freecodecamp.org) along with displaying a timer that changes every second.
server-side
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('Index').setTitle('Realtime Data');
}
function randomQuotes() {
var baseURL = 'https://thesimpsonsquoteapi.glitch.me/quotes';
var quotesData = UrlFetchApp.fetch(baseURL, { muteHttpExceptions: true });
var quote;
var imageURL;
if (quotesData.getResponseCode() == 200 || quotesData.getResponseCode() == 201) {
var response = quotesData.getContentText();
var data = JSON.parse(response)[0];
quote = data["quote"];
imageURL = data["image"];
} else {
quote = 'Random Quote Generator is broken!';
imageURL = 'https://cdn.shopify.com/s/files/1/1061/1924/products/Sad_Face_Emoji_large.png?v=1480481055';
}
var randomQuote = {
"quote": quote,
"imageTag": '<img class="responsive-img" src="' + imageURL + '">'
}
return randomQuote;
}
function getTime() {
var now = new Date();
return now;
}
client-side
highlighting the code pieces that matter the most.
demo
you can access a demo web app hosted on my account here & here's a visual overview -
credits
- cover image by cristian ruiz as seen on dribbble.
footnote
*solutioning: i wanted to know if this is even a real word. googled it, obviously. found this article and read something that made my day -
I hate it when people utilize paradigms inculcating contra-diminutive words for the ostensible objective of maximizing pretentiousness.