[Примеры, Google Apps Script] Разработка дополнений/скриптов для Google Таблиц (spreadsheets)
Документация по Google Apps Script (Гугл скрипты): https://developers.google.com/apps-script/.
Лимиты при использовании Google Script: https://docs.google.com/macros/dashboard.
Скрипты: https://script.google.com/home.
Триггеры: https://developers.google.com/apps-script/guides/triggers/.
Примеры работы с Google Apps Script на английском: https://ctrlq.org/code.
Введение в работу с Google Apps Script: GAS — С чего начать изучение? и О редакторе сценариев.
Библиотека для работы с OAuth2: https://github.com/gsuitedevs/apps-script-oauth2.
Содержание:
- Что есть что
- Добавление новых пунктов в меню Гугл.Таблицы
- Работа с классами SpreadsheetApp, Spreadsheet и Sheet на Google Apps Script
- Работа с классом Range
- Работа с классом UrlFetchApp (отправка GET/POST запросов, парсинг данных)
- Работа с классами DriveApp, Folder и File (создание/удаление папок/файлов на Google Drive)
- Работа с классом MailApp (отправка писем)
- Работа с триггером onEdit (реакция на изменения в таблице) и классом LanguageApp (перевод текста в Google Spreadsheets)
- Работа с диалоговыми окнами (ui.alert, ui.prompt) на Google Apps Script
- Работа с HTML Service (вывод модального окна и сайдбара в Google Spreadsheets)
- Работа с классом GmailApp
1. Что есть что
spreadsheetId — ID таблицы (файла)
sheetId — ID листа (Лист3)
DataRange — диапазон ячеек, в которых присутствуют данные
ActiveRange — выделенный диапазон ячеек (например, выделенный мышью)
2. Добавление новых пунктов в меню Гугл.Таблицы
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Функция onOpen() запускается всегда при открытии документа // https://developers.google.com/apps-script/guides/triggers/#onopen function onOpen() { // Создаём новое меню // https://developers.google.com/apps-script/reference/base/ui#createmenucaption SpreadsheetApp.getUi() .createMenu('Моё меню') .addItem('Элемент 1', 'myFunction1') .addSeparator() .addSubMenu(SpreadsheetApp.getUi().createMenu('Подменю') .addItem('Элемент 2', 'myFunction2') .addItem('Элемент 3', 'myFunction3')) .addSeparator() .addItem('Элемент 4', 'myFunction4') .addToUi(); // myFunction1, myFunction2, myFunction3 - функции, которые вызываются при нажатии на элемент меню // Добавляем новые пункты в меню "Дополнения" // https://developers.google.com/apps-script/reference/base/ui#createaddonmenu SpreadsheetApp.getUi() .createAddonMenu() .addItem('Открыть сайдбар', 'openSidebar') .addItem('Открыть модальное окно', 'openModal') .addToUi(); // 'Открыть сайдбар' - название пункта меню // 'openSidebar' - функция, которая сработает при нажатии на этот пункт } |
3. Работа с классами SpreadsheetApp, Spreadsheet и Sheet на Google Apps Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function myFunction1() { // Получаем объект с таблицей по URL // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#openbyurlurl var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/12FZqzgh0BAs94UUgi9j3l_1y_kHk7pL6iYyluUx8464/edit'); // Записываем в журнал название, полученной таблицы // В журнал будет добавлена запись "Примеры". // Записи журнала можно посмотреть в редакторе скриптов, выбрав в меню "Просмотр - Журналы" // https://developers.google.com/apps-script/reference/base/logger Logger.log(ss.getName()); // Получаем объект с таблицей по ID // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet-app#openbyidid var ss = SpreadsheetApp.openById('12FZqzgh0BAs94UUgi9j3l_1y_kHk7pL6iYyluUx8464'); // Записываем в журнал URL таблицы Logger.log(ss.getUrl()); // Получаем объект с активной (открытой в данный момент) таблицей var ss = SpreadsheetApp.getActiveSpreadsheet(); // Записываем в журнал ID таблицы Logger.log(ss.getId()); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
function myFunction2() { // Получаем объект с активной (открытой в данный момент) таблицей var ss = SpreadsheetApp.getActiveSpreadsheet(); // Объект со списком всех листов в документе // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheets var sheetsList = ss.getSheets(); for (var i = 0; i < sheetsList.length; i++) { // Объект с листом // https://developers.google.com/apps-script/reference/spreadsheet/sheet var sheet = sheetsList[i]; // Получаем ID листа // https://developers.google.com/apps-script/reference/spreadsheet/sheet#getsheetid var sheetId = sheet.getSheetId(); Logger.log('ID:' + sheetId.toString()); // Получаем название листа // https://developers.google.com/apps-script/reference/spreadsheet/sheet#getsheetname var sheetName = sheet.getSheetName(); Logger.log('Name:' + sheetName); // Получаем позицию последней заполненной строки var lastRowIndex = sheet.getLastRow(); Logger.log('lastRowIndex: ' + lastRowIndex); // Получаем позицию последней заполненной колонки // https://developers.google.com/apps-script/reference/spreadsheet/sheet#getlastcolumn var lastColumnIndex = sheet.getLastColumn(); Logger.log('lastColumnIndex: ' + lastColumnIndex); if (lastRowIndex > 0 && lastColumnIndex > 0) { // Получаем всё содержимое листа в виде массива // https://developers.google.com/apps-script/reference/spreadsheet/sheet#getsheetvaluesstartrow-startcolumn-numrows-numcolumns var sheetValues = sheet.getSheetValues( 1, // startRow 1, // startColumn lastRowIndex, // numRows lastColumnIndex); // numColumns Logger.log(sheetValues); } // Второй вариант получения всего содержимого листа в виде массива var range = sheet.getDataRange(); var sheetValues = range.getValues(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
function myFunction3() { var ss = SpreadsheetApp.getActiveSpreadsheet(); // Получаем объект с листом по имени листа // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheetbynamename var sheet = ss.getSheetByName('Лист1'); // Изменяем название листа sheet.setName('Список игроков'); // Скрываем колонку C // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#hidecolumncolumn var range = sheet.getRange("C1"); sheet.hideColumn(range); // Скрываем строку 4 var range = sheet.getRange("A4"); sheet.hideRow(range); // Получаем ширину колонки B // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getcolumnwidthcolumnposition Logger.log(sheet.getColumnWidth( 2 // Номер колонки )); // Устанавливаем ширину колонки B равной 300px // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#setcolumnwidthcolumnposition-width sheet.setColumnWidth( 2, // Номер колонки 300 // Ширина ); } |
4. Работа с классом Range
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
function myFunction4() { var ss = SpreadsheetApp.getActiveSpreadsheet(); // Получаем объект с диапазоном ячеек // https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getrangea1notation var range = ss.getRange("Список игроков!A1:D4"); var sheet = ss.getSheetByName('Список игроков'); var range = sheet.getRange('A1:D4'); // Массив с содержимым ячеек, воходящих в диапазон // https://developers.google.com/apps-script/reference/spreadsheet/range#getvalues var values = range.getValues(); Logger.log(values); // Значение одной ячейки // https://developers.google.com/apps-script/reference/spreadsheet/range#getValue() var value = sheet.getRange('B3').getValue(); Logger.log(value); // Устанавливаем значение одной ячейки // https://developers.google.com/apps-script/reference/spreadsheet/range#setvaluevalue var cell = sheet.getRange("E1"); cell.setValue('Новый рейтинг'); sheet.getRange("F1").setValue('Разряд'); // Устанавливаем значения для диапазона ячеек // https://developers.google.com/apps-script/reference/spreadsheet/range#setvaluesvalues var range = sheet.getRange("E2:F5"); range.setValues([ [1037, '1 юн'], [1237, '2 юн'], [1637, '4 юн'], [137, '2 юн'] ]); // Устанавливаем формат отображения данных // https://developers.google.com/apps-script/reference/spreadsheet/range#setNumberFormat(String) sheet.getRange("E2").setNumberFormat("+#[Green];-#[Red];+0[Green]"); sheet.getRange("E3").setNumberFormat("#,##0_);(#,##0)"); sheet.getRange("E4").setNumberFormat("#,##0.00"); // Устанавливаем фон ячеек // sheet.getRange("A1:F1").setBackground("#1CFF4C"); // Устанавливаем цвет текста // https://developers.google.com/apps-script/reference/spreadsheet/range#setfontcolorcolor sheet.getRange("A1:F1").setFontColor("red"); // Устанавливаем выравнивание текста по центру // https://developers.google.com/apps-script/reference/spreadsheet/range#sethorizontalalignmentalignment sheet.getRange("A1:F1").setHorizontalAlignment('center'); // Объединяем ячейки // https://developers.google.com/apps-script/reference/spreadsheet/range#merge sheet.getRange("F1:G1").merge(); } |
5. Работа с классом UrlFetchApp (отправка GET/POST запросов, парсинг данных)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
// Вариант 1. Используется метод UrlFetchApp.fetch function myFunction5_1() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('habr'); var values = sheet.getDataRange().getValues(); for (var i = 1; i < values.length; i++) { var url = values[i][0]; // https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app // Загружаем страницу по указанному url var response = UrlFetchApp.fetch(url, { 'muteHttpExceptions': true, // Не выбрасывать исключения, если код ответа != 200 'validateHttpsCertificates': false, // Игнорировать невалидные сертификаты при HTTPS запросах }); // https://developers.google.com/apps-script/reference/url-fetch/http-response var responseCode = response.getResponseCode(); // Код ответа сервера var content = response.getContentText(); // Получаем html код страницы if (responseCode === 200) { // Получаем название поста var title = content.match(/title>(.*?)\</)[1]; // Вставляем название в таблицу sheet.getRange( i + 1, // номер строки 2 // номер столбца ).setValue(title); } } } // Вариант 2. Используется метод UrlFetchApp.fetchAll // Плюсы - работает быстрее // Минусы - если какая-либо страница не доступна будет выброшено исключение и работа скрипта будет завершена // (Exception: Ошибка DNS: http://... Exception: Адрес недоступен:http://... Exception: Время ожидания ответа: http://...) function myFunction5_2() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('habr'); var values = sheet.getDataRange().getValues(); var requestsList = []; // Массив запросов for (var i = 1; i < values.length; i++) { var url = values[i][0]; requestsList.push({ 'url': url, 'method': 'get', 'muteHttpExceptions': true, 'validateHttpsCertificates': false, }); } var responseList = UrlFetchApp.fetchAll(requestsList); for (i in responseList) { var response = responseList[i]; // https://developers.google.com/apps-script/reference/url-fetch/http-response var responseCode = response.getResponseCode(); // Код ответа сервера var content = response.getContentText(); // Получаем html код страницы if (responseCode === 200) { // Получаем название поста var title = content.match(/title>(.*?)\</)[1]; // Вставляем название в таблицу sheet.getRange(parseInt(i) + 2, 2).setValue(title); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// Отправка простого GET-запроса // https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl var url = 'https://api-metrika.yandex.ru/stat/v1/data.json'; var resData = UrlFetchApp.fetch(url); // Получаем ответ от сервера в виде строки var resDataJson = JSON.parse(resData); // Парсим строку в json-объект // Отправка POST-запроса с передачей дополнительных параметров // https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl-params var url = 'https://www.googleapis.com/webmasters/v3/sites/'; var options = { "headers": {'Authorization': 'Bearer 545435ghrth5h54h45'}, // Заголовки запроса "method": 'POST', // Метод - POST "payload": JSON.stringify({ // Тело запроса "startDate": '2018-03-21', "endDate": '2018-04-15' }), "contentType": 'application/json' }; var resData = UrlFetchApp.fetch(url, options); // Получаем ответ от сервера в виде строки // Парсим строку в XML-объект // https://developers.google.com/apps-script/reference/xml-service/xml-service var resDataXml = XmlService.parse(resData); |
Парсинг заголовков сайтов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
function parser() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName('list'); var values = sheet.getDataRange().getValues(); var insertError = function(msg, numRow) { sheet.getRange(numRow, 2).setValue('ОШИБКА! ' + msg).setBackground('red'); } var rowNumStart = 1; // Номер строки, с которой необходимо начать парсинг for (var i = rowNumStart; i < values.length; i++) { var url = values[i][0]; try { var response = UrlFetchApp.fetch(url, { 'muteHttpExceptions': true, 'validateHttpsCertificates': false, 'followRedirects': true, }); // Загружаем страницу по указанному url } catch(e) { insertError(e, i+1); continue; } // https://developers.google.com/apps-script/reference/url-fetch/http-response var responseCode = response.getResponseCode(); // Код ответа сервера if (responseCode === 200) { try { var headers = response.getHeaders(); var charset = headers['Content-Type'].match(/charset=(.*)$/)[1].replace(/[";]+/gi, ''); // Кодировка страницы } catch (e) { var contentForCharset = response.getContentText(); var charsetMatch = contentForCharset.match(/charset=(.*?)"/); var charset = (charsetMatch !== null) ? charsetMatch[1] : "UTF-8"; } var content = response.getContentText(charset); // Получаем html код страницы // Получаем название поста var titleMatch = content.match(/<title[^>]*>\s*([\s\S]*?)\s*</); if (titleMatch !== null) { var title = titleMatch[1]; // Вставляем название в таблицу sheet.getRange(i+1,2).setValue(title); } else { insertError('Не удалось распарсить title.', i+1); } } else { insertError('Код ответа сервера != 200.', i+1); } } } |
6. Работа с классами DriveApp, Folder и File (создание/удаление папок/файлов на Google Drive)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function myFunction7() { // Получаем все папки, расположенные на Гугл.Диске // https://developers.google.com/apps-script/reference/drive/drive-app var folders = DriveApp.getFolders(); while (folders.hasNext()) { var folder = folders.next(); // ID папки // https://developers.google.com/apps-script/reference/drive/folder#getid var folderId = folder.getId(); Logger.log('ID: ' + folderId); // Название папки // https://developers.google.com/apps-script/reference/drive/folder#getname var folderName = folder.getName(); Logger.log('Name: ' + folderName); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function myFunction8() { // Получаем объект с папкой по её ID // https://developers.google.com/apps-script/reference/drive/drive-app#getfolderbyidid var folder = DriveApp.getFolderById('1ADJG66xybO63YHHhtLZBc0zGpH2P7xJI'); // Получаем объект с папкой по её названию // https://developers.google.com/apps-script/reference/drive/drive-app#getfoldersbynamename var folders = DriveApp.getFoldersByName('tests'); var folder; while (folders.hasNext()) { folder = folders.next(); } // Получаем список файлов в папке // https://developers.google.com/apps-script/reference/drive/folder#getfiles var files = folder.getFiles(); while (files.hasNext()) { var file = files.next(); // ID файла // https://developers.google.com/apps-script/reference/drive/folder#getid var fileId = file.getId(); Logger.log(fileId); // Название файла // https://developers.google.com/apps-script/reference/drive/folder#getname var fileName = file.getName(); Logger.log(fileName); // URL файла // https://developers.google.com/apps-script/reference/drive/folder#geturl var fileUrl = file.getUrl(); Logger.log(fileUrl); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
function myFunction9() { // Получаем объект с папкой по её ID var folder = DriveApp.getFolderById('1ADJG66xybO63YHHhtLZBc0zGpH2P7xJI'); // Создаём новую папку // https://developers.google.com/apps-script/reference/drive/folder#createfoldername var folderForPdf = folder.createFolder('PDF файлы'); // Получаем объект с открытой таблицей var ss = SpreadsheetApp.getActiveSpreadsheet(); var ssId = ss.getId(); // ID таблицы // Получаем объект с файлом открытой таблицы var fileSheet = DriveApp.getFileById(ssId); // Создаём PDF файл и сохраняем его в новой папке var pdfBlob = fileSheet.getBlob().getAs('application/pdf'); var pdfFile = folderForPdf.createFile(pdfBlob); // Получаем URL, созданного файла var pdfFileUrl = pdfFile.getUrl(); Logger.log(pdfFileUrl); } |
7. Работа с классом MailApp (отправка писем)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
function myFunction10() { // https://developers.google.com/apps-script/reference/mail/mail-app // Отправляем простое письмо MailApp.sendEmail({ to: 'mymail@gmail.com', // Email получателя письма subject: 'Тема письма', body: "Line 1\r\nLine 2\r\nLine 3", // Содержимое письма }); // Отправляем письмо с прикрепленным файлом // 1bPpy2Mm7sAffcZwSvuxOooPfrhfEWuE2 - ID Pdf файла, хранящегося на гугл диске var pdfFileBlob = DriveApp.getFileById( '1bPpy2Mm7sAffcZwSvuxOooPfrhfEWuE2' ).getBlob(); MailApp.sendEmail({ to: 'mymail@gmail.com', // Email получателя письма subject: 'Тема письма 2', body: "Line 1\r\nLine 2\r\nLine 3", // Содержимое письма // Прикрепляем файл attachments: [pdfFileBlob] }); } |
8. Работа с триггером onEdit (реакция на изменения в таблице) и классом LanguageApp (перевод текста в Google Spreadsheets)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// Функция onEdit является триггером, который срабатывает при завершении ввода данных в ячейку Таблицы пользователем // https://developers.google.com/apps-script/guides/triggers/#onedite function onEdit(e) { Logger.log(e); // Получаем диапазон ячеек, в которых произошли изменения // https://developers.google.com/apps-script/reference/spreadsheet/range var range = e.range; // Лист, на котором производились изменения // https://developers.google.com/apps-script/reference/spreadsheet/sheet var sheet = range.getSheet(); // Проверяем, нужный ли это нам лист Logger.log(sheet.getName()); if (sheet.getName() != 'Перевод текста') { return false; } // Переводить необходимо текст, введённый только в первую колонку. // Проверяем стартовую позицию диапазона Logger.log(range.getColumn()); if (range.getColumn() != 1) { return false; } for (var i = 1; i <= range.getNumRows(); i++) { var cell = range.getCell( i, // номер строки 1 // номер колонки ); // Получаем текст на русском var russianText = cell.getValue(); // Переводим текст на английский // https://developers.google.com/apps-script/reference/language/language-app var translatedText = LanguageApp.translate( russianText, // текст 'ru', // с какого языка переводим 'en' // на какой язык переводим ); // Вставляем переведённый текст во вторую колонку sheet.getRange( cell.getRowIndex(), // номер строки 2 // номер столбца ).setValue(translatedText); } } |
9. Работа с диалоговыми окнами (ui.alert, ui.prompt) на Google Apps Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
// Функция onOpen() запускается автоматически при открытии документа // https://developers.google.com/apps-script/guides/triggers/#onopen function onOpen() { // Создаём новое меню // https://developers.google.com/apps-script/reference/base/ui#createmenucaption SpreadsheetApp.getUi() .createMenu('Custom Menu') .addItem('Show alert', 'showAlert') .addItem('Show prompt', 'showPrompt') .addToUi(); } function showAlert() { var ui = SpreadsheetApp.getUi(); // https://developers.google.com/apps-script/reference/base/ui#alerttitle-prompt-buttons var result = ui.alert( 'Подтвердите действие', // Заголовок окна 'Вы уверены, что хотите продолжить?', // Сообщение ui.ButtonSet.YES_NO // Кнопки ); if (result == ui.Button.YES) { // Пользователь нажал на "Да" // User clicked "Yes". ui.alert('Подтверждение получено.'); } else { // Пользователь нажал на "Нет" или на X (закрыл окно) ui.alert('В разрешении отказано.'); } } function showPrompt() { var ui = SpreadsheetApp.getUi(); // https://developers.google.com/apps-script/reference/base/ui#prompttitle-prompt-buttons var result = ui.prompt( 'Сообщите что-нибудь о себе!', // Заголовок 'Введите своё имя:', // Сообщение ui.ButtonSet.OK_CANCEL // Кнопки ); var button = result.getSelectedButton(); // Кнопка, на которую нажал пользователь var text = result.getResponseText(); // Текст, который ввёл пользователь if (button == ui.Button.OK) { ui.alert('Ваше имя: ' + text + '.'); } else if (button == ui.Button.CANCEL) { ui.alert('Вы отказались вводить своё имя.'); } else if (button == ui.Button.CLOSE) { ui.alert('Вы закрыли окно.'); } } |
10. Работа с HTML Service (вывод модального окна и сайдбара в Google Spreadsheets)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// Функция onOpen() запускается всегда при открытии документа // https://developers.google.com/apps-script/guides/triggers/#onopen function onOpen() { // Создаём новое меню // https://developers.google.com/apps-script/reference/base/ui#createmenucaption SpreadsheetApp.getUi() .createMenu('Custom Menu') .addItem('Show modal dialog', 'showModalDialog') // При нажатии на этот элемент меню откроется модальное окно .addItem('Show sidebar', 'showSidebar') // При нажатии на этот элемент меню откроется сайдбар .addToUi(); } // Открытие модального окна function showModalDialog() { var modalHtml = "<code>HTML</code> код - содержимое <i>модального</i> <br> окна"; // https://developers.google.com/apps-script/reference/html/html-service#createhtmloutputhtml var htmlOutput = HtmlService.createHtmlOutput(modalHtml) .setWidth(600) // Ширина .setHeight(100); // Высота // Альтернативный вариант - создание модального окна с содержимым из файла // https://developers.google.com/apps-script/reference/html/html-service#createHtmlOutputFromFile(String) // В этом случаем HTML код помещаем в отдельный файл (Файл - Создать - HTML файл) // var htmlOutput = HtmlService.createHtmlOutputFromFile(filenameModal); // https://developers.google.com/apps-script/reference/base/ui#showModalDialog(Object,String) SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Заголовок модального окна'); } // Открытие сайдбара function showSidebar() { var htmlOutput = HtmlService .createHtmlOutput('<p>A change of speed, a change of style...</p>') .setTitle('My add-on'); // https://developers.google.com/apps-script/reference/base/ui#showsidebaruserinterface SpreadsheetApp.getUi().showSidebar(htmlOutput); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
// Открытие сайдбара function showSidebar() { // Подключаем Bootstrap var sidebarHTML = '<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">'; // Подключаем jQuery sidebarHTML += '<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>'; // Создаём форму sidebarHTML += '<form style="padding: 20px;text-align:center;">\ <div class="form-group">\ <label for="name">Имя</label>\ <input type="text" class="form-control" id="name" name="name" value="">\ </div>\ <div class="form-group">\ <label for="abrakadabra">Какая-то абракадабра</label>\ <textarea class="form-control" id="abrakadabra" name="abrakadabra" rows="3"></textarea> \ </div>\ <div class="form-group">\ <label for="strNum">Номер строки, в которую необходимо внести данные</label>\ <input type="text" class="form-control" id="strNum" name="strNum" value="">\ </div>\ <button type="submit" class="btn btn-primary">Записать данные в таблицу</button>\ <br><br><br>\ <button type="button" id="sidebarClose" class="btn btn-danger">Закрыть сайдбар</button>\ </form>'; // Добавляем скрипты // При сабмите формы вызываем функцию writeStrInTable() и передаём ей введённые данные // https://developers.google.com/apps-script/guides/html/reference/run // При клике на кнопку 'Закрыть сайдбар' закрываем его // https://developers.google.com/apps-script/guides/html/reference/host#close() sidebarHTML += "<script>\ $(document).on('submit', 'form', function () { \ google.script.run \ .withSuccessHandler(function (resultMsg) { \ alert(resultMsg);\ })\ .writeStrInTable(\ { name: $('#name').val(), abrakadabra: $('#abrakadabra').val(), strNum: $('#strNum').val() }\ );\ return false;\ });\ \ $('#sidebarClose').on('click', function() {\ google.script.host.close();\ });\ </script>"; var htmlOutput = HtmlService .createHtmlOutput(sidebarHTML) .setTitle('My add-on'); // https://developers.google.com/apps-script/reference/base/ui#showsidebaruserinterface SpreadsheetApp.getUi().showSidebar(htmlOutput); } function writeStrInTable(e) { var name = e.name; var abrakadabra = e.abrakadabra; var strNum = parseInt(e.strNum); // Получаем объект с активной (открытой в данный момент) таблицей var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getActiveSheet(); // Записываем полученные данные в таблицу sheet.getRange("A" + strNum).setValue(name); sheet.getRange("B" + strNum).setValue(abrakadabra); return "Всё прошло успешно!"; } |
11. Работа с классом GmailApp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
function getEmails() { // Документация по работе с классом GmailApp (Google Apps Script) // https://developers.google.com/apps-script/reference/gmail/gmail-app // Получаем цепочки писем, находящиеся в разделе "Входящие" // https://developers.google.com/apps-script/reference/gmail/gmail-app#getInboxThreads() var threads = GmailApp.getInboxThreads(); // Все поисковые операторы, которые можно использовать в Gmail // https://support.google.com/mail/answer/7190?hl=ru // Получаем цепочки писем, находящиеся в разделе "Отправленные" // https://developers.google.com/apps-script/reference/gmail/gmail-app#search(String) var threads = GmailApp.search("in:sent"); // Перебираем цепочки писем for (var t = 0; t < threads.length; t++) { // Получаем массив с письмами // https://developers.google.com/apps-script/reference/gmail/gmail-thread#getMessages() var messages = threads[t].getMessages(); // Перебираем письма for (var m = 0; m < messages.length; m++) { // https://developers.google.com/apps-script/reference/gmail/gmail-message var message = messages[m]; // Объект с сообщением var id = message.getId(); // Уникальный ID письма var fromEmail = message.getFrom().replace(/^.*</, '').replace(/>/, ''); // От кого получено письмо (Email) var toEmail = message.getTo().replace(/^.*</, '').replace(/>/, ''); // Кому отправлено письмо (Email) var date = Utilities.formatDate( message.getDate() , "GMT+3", "yyyy-MM-dd HH:mm"); // Дата var subject = message.getSubject(); // Тема письма var body = message.getPlainBody(); // Тело письма } } // Получаем цепочки, связанные с указанным адресатом var threads = GmailApp.search("from:mymail@gmail.com OR to:mymail@gmail.com"); // Получаем массив со всеми сообщениями из указанных цепочек // https://developers.google.com/apps-script/reference/gmail/gmail-app#getmessagesforthreadsthreads var messages = GmailApp.getMessagesForThreads(threads); for (var i = 0; i < messages.length; i++) { for (var m = (messages[i].length - 1); m >= 0; m--) { var message = messages[i][m]; } } } |