cmputernetwork

Комп'ютерні мережі та розподілені системи

13. Хмарні технології<– Лекції –> 15 Google Sheet API

14. Побудова розподілених застосунків з використанням Google Scripts

14.1. Вступ до Google Apps Scripts

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

рис.14.1. Застосунки Google Workspace

У Apps Script як і для багатьох інших реалізацій JavaScript середовище виконання містить рушій JavaScript, який аналізує та виконує код сценарію. Apps Script підтримує рушій V8, який використовують наприклад Google Chrome та Node.js.

Apps Script є універсальним. Зокрема він дозволяє:

Apps Script працює на стороні сервера, але може мати інтерфейс користувача, створений за допомогою Html, CSS, JavaScript або будь-якої іншої технології, що підтримується браузером. На відміну від Nodejs, який керується подіями, GAS працюють у потоковій моделі. Усі виклики скрипта генерують унікальний екземпляр цього скрипта, який виконується ізольовано від усіх інших екземплярів. Коли екземпляр сценарію завершує виконання, він знищується.

Функції в Apps Script блокуються, тому шаблони зворотного виклику й асинхронного програмування не потрібні. Блокування використовується, щоб запобігти одночасному виконанню критичних розділів коду, наприклад файлового вводу/виводу, різними екземплярами.

14.2. Самостійне використання Apps Script

Скрипти створюються на сторінці Google Apps Script https://script.google.com. Для роботи з цим сервісом, так само як і з більшістю інших необхідно мати обліковий запис Google. Приклад функції в GAS показаний на рис.14.2.

рис.14.2. Приклад функції в Google Apps Script

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

рис.14.3. Приклад журналу в Google Apps Script

Самостійне виконання GAS без взаємодії має мало сенсу, тому варто використовувати його разом з підключенням різноманітних сервісів через клієнтський API.

14.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().

Публікація

Після написання коду скрипт необхідно зберегти і опублікувати. Порядок публікації показаний на рис.14.4.

рис.14.4. Публікація скрипту як Веб-застосунку

Після публікації застосунку його базовий URL матиме вигляд:

https://script.google.com/macros/s/AKfyVOWxGcR9A/exec

Для перевірки роботи скрипту треба вписати в поле адреси браузера вказаний URL. Повинен з’явитися відповідно форматований текст.

Зауважте що кожна зміна коду буде приводити до необхідності публікації нового застосунку. Стара адреса буде використовуватися зі старим кодом. Так забезпечується версійність, коли старі застосунки залишаються робочими при зміні реалізації.

рис.14.5. Вибір версію скрипту

Також варто відзначити, що Google Apps Scripts пропонує два інтерфейси:

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)

Структура об’єкта події:

name=alice&n=1&n=2
{"name": "alice", "n": "1"}
{"name": ["alice"], "n": ["1", "2"]}
332
332
text/csv
Alice,21

Наприклад, можна передати такі параметри, як 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
}

14.4. Підключення сервісів Google Workspace

До Apps Scripts можна підключати інші сервіси Google. Це можна зробити натиснувши відповідну кнопку “Сервіси” (рис.14.6)

image-20231128173044809

рис.14.6. Підключення сервісу до Google Apps Scripts

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

image-20231128173357690

рис.14.7. Приклад використання підключеного сервісу Google Calendar

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

image-20231128173750960

рис.14.8. Приклад надання дозволів

14.5. Використання Apps Script в Google Sheets

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

image-20231114161640746

рис.14.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. Необхідно автентифікувати себе, та надати дозвіл на доступ (рис.14.10).

image-20221206182104694

рис.14.10. Дозвіл на доступ застосунку до Google Sheet

Після успішного виконання у вікні консолі будуть з’являтися повідомлення. Детальніше про використання Google Sheet розглянуто в наступній лекції.

14.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 і надсилання облікових даних із вашими запитами:

Для формування запиту можна користуватися різними методами. Вибір методу та інших параметрів задається у другому аргументі - 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

14.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 наведено в наступній лекції.

Контрольні питання

  1. Що таке Google Apps Scripts?
  2. Які можливості надає Google Apps Scripts?
  3. Яка особливість виконання Google Apps Scripts?
  4. Як створити GAS?
  5. Розкажіть про публікацію Apps Script як Веб-застосунків. Яким чином забезпечується підтримка нових та старих версій веб-застосунку?
  6. Які HTTP методи підтримуються Web-застосунком Google Apps Scripts?
  7. Розкажіть про використання об’єкту події у Web-застосунку Google Apps Scripts.
  8. Яким чином відбувається підключення та використання сервісів Google Workspace?
  9. Розкажіть про надання дозволів на використання сервісів Google Workspace.
  10. Розкажіть про принципи створення GAS в Google Sheets.
  11. Розкажіть про принципи створення GAS в якості клієнта API.
  12. Які можливості надають параметри функції UrlFetchApp.fetch?
  13. Розкажіть про методи серіалізації та десеріалізації JSON та XML в GAS.
  14. Які базові сервіси надаються GAS?

Корисні посилання

https://riptutorial.com/google-apps-script

Посилання на відеозаписи лекцій

Запис Л14. Побудова розподілених застосунків з використанням Google Scripts