#HSLIDE
- Terry Brady, Georgetown University Library
- Craig Boman, University of Dayton Library
#HSLIDE
- What is Google Apps Script
- Running Sample Apps Script Examples
- Coding Google Apps Script
- JavaScript Primer
- Building a Sample Application
- Using Google Apps Script in the Library
- Brainstorming possible uses
#HSLIDE
Google Apps Script is a server-side implementation of JavaScript with access to several Google API's.
Google Apps Script Documentation
#HSLIDE
- Google Script Project on Google Drive
- Embedded in a Google Product
- Document
- Sheet
- Google Form
- Google Site
- Packaged for the Chrome Store as an Add-On
#VSLIDE
- Runnable on demand from the script editor
- Deploy-able as a web service
- Schedule-able as a trigger (time-driven)
#VSLIDE
- Runnable from a custom menu item
- Invoke-able as a spreadsheet formula
- Triggered by a user event
- onOpen()
- onEdit()
#VSLIDE
- Offered to the Public
- For Sale or For Free
- Offered to your Google Apps Domain
- Offered Privately by URL
#HSLIDE
- It is available where your users already are
- No need to introduce another login
- Sometimes a Document or a Spreadsheet provides the correct level of complexity to solve a problem
- Can be authorized to access personal Google Services (Mail, Calendar, Drive)
#VSLIDE
- Sharable using existing Google Drive sharing options
- User must authorize the specific functions that will be performed by the script
- Configurable Authorization
- Run as the user running the script
- Run as the author of the script
#HSLIDE
- App Example 1: Building a Web Service
- Saves Results to Google Drive
- App Example 2: Extending Google Sheets
- Publish from Sheets to Google Sites and Gmail
- Code Example 3: Embed Interactive HTML App
- Add an HTML Panel to Google Sheets
- Add client-side JavaScript
- Perform ISBN Lookup
#HSLIDE
- Librarians often work with text strings that look like numbers or dates
- Call numbers, Accession Numbers
- What would happen to this data (by default) in Excel or Google Sheets?
Col A, Col B, Col C
One,Preserve date as MM/DD/YYYY,01/01/2017
Two,Preserve date as YYYY-MM-DD,2017-01-01
Three,Preserve Number with leading zeros,00002222
- What happens when the data is shared?
#VSLIDE
- Load data to CSV
- Disable auto-correct in all cells
#VSLIDE
- Sample Script Project
- Select "Make a Copy" to save an editable copy
- Click "Deploy as Webapp", set the run as parameters as appropriate to you
- Copy the current web app URL
#VSLIDE
- Code.gs
- doGet() Display upload page (Index.html)
- doPost()
- Process CSV Upload, create Google Sheet
- Display a link to the generated Sheet (Response.html)
- Index.html: CSV Upload Page
- Response.html: HTML Fragment to display link to uploaded Sheets
#VSLIDE
- Open the URL you saved - calls doGet()
- Supply a CSV as a file or in the text box provided
- Upload CSV data
Col A, Col B, Col C
One,Preserve date as MM/DD/YYYY,01/01/2017
Two,Preserve date as YYYY-MM-DD,2017-01-01
Three,Preserve Number with leading zeros,00002222
- Click the link to the generated spreadsheet
#VSLIDE
#VSLIDE
#HSLIDE
- Illustrates what an application can do with Google Services
- User edits a spreadsheet
- Spreadsheet content is published by Gmail
- Spreadsheet content is published to Google Sites
#VSLIDE
- Developed for an org in which several folks had limited computer literacy
- Publish assignment updates to Google Sites daily
- Email upcoming assignments once a week (with a link to Google Sites)
#VSLIDE
- Dates in column headers (Row 1)
- Code detects the next date to publish
- Times (on a specific day) are defined in Row 2
- Roles (to be assigned) are defined in column A
#VSLIDE?image=https://github.com/terrywbrady/OnlineRota_GoogleAppsScript/raw/master/screenshots/sheet1.jpg
#VSLIDE
#VSLIDE?image=https://github.com/terrywbrady/OnlineRota_GoogleAppsScript/raw/master/screenshots/sheet2.jpg
#VSLIDE
A date trigger is also set up to send e-mail weekly
#VSLIDE?image=https://github.com/terrywbrady/OnlineRota_GoogleAppsScript/raw/master/screenshots/sheet3.jpg
#VSLIDE
Note that the sample e-mail was sent in Nov 2016
#VSLIDE
A date trigger is also set up to update Google Sites Daily
#VSLIDE?image=https://github.com/terrywbrady/OnlineRota_GoogleAppsScript/raw/master/screenshots/sheet4.jpg
#VSLIDE
Note that the sample page was updated in Nov 2016
#VSLIDE
- Sample Spreadsheet
- Select "Make a Copy" to save an editable copy
- Create a personal Google Site
- Create a page within the site named "rotasearch"
- Set a script property named "siteid" with a URL to your new site
#VSLIDE
- Make an edit
- Send email
- Optionally Publish to Google Sites.
- See the following Google Sites example
- This step will currently only work with "Classic" Google Sites
- Create a trigger to call "sendRota" on a daily basis
#VSLIDE
- Per this note, Google App Script does not yet support the new version of Google Sites
- Get the URL to your classic Google Site such as https://sites.google.com/site/code4libdemo/
- In your Google Script, add this as a Script Property named "siteid"
- If you cannot create a classic Google Site, skip this step
#VSLIDE
#VSLIDE
#VSLIDE
#VSLIDE
#VSLIDE
#VSLIDE
#VSLIDE
#HSLIDE
Before coding Google Apps Script, we will review JavaScript coding
- Online JavaScript Resources
- Offline JavaScript Tutorial
#VSLIDE
Online Resources
#VSLIDE
The following JavaScript tutorial is here in case we have limited internet access
#VSLIDE
Save the following to your desktop as test.html.
<html>
<head>
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<h1>JS Testing</h1>
<button onclick="hello()">Say Hello</button>
</body>
</html>
#VSLIDE
Save the following to your desktop as test.js.
function hello(){
alert("hello from alert");
}
#VSLIDE
Numbers can be assigned to a variable or computed by function.
var count = 0;
function hello(){
count = count + 1;
alert("hello from alert :" + count);
}
#VSLIDE
Strings are assigned by enclosing them with quotes.
function hello(){
var name = "my friend";
alert("hello from alert :" + name);
}
#VSLIDE
function hello(){
//assign multiple values in brackets
var arr = ["cat", "dog", "bird"];
//reference values by position in brackets, starting with zero
alert("First item: " + arr[0] + ". All items: " + arr.join(","));
}
#VSLIDE
function hello(){
//assign properties within curly braces
var president = {first: "George", last: "Washington"};
//reference simple properties with a period
alert("Hello President " + president.last);
}
#VSLIDE
function hello(){
//complex property names must be quoted
var president = {"first-name": "George", "last-name": "Washington"};
//complex property names are referenced within brackets
alert("Hello President " + president["last-name"]);
}
#VSLIDE
//declare a function
function greeting(){
return "Greetings";
}
function hello(){
//call a function by adding parentheses
alert(greeting());
}
#VSLIDE
//function parameters are declared inside parentheses
function greeting(name){
return "Greetings, " + name;
}
function hello(){
//function parameters are passed inside parentheses
alert(greeting("Friend"));
}
#VSLIDE
function hello(){
var president = {
first: "George",
last: "Washington",
//object can contain functions
respond: function() {return "Call me " + this.first;}
};
//functions within an object can be called
alert(president.respond());
}
#VSLIDE
Add the following to your html header
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
Add the following to your html body
<input id="myname" type="text"/>
#VSLIDE
JQuery makes it easy to refernce input fields on a page regardless of your browser.
function greeting(name){
return "Greetings, " + name;
}
function hello(){
//$ is used to call a JQuery function
//"#myname" looks for a field with id="myname"
//.val() returns the value supplied by the user
var name=$("#myname").val();
alert(greeting(name));
}
#HSLIDE
- Create an application in Google Sheets that looks up ISBN numbers and returns book titles
#VSLIDE
We will build the sample ISBN lookup app in 6 parts
- 3A: Simulated ISBN Lookup
- 3B: Lookup ISBN with Google Books API
- 3C: Display Lookup Results with Google Sheets UI
- 3D: Display a static HTML panel
- 3E: Display a Templated HTML panel (with lookup results)
- 3F: Display an Interactive HTML panel (to lookup results)
#HSLIDE
Create a Google Sheet with the following data
ISBN | Google Books Lookup |
---|---|
9780141977263 | |
9780590328197 |
#VSLIDE
- Tools -> Script Editor
- This will open up the Apps Script Cloud IDE
#VSLIDE
function isbnLookup(id) {
return "Sample ISBN Lookup " + id;
}
function test() {
var isbn = "9780141977263";
var title = isbnLookup(isbn)
var msg = "The title for ISBN " + isbn + " is " + title;
Logger.log(msg);
}
#VSLIDE
Name the project something like "Test Project"
#VSLIDE
From the "Select function" drop down, select "test" and click the "Run" or "Debug" button
#VSLIDE
Click "View Logs" to confirm that the function ran.
#VSLIDE
#VSLIDE
Modify cell B2 to contain the following formula
=isbnLookup(A2)
Copy cell B2 into cell B3 to create the following formula
=isbnLookup(A3)
#VSLIDE
#VSLIDE
#HSLIDE
- Google Apps Script API Reference for UrlFetchApp
- Update the isbnLookup function to use the Google Books API to lookup the isbn
#VSLIDE
function isbnLookup(id) {
var url = "https://www.googleapis.com/books/v1/volumes?country=US&q=isbn:"+id+getApiKey();
var options = {contentType : "application/json"};
var resp = UrlFetchApp.fetch(url, options);
if (resp == null || resp == "") return "N/A";
var respdata = JSON.parse(resp.getContentText());
if (respdata["items"] == undefined) return "Not found";
if (respdata["items"].length == 0) return "Not found";
var data = respdata["items"][0]["volumeInfo"];
return (data["subtitle"] == undefined) ?
data["title"] : data["title"] + ": " + data["subtitle"];
}
#VSLIDE
Without an API key, Google may throttle your requests
function getApiKey() {
//Request a booksapi key from Google
//Set a script property using File->Project Properties->Script Properties
var key = PropertiesService.getScriptProperties().getProperty("booksapi");
//Logger.log(key);
return key == undefined ? "" : "&key="+key;
}
#VSLIDE
- The first time you run this, you will need to authorize Google Apps to send data to an external URL
#VSLIDE
#VSLIDE
#HSLIDE
- Add Menu to Google Sheets
function onOpen(e) {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem("Test Function", "test")
.addToUi();
}
#VSLIDE
#VSLIDE
Modify the test() function to access the Spreadsheet UI
function test() {
var isbn = "0764506331";
var title = isbnLookup(isbn)
var msg = "The title for ISBN " + isbn + " is " + title;
Logger.log(msg);
SpreadsheetApp.getUi().alert(msg);
}
#VSLIDE
#VSLIDE
#HSLIDE
In the script IDE, create "Sidebar.html"
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Sample HTML Panel in Google Sheets</h2>
<div>We will use this panel to add additional features to the Spreadsheet</div>
</body>
</html>
#VSLIDE
#VSLIDE
Create a function showSidebar()
function showSidebar() {
var html = HtmlService.createHtmlOutputFromFile("Sidebar.html");
SpreadsheetApp.getUi().showSidebar(html);
}
#VSLIDE
Add showSidebar() to the Add On Menu
function onOpen(e) {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem("Test Function", "test")
.addItem("Show Sidebar", "showSidebar")
.addToUi();
}
#VSLIDE
#VSLIDE
#VSLIDE
#HSLIDE
A template can take an interpret values passed to the template.
- In the script IDE, create "Template.html"
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>Sample HTML Panel in Google Sheets</h2>
<div>The title for ISBN <?=isbn?>: <?=title?></div>
</body>
</html>
#VSLIDE
Create a function showSidebarTemplate() which passes data to a template
function showSidebarTemplate() {
var t = HtmlService.createTemplateFromFile("Template.html");
t.isbn = "0596517742";
t.title = isbnLookup(t.isbn);
var html = t.evaluate();
SpreadsheetApp.getUi().showSidebar(html);
}
#VSLIDE
Add a call to showSidebarTemplate() to the Add On Menu
function onOpen(e) {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem("Test Function", "test")
.addItem("Show Sidebar", "showSidebar")
.addItem("Show Template", "showSidebarTemplate")
.addToUi();
}
#VSLIDE
#VSLIDE
#VSLIDE
#HSLIDE
Your client JavaScript can invoke server-side methods using google.script.run
- In the script IDE, create a new html file named "SidebarWithClientJS.html"
#VSLIDE HTML File With Client JS: SidebarWithClientJS.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- Client JavaScript Goes Here (See Next Slide) -->
</head>
<body>
<!-- HTML Body Goes Here (See 2 slides ahead) -->
</body>
</html>
#VSLIDE HTML Body (Will be Modified by JS)
<h2>Sample HTML Panel in Google Sheets</h2>
<div>
The title for ISBN
<input id="isbn" type="text" size="14"/>:
<textarea id="booktitle" rows="5" cols="35">--</textarea>
</div>
#VSLIDE Client JavaScript Overview
- Ready function $(function()) is called on page load
- onBlur() event added to ISBN
- User enters a value into ISBN
- onBlur() is called
- BOOKTITLE is cleared
- The value entered into ISBN is passed to the server-side function isbnLookup()
- If successful, showValue() will be invoked
- BOOKTITLE is updated with the title
- If successful, showValue() will be invoked
#VSLIDE Client JavaScript
<script>
function showValue(data) {
$("#booktitle").val(data);
}
$(function(){
$("#isbn").on("blur", function(){
$("#booktitle").val("");
google.script.run.withSuccessHandler(showValue)
.isbnLookup($("#isbn").val());
});
});
</script>
#VSLIDE Complete File (For Copy/Paste)
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function showValue(data) {
$("#booktitle").val(data);
}
$(function(){
$("#isbn").on("blur", function(){
$("#booktitle").val("");
google.script.run.withSuccessHandler(showValue)
.isbnLookup($("#isbn").val());
});
});
</script>
</head>
<body>
<h2>Sample HTML Panel in Google Sheets</h2>
<div>
The title for ISBN
<input id="isbn" type="text" size="14"/>:
<textarea id="booktitle" rows="5" cols="35">--</textarea>
</div>
</body>
</html>
#VSLIDE
Create a function showSidebarWithClientJS()
function showSidebarWithClientJS() {
var html = HtmlService.createHtmlOutputFromFile("SidebarWithClientJS.html");
SpreadsheetApp.getUi().showSidebar(html);
}
#VSLIDE
Add a call to showSidebarWithClientJS() to the Add On Menu
function onOpen(e) {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem("Test Function", "test")
.addItem("Show Sidebar", "showSidebar")
.addItem("Show Template", "showSidebarTemplate")
.addItem("Show Sidebar With Client JS", "showSidebarWithClientJS")
.addToUi();
}
#VSLIDE
#VSLIDE
An onBlur event is bound to the ISBN field.
#VSLIDE
The title field is updated after entering an ISBN.
#VSLIDE
#HSLIDE
- When installing an onOpen() trigger or other special triggers some restrictions apply to what your script can do
- You may need to simplify the actions performed with a trigger and defer them to a user-driven action
- If you see unexpected behavior in your scripts, evaluate if one of these restrictions has applied
#HSLIDE
#HSLIDE
- Creating a Google Doc Add-On Example
- Templated HTML
- Calling Server Side Functions from Client JavaScript
#HSLIDE
- How are Google Apps used in your library?
- Where could Google Apps be useful?
- What Common Extensions would be of use to Code4Lib?
- Would this group like to initiate a project together?
#HSLIDE
- Terry Brady, Georgetown University Library
- Craig Boman, University of Dayton Library