Побудова розподілених застосунків з використанням Google Scripts : теоретична частина
1. Вступ до Google Apps Scripts
Google Apps Script (GAS) - це платформа для розробки застосунків, що дозволяє швидко та легко створювати бізнес-застосунки, які інтегруються з Google Workspace. Код пишеться на сучасному JavaScript і надається доступ до вбудованих бібліотек для застосунків Google Workspace, таких як Gmail, Календар, Диск тощо. Непотрібно нічого встановлювати — доступний редактор коду прямо у браузері, а скрипти запускаються на серверах Google.

рис.1. Застосунки Google Workspace
У Apps Script як і для багатьох інших реалізацій JavaScript середовище виконання містить рушій JavaScript, який аналізує та виконує код сценарію. Apps Script підтримує рушій V8, який використовують наприклад Google Chrome та Node.js.
Apps Script є універсальним. Зокрема він дозволяє:
- Додати користувацькі меню, діалоги та бічні панелі до Документів, Таблиць(Sheets) та Форм Google.
- Писати користувацькі функції та макроси для Google Sheets.
- Публікувати веб-застосунки - самостійно або вбудовані в Google Sites.
- Взаємодіяти з іншими сервісами Google, включаючи AdSense, Analytics, Календар, Диск, Gmail та Картами.
- Створювати add-ons для розширення Документів, Таблиць, Слайдів та форм Google і публікувати їх у магазині застосунків.
- Конвертувати Android App в Android add-on, щоб він міг обмінюватися даними з Google Doc або Листом користувача на мобільному пристрої.
- Упорядковувати робочі процеси чату Hangouts, створивши чат-бот.
Apps Script працює на стороні сервера, але може мати інтерфейс користувача, створений за допомогою Html, CSS, JavaScript або будь-якої іншої технології, що підтримується браузером. На відміну від Nodejs, який керується подіями, GAS працюють у потоковій моделі. Усі виклики скрипта генерують унікальний екземпляр цього скрипта, який виконується ізольовано від усіх інших екземплярів. Коли екземпляр сценарію завершує виконання, він знищується.
Функції в Apps Script блокуються, тому шаблони зворотного виклику й асинхронного програмування не потрібні. Блокування використовується, щоб запобігти одночасному виконанню критичних розділів коду, наприклад файлового вводу/виводу, різними екземплярами.
2. Самостійне використання Apps Script
Скрипти створюються на сторінці Google Apps Script https://script.google.com. Для роботи з цим сервісом, так само як і з більшістю інших необхідно мати обліковий запис Google. Приклад функції в GAS показаний на рис.2.

рис.2. Приклад функції в Google Apps Script
Після створення функціїї, її можна зберегти і запустити проект на виконання. Результат виконання можна передивитися у консолі журналу виконання.

рис.3. Приклад журналу в Google Apps Script
Самостійне виконання GAS без взаємодії має мало сенсу, тому варто використовувати його разом з підключенням різноманітних сервісів через клієнтський API.
3. Публікація Apps Script як Веб-застосунків
Обробка методів
Скрипт можна опублікувати як веб-застосунок. Для цього треба, щоб в скрипті були використані функції, які реалізовують методи GET через функцію doGet(e) та/або POST через функцію doPost(e). В обох випадках аргумент e представляє параметр події, який може містити інформацію про будь-які параметри запиту.
Таким чином коли скрипт публікується як веб-застосунок, кожного разу коли відбувається запит до URL-адреси скрипта - викликаються спеціальні функції зворотного виклику doGet() і doPost().
Можна оперувати як HTML змістом, повертаючи об’єкти інтерфейсу користувача, створеного за допомогою HTML service, так і використовувати Content service для повернення текстового вмісту у вигляді звичайного тексту або серіалізованого JSON, XML. Перший дозволяє реалізовувати динамічно генеровані WEB-сторінки, а другий - розробляти сервіси що надають доступ через HTTP API, відповідаючи на запити GET та POST та обслуговуючи дані різних типів MIME, що доступні 24/7.
Розглянемо простий приклад для Веб-сервісу, що генерує HTML сторінку
function doGet(e) {
return HtmlService.createHtmlOutput().setContent ('<h1>Привіт світ!</h1>');
}
У цьому випадку викликається функція doGet яка в якості вхідного аргументу отримує об’єкт e - параметр події, який може містити інформацію про будь-які параметри запиту. HTML service використаний для генерування веб-сторінки, створивши контент через метод createHtmlOutput().
Публікація
Після написання коду скрипт необхідно зберегти і опублікувати. Порядок публікації показаний на рис.4.

рис.4. Публікація скрипту як Веб-застосунку
Після публікації застосунку його базовий URL матиме вигляд:
https://script.google.com/macros/s/AKfyVOWxGcR9A/exec
Для перевірки роботи скрипту треба вписати в поле адреси браузера вказаний URL. Повинен з’явитися відповідно форматований текст.
Зауважте що кожна зміна коду буде приводити до необхідності публікації нового застосунку. Стара адреса буде використовуватися зі старим кодом. Так забезпечується версійність, коли старі застосунки залишаються робочими при зміні реалізації.

рис.5. Вибір версію скрипту
Також варто відзначити, що Google Apps Scripts пропонує два інтерфейси:
- для виконання, URL якого завершується
/execі постійно змінюється при публікації - для налагодження, URL якого завершується
/devі не змінюється при публікації; тобто дане посилання є постійним, що спрощує налагодження але доступний тільки розробникам. Його можна отримати з меню “Ввести в дію->Тестувати пакети”. Приклад такого URL:
https://script.google.com/macros/s/AKfycbzES1LxLzsgWPDm/dev
Таким чином налагоджувати веб-застосунок простіше з URL, що завершується на /dev
Можна також зробити відповідний текстовий Content. Наприклад скрипт що просто повертає текст при запиті сторінки, матиме наступний вигляд.
function doGet() {
return ContentService.createTextOutput('Привіт світ!');
}
Використовуючи ці ж об’єкти можна відповідати на запити в форматі ATOM, CSV, iCal, JavaScript, JSON, RSS, vCard, та XML.
Об’єкт події (Event parameter)
Структура об’єкта події:
e.queryString- Значення частини рядка запиту URL-адреси або значення null, якщо рядок запиту не вказано, наприклад:
name=alice&n=1&n=2
e.parameter- об’єкт з пар ключ/значення, які відповідають параметрам запиту. Для параметрів, які мають кілька значень, повертається лише перше значення, наприклад:
{"name": "alice", "n": "1"}
e.parameters- Об’єкт, подібний доe.parameter, але з масивом значень для кожного ключа
{"name": ["alice"], "n": ["1", "2"]}
-
e.pathInfo- URL-шлях після/execабо/dev. Наприклад, якщо URL-шлях закінчується на/exec/hello, інформація про шлях будеhello. -
e.contextPathНе використовується, завжди порожній рядок. -
e.contentLength- Довжина тіла запиту для запитів POST або-1для запитів GET.
332
e.postData.length- те саме щоe.contentLength
332
e.postData.type- Тип MIME тіла POST
text/csv
e.postData.contents- Текст вмісту тіла POST
Alice,21
e.postData.name- Завжди значенняpostData
Наприклад, можна передати такі параметри, як username та age до URL-адреси, як показано нижче:
https://script.google.com/.../exec?username=jsmith&age=21
Потім можна відобразити параметри так:
function doGet(e) {
var params = JSON.stringify(e);
return HtmlService.createHtmlOutput(params);
}
У наведеному вище прикладі doGet(e) повертає такий результат:
{
"queryString": "username=jsmith&age=21",
"parameter": {
"username": "jsmith",
"age": "21"
},
"contextPath": "",
"parameters": {
"username": [
"jsmith"
],
"age": [
"21"
]
},
"contentLength": -1
}
4. Підключення сервісів Google Workspace
До Apps Scripts можна підключати інші сервіси Google. Це можна зробити натиснувши відповідну кнопку “Сервіси” (рис.6)

рис.6. Підключення сервісу до Google Apps Scripts
Після добавлення можна звертатися до сервісів через означені методи. На наведеному нижче прикладі показано як в консоль виводиться перелік запланованих подій в Google Calendar.

рис.7. Приклад використання підключеного сервісу Google Calendar
При запуску скриптів, що доступаються до застосунків або сервісів Google, необхідно надавати дозволи. На рис.8 показана послідовність надання дозволів.

рис.8. Приклад надання дозволів
5. Використання Apps Script в Google Sheets
Скрипти Apps Script можуть використовуватися разом з Google Таблицями (Google Sheets). Це має те саме призначення, що і мова VBA в MS Excel . В Гугл Таблицях для нової або існуючої таблиці в меню “Інструменти - Редактор сценаріїв” створюється код, наприклад:

рис.9. Створення розширення на Apps Script
function myFunction() {
//отримати активну сторінку
let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// на активній сторінці у комірках з 1,1 виведе повідомлення
let word = "Привіт світ!";
for (i=0; i<word.length; i++){
sheet.getRange(1,i+1).setValue(word[i]);
}
}
Після збереження коду, його можна запустити на виконання. Перший запуск приведе до необхідності автентифікації, тому з’явиться повідомлення про необхідність надання доступу застосунку до Google Sheet. Необхідно автентифікувати себе, та надати дозвіл на доступ (рис.10).

рис.10. Дозвіл на доступ застосунку до Google Sheet
Після успішного виконання у вікні консолі будуть з’являтися повідомлення. Детальніше про використання Google Sheet розглянуто в наступній лекції.
6. Використання в якості клієнта API
UrlFetch
Google Apps Script може взаємодіяти з API з усього Інтернету у якості HTTP-клієнту. Для цього можна використовувати службу UrlFetch, що дає можливість надсилати запити API. Формат виклику:
fetch(url, params);
У наведеному нижче прикладі використовується API GitHub для пошуку сховищ зі 10000 або більше зірочками, у яких згадується “Apps Script” і виведення їх кількості. Цей запит API не потребує авторизації чи ключа API.
function myFunction() {
let query = '"Apps Script" stars:">=10000"'; // запит
let url = 'https://api.github.com/search/repositories' // клієнтський API github
+ '?sort=stars' // параметр сортування stars
+ '&q=' + encodeURIComponent(query); // параметр запиту
// відправка клієнтського запиту
var response = UrlFetchApp.fetch(url,{'muteHttpExceptions': true}
//muteHttpExceptions - Якщо значення true, вибірка не створює винятку,
//якщо код відповіді вказує на помилку, а натомість повертає HTTPResponse.
);
let repos = response.getContent();
console.log(repos.length);
}
API, які діють від імені користувача, зазвичай потребують авторизації, часто з використанням протоколу OAuth. Apps Script не підтримує вбудовану підтримку протоколу, але є бібліотеки з відкритим кодом, які можна використовувати для виконання потоку OAuth і надсилання облікових даних із вашими запитами:
- OAuth1 для Apps Script: сумісний із OAuth 1.0 і 1.0a.
- OAuth2 для Apps Script: сумісний з OAuth2.
Для формування запиту можна користуватися різними методами. Вибір методу та інших параметрів задається у другому аргументі - params, який містить наступні параметри:
| Назва параметру | Тип | Опис |
|---|---|---|
contentType |
String |
тип вмісту (за замовчуванням application/x-www-form-urlencoded). Іншим прикладом типу вмісту є application/xml; charset=utf-8. |
headers |
Object |
карту ключ/значення JavaScript заголовків HTTP для запиту |
method |
String |
метод HTTP для запиту: get, delete, patch, post або put. За замовченням - get. |
payload |
String |
корисне навантаження (тобто тіло POST) для запиту. Деякі методи HTTP (наприклад, GET) не приймають корисне навантаження. Це може бути рядок, масив байтів, blob (бінарні дані) або об’єкт JavaScript. Об’єкт JavaScript інтерпретується як зіставлення імен полів форми зі значеннями, де значеннями можуть бути рядки або blob. |
validateHttpsCertificates |
Boolean |
Якщо значення false, fetch ігнорує будь-які недійсні сертифікати для запитів HTTPS. За замовченням є true. |
followRedirects |
Boolean |
Якщо false, fetch не виконує автоматично перенаправлення HTTP; функція повертає оригінальну відповідь HTTP. За замовченням є true. |
muteHttpExceptions |
Boolean |
Якщо true, fetch не створює винятку, якщо код відповіді вказує на помилку, а натомість повертає HTTPResponse. За замовченням є false. |
escaping |
Boolean |
Якщо false зарезервовані символи в URL-адресі не екрануються. За замовченням є true. |
Нижче наведений приклад використання параметрів для реалізації HTTP методу POST.
// Зробити запит POST з корисним навантаженням JSON
var data = {
'name': 'Bob Smith',
'age': 35,
'pets': ['fido', 'fluffy']
};
var options = {
'method' : 'post',
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};
UrlFetchApp.fetch('https://httpbin.org/post', options);
Робота з JSON
Якщо запитуваний API повертає на запит необроблену відповідь у форматі JSON , доступ до його рядкового вигляду можна отримати за допомогою методу HTTPResponse.getContentText(). Після того, як цей рядок буде отримано, можна перетворити його в об’єкт JS за допомогою виклику JSON.parse().
// до цього моменту зроблений запит до API та отримана відповідь
var json = response.getContentText();
var data = JSON.parse(json);
Logger.log(data.title);
Так само, щоб створити рядкове представлення JSON об’єкта JavaScript можна використати JSON.stringify().
var data = {
'entry': {
'group': {
'title': 'Dog Skateboarding',
'description': 'My dog gets some serious air'
},
'keywords': 'dog, skateboard'
}
}
var payload = JSON.stringify(data);
Детальніше про JSON та роботою з ним в GAS, можна прочитати в лекції по JSON
Парсинг XML
Так само як в з JSON доступ до XML-відповіді робиться за допомогою методу HTTPResponse.getContentText().Після того, як цей рядок буде отримано, можна перетворити його в об’єкт JS за допомогою виклику XmlService.parse().
// до цього моменту зроблений запит до API та отримана відповідь
var xml = response.getContentText();
var doc = XmlService.parse(xml);
Так само, щоб створити рядкове представлення XML об’єкта JavaScript можна використати методи вбудованого об’єкту XmlService.
var root = XmlService.createElement('entry')
.setAttribute('keywords', 'dog, skateboard');
var group = XmlService.createElement('group')
.setAttribute('title', 'Dog Skateboarding');
.setAttribute('description', 'My dog gets some serious air');
root.addContent(group);
var document = XmlService.createDocument(root);
var payload = XmlService.getPrettyFormat().format(document);
Детальніше про XML та роботою з ним в GAS, можна прочитати в лекції по XML
7. Базові сервіси GAS та тригери
Базові сервіси GAS надають доступ до інформації користувача, такої як адреси електронної пошти та імена користувачів. Вони також керують журналами скриптів і діалоговими вікнами в застосунках Google Workspace. Ці сервіси надаються через класи та об’єкти, перелік яких наведений нижче.
| Клас/об’єкт | Призначення |
|---|---|
Blob |
Об’єкт обміну даними для служб Apps Script. |
BlobSource |
Інтерфейс BlobSource для об’єктів, які можуть експортувати свої дані як Blob. |
Browser |
Цей клас надає доступ до діалогових вікон, характерних для Google Таблиць. |
Button |
Перелік, що представляє заздалегідь означені локалізовані діалогові кнопки, повернуті alert або PromptResponse.getSelectedButton() , щоб вказати, яку кнопку в діалоговому вікні натиснув користувач. |
ButtonSet |
Перелік, що представляє заздалегідь означені локалізовані набори однієї або кількох діалогових кнопок, які можна додати до alert або prompt. |
ColorType |
Типи кольорів |
Logger |
Цей клас дозволяє розробнику записувати текст у журнали налагодження. |
Menu |
Спеціальне меню в екземплярі інтерфейсу користувача для програми Google. |
MimeType |
Перелік, який надає доступ до декларацій типу MIME без явного введення рядків. |
Month |
Перелік місяців року. |
PromptResponse |
Відповідь на діалогове вікно prompt , що відображається в середовищі інтерфейсу користувача для програми Google. |
RgbColor |
Колір, означений червоним, зеленим, синім кольоровими каналами. |
Session |
клас, що надає доступ до інформації про сеанс, такої як адреса електронної пошти користувача (у деяких випадках) і налаштування мови. |
Ui |
Екземпляр середовища інтерфейсу користувача для програми Google, який дозволяє сценарію додавати такі функції, як меню, діалогові вікна та бічні панелі. |
User |
Представлення користувача, придатне для скрипту. |
Weekday |
Перелік, що представляє дні тижня. |
console |
Цей клас дозволяє розробнику записувати журнали до служби Stackdriver Logging від Google Cloud Platform. |
Детальний опис цих сервісів доступний за посиланням.
GAS надає можливість запускати функції за певними подіями. Це можуть бути вже наведені функції doGet та doPost , які запускаються при отриманні відповідного HTTP-запиту від клієнту, або вбудовані тригери у застосунки Google, або таймерні тригери, які налаштовуються в GAS. Детальніше про використання тригерів в Google Sheet наведено в наступній лекції.
Контрольні питання
- Що таке Google Apps Scripts?
- Які можливості надає Google Apps Scripts?
- Яка особливість виконання Google Apps Scripts?
- Як створити GAS?
- Розкажіть про публікацію Apps Script як Веб-застосунків. Яким чином забезпечується підтримка нових та старих версій веб-застосунку?
- Які HTTP методи підтримуються Web-застосунком Google Apps Scripts?
- Розкажіть про використання об’єкту події у Web-застосунку Google Apps Scripts.
- Яким чином відбувається підключення та використання сервісів Google Workspace?
- Розкажіть про надання дозволів на використання сервісів Google Workspace.
- Розкажіть про принципи створення GAS в Google Sheets.
- Розкажіть про принципи створення GAS в якості клієнта API.
- Які можливості надають параметри функції
UrlFetchApp.fetch? - Розкажіть про методи серіалізації та десеріалізації JSON та XML в GAS.
- Які базові сервіси надаються GAS?
Корисні посилання
https://riptutorial.com/google-apps-script
Посилання на відеозаписи лекцій
Запис Л14. Побудова розподілених застосунків з використанням Google Scripts
Автор
Теоретичне заняття розробив Олександр Пупена.
Feedback
Якщо Ви хочете залишити коментар у Вас є наступні варіанти:
Про проект і можливість допомогти проекту написано тут