Что такое Google Apps Script и для чего он нужен?
Google Apps Script (GAS) — это облачная платформа для разработки на JavaScript, позволяющая расширять функциональность приложений Google Workspace (Sheets, Docs, Forms, Gmail, Calendar и др.) и автоматизировать рабочие процессы. GAS предоставляет удобный способ интеграции различных сервисов Google и внешних API без необходимости развертывания собственной инфраструктуры.
Основная цель GAS — упростить создание кастомных решений, которые взаимодействуют с экосистемой Google. Это может быть автоматизация рутинных задач, создание пользовательских меню и интерфейсов, обработка данных, генерация отчетов, интеграция со сторонними сервисами и многое другое.
Преимущества использования Google Apps Script
- Интеграция: Глубокая интеграция с сервисами Google Workspace «из коробки».
- Простота: Основан на JavaScript, что делает его доступным для широкого круга разработчиков. Не требует управления серверами.
- Бесплатность: Большинство квот и возможностей доступны бесплатно в рамках стандартных аккаунтов Google.
- Расширяемость: Возможность подключения к внешним API и базам данных через JDBC или UrlFetch Service.
- Автоматизация: Мощные триггеры (по времени, по событиям) для запуска скриптов.
Настройка среды разработки: редактор скриптов Google
Для начала работы не требуется установка дополнительного ПО. Редактор скриптов доступен непосредственно из приложений Google Workspace (например, в Google Sheets: «Расширения» -> «Apps Script»).
Редактор предоставляет базовые функции: подсветку синтаксиса, автодополнение (с учетом типов через JSDoc), отладчик, управление версиями и развертыванием. Современный редактор поддерживает функции, схожие с VS Code, включая улучшенное автодополнение и проверку кода.
Первый скрипт: основы синтаксиса и структуры
Скрипты GAS пишутся на JavaScript (поддерживается синтаксис ES6+). Каждый скрипт состоит из одного или нескольких файлов .gs. Функции в этих файлах могут вызываться вручную, через триггеры или из пользовательского интерфейса.
/**
* Записывает приветственное сообщение в лог.
* @param {string} name Имя для приветствия.
* @returns {void}
*/
function logGreeting(name: string): void {
const message: string = `Привет, ${name}! Добро пожаловать в Google Apps Script.`;
Logger.log(message); // Вывод в лог выполнения (Ctrl+Enter или Cmd+Enter)
}
/**
* Основная функция для демонстрации.
*/
function runExample(): void {
logGreeting('Разработчик');
}
Работа с Google Sheets
Чтение и запись данных в таблицы Google
Сервис SpreadsheetApp является точкой входа для взаимодействия с Google Sheets. Он позволяет получать доступ к активной таблице, конкретным листам, диапазонам ячеек и их значениям.
/**
* Читает данные из указанного диапазона листа.
* @param {string} sheetName Имя листа.
* @param {string} rangeA1 Диапазон в нотации A1 (например, "A1:C10").
* @returns {any[][]} Двумерный массив со значениями ячеек.
*/
function readSheetData(sheetName: string, rangeA1: string): any[][] {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
if (!sheet) {
Logger.log(`Лист с именем "${sheetName}" не найден.`);
return [];
}
const range = sheet.getRange(rangeA1);
return range.getValues();
}
/**
* Записывает данные в указанный диапазон листа.
* @param {string} sheetName Имя листа.
* @param {string} startCell Начальная ячейка для записи (например, "A1").
* @param {any[][]} data Двумерный массив данных для записи.
* @returns {void}
*/
function writeSheetData(sheetName: string, startCell: string, data: any[][]): void {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
if (!sheet || !data || data.length === 0 || data[0].length === 0) {
Logger.log('Ошибка: Лист не найден или данные некорректны.');
return;
}
const startRow = sheet.getRange(startCell).getRow();
const startCol = sheet.getRange(startCell).getColumn();
const numRows = data.length;
const numCols = data[0].length;
sheet.getRange(startRow, startCol, numRows, numCols).setValues(data);
Logger.log(`Данные (${numRows}x${numCols}) успешно записаны в ${sheetName}!${startCell}.`);
}
Форматирование данных и создание диаграмм
GAS позволяет управлять форматированием ячеек (шрифт, цвет, границы, числовые форматы) через методы объекта Range. Также можно программно создавать и изменять диаграммы на листах, используя сервис Charts и методы Sheet.insertChart().
/**
* Применяет базовое форматирование к заголовкам таблицы.
* @param {GoogleAppsScript.Spreadsheet.Range} headerRange Диапазон заголовков.
* @returns {void}
*/
function formatHeaders(headerRange: GoogleAppsScript.Spreadsheet.Range): void {
headerRange
.setBackground('#cfe2f3') // Светло-голубой фон
.setFontWeight('bold')
.setHorizontalAlignment('center');
}
/**
* Создает простую линейную диаграмму на листе.
* @param {GoogleAppsScript.Spreadsheet.Sheet} sheet Лист для вставки диаграммы.
* @param {GoogleAppsScript.Spreadsheet.Range} dataRange Диапазон данных для диаграммы.
* @param {string} title Заголовок диаграммы.
* @returns {GoogleAppsScript.Spreadsheet.EmbeddedChart | null} Созданная диаграмма или null в случае ошибки.
*/
function createLineChart(sheet: GoogleAppsScript.Spreadsheet.Sheet, dataRange: GoogleAppsScript.Spreadsheet.Range, title: string): GoogleAppsScript.Spreadsheet.EmbeddedChart | null {
if (!sheet || !dataRange) return null;
const chartBuilder = sheet.newChart()
.setChartType(Charts.ChartType.LINE)
.addRange(dataRange)
.setPosition(5, 5, 0, 0) // Позиция относительно верхнего левого угла
.setOption('title', title)
.setOption('useFirstColumnAsDomain', true) // Использовать первую колонку как ось X
.build();
sheet.insertChart(chartBuilder);
Logger.log(`Диаграмма "${title}" создана.`);
return chartBuilder;
}
Триггеры: автоматическое выполнение скриптов в Google Sheets
Триггеры позволяют запускать функции автоматически при наступлении определенных событий:
- Простые триггеры:
onOpen(e),onEdit(e),onInstall(e). Выполняются с ограниченными правами. - Устанавливаемые триггеры: Настраиваются программно (
ScriptApp.newTrigger()) или через интерфейс редактора. Могут запускаться по времени (ежедневно, ежечасно), при открытии таблицы, при изменении данных, при отправке формы. Требуют авторизации пользователя.
Примеры скриптов для автоматизации задач в Google Sheets (обработка данных, импорт/экспорт)
- Обработка данных: Скрипт, который при изменении данных в столбце «Статус» автоматически переносит строку на другой лист.
- Импорт CSV: Функция, которая загружает CSV-файл из Google Drive и парсит его содержимое в таблицу.
- Агрегация данных: Ежедневный запуск скрипта, который собирает данные с нескольких листов (например, по рекламным кампаниям) и формирует сводный отчет на отдельном листе.
/**
* Пример: Импортирует данные из CSV файла в Google Drive.
* @param {string} fileId ID CSV файла в Google Drive.
* @param {string} targetSheetName Имя листа для импорта данных.
* @returns {void}
*/
function importCsvFromDrive(fileId: string, targetSheetName: string): void {
try {
const file = DriveApp.getFileById(fileId);
const csvContent = file.getBlob().getDataAsString('UTF-8'); // Указываем кодировку
const csvData = Utilities.parseCsv(csvContent);
if (csvData.length === 0) {
Logger.log('CSV файл пуст или не удалось его распарсить.');
return;
}
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(targetSheetName);
if (!sheet) {
sheet = ss.insertSheet(targetSheetName);
}
sheet.clearContents(); // Очищаем лист перед записью
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
Logger.log(`Данные из файла ID ${fileId} успешно импортированы в лист "${targetSheetName}".`);
} catch (e: any) {
Logger.log(`Ошибка при импорте CSV: ${e.message}\n${e.stack}`);
}
}
Взаимодействие с Google Docs и Slides
Создание, редактирование и форматирование документов Google Docs
Сервис DocumentApp позволяет работать с Google Docs. Можно создавать новые документы, открывать существующие, добавлять и форматировать текст, абзацы, списки, таблицы, изображения.
/**
* Создает новый Google Doc с заголовком и текстом.
* @param {string} docName Имя нового документа.
* @param {string} title Заголовок документа.
* @param {string} bodyText Текст основного содержимого.
* @returns {string} URL созданного документа.
*/
function createSimpleDoc(docName: string, title: string, bodyText: string): string {
const doc = DocumentApp.create(docName);
const body = doc.getBody();
// Добавляем заголовок H1
body.appendParagraph(title)
.setHeading(DocumentApp.ParagraphHeading.HEADING1);
// Добавляем основной текст
body.appendParagraph(bodyText);
doc.saveAndClose();
Logger.log(`Документ "${docName}" создан: ${doc.getUrl()}`);
return doc.getUrl();
}
/**
* Добавляет таблицу в существующий документ.
* @param {string} docId ID документа.
* @param {string[][]} data Данные для таблицы (массив массивов).
* @returns {void}
*/
function addTableToDoc(docId: string, data: string[][]): void {
if (!data || data.length === 0) return;
const doc = DocumentApp.openById(docId);
const body = doc.getBody();
body.appendTable(data);
doc.saveAndClose();
Logger.log(`Таблица добавлена в документ ID ${docId}.`);
}
Работа с презентациями Google Slides: добавление слайдов и элементов
Сервис SlidesApp предназначен для работы с Google Slides. Он позволяет создавать презентации, добавлять слайды на основе макетов, вставлять текст, фигуры, изображения, таблицы и видео.
/**
* Добавляет новый слайд с заголовком и текстом в презентацию.
* @param {string} presentationId ID презентации.
* @param {string} slideTitle Заголовок слайда.
* @param {string} slideBody Текст на слайде.
* @returns {void}
*/
function addSlide(presentationId: string, slideTitle: string, slideBody: string): void {
const pres = SlidesApp.openById(presentationId);
const slideLayout = pres.getLayouts()[1]; // Используем второй макет (например, Title and Body)
const slide = pres.appendSlide(slideLayout);
// Вставляем текст в плейсхолдеры
const titlePlaceholder = slide.getPlaceholder(SlidesApp.PlaceholderType.TITLE);
if (titlePlaceholder) {
titlePlaceholder.asShape().getText().setText(slideTitle);
}
const bodyPlaceholder = slide.getPlaceholder(SlidesApp.PlaceholderType.BODY);
if (bodyPlaceholder) {
bodyPlaceholder.asShape().getText().setText(slideBody);
}
Logger.log(`Слайд "${slideTitle}" добавлен в презентацию ID ${presentationId}.`);
}
Автоматизация создания отчетов и презентаций на основе данных
Одна из самых мощных возможностей GAS — генерация документов и презентаций на основе данных из Google Sheets или других источников. Можно создать шаблон документа или слайда с плейсхолдерами ({{placeholder}}) и затем программно заменять их на реальные данные.
/**
* Генерирует отчет в Google Doc на основе данных из строки таблицы.
* @param {string} templateDocId ID документа-шаблона.
* @param {Record<string, string>} data Данные для замены плейсхолдеров (ключ: плейсхолдер, значение: текст).
* @param {string} outputDocName Имя генерируемого документа.
* @returns {string | null} URL созданного документа или null.
*/
function generateDocFromTemplate(templateDocId: string, data: Record<string, string>, outputDocName: string): string | null {
try {
const templateDoc = DriveApp.getFileById(templateDocId);
const newDocFile = templateDoc.makeCopy(outputDocName);
const newDoc = DocumentApp.openById(newDocFile.getId());
const body = newDoc.getBody();
for (const placeholder in data) {
body.replaceText(`{{${placeholder}}}`, data[placeholder]);
}
newDoc.saveAndClose();
const url = newDoc.getUrl();
Logger.log(`Отчет "${outputDocName}" сгенерирован: ${url}`);
return url;
} catch (e: any) {
Logger.log(`Ошибка генерации документа: ${e.message}`);
return null;
}
}
Примеры скриптов для работы с текстом и изображениями
- Замена текста: Найти и заменить определенные слова или фразы во всех документах в папке.
- Вставка изображений: Добавить логотип компании или изображения продуктов в документ/презентацию из Google Drive или по URL.
- Анализ текста: Подсчет количества слов или символов в документе.
Автоматизация Gmail и Google Calendar
Отправка и обработка писем с помощью Gmail API
Сервис GmailApp предоставляет доступ к ящику Gmail. Можно отправлять письма (простые и HTML), искать письма по критериям, получать содержимое писем, управлять метками и перемещать письма.
/**
* Отправляет email.
* @param {string} recipient Адрес получателя.
* @param {string} subject Тема письма.
* @param {string} body Текст письма (может быть HTML).
* @param {GmailApp.GmailAdvancedOptions | undefined} options Дополнительные параметры (cc, bcc, htmlBody, attachments и т.д.).
* @returns {void}
*/
function sendEmail(recipient: string, subject: string, body: string, options?: GmailApp.GmailAdvancedOptions): void {
try {
GmailApp.sendEmail(recipient, subject, body, options);
Logger.log(`Письмо отправлено на ${recipient}.`);
} catch (e: any) {
Logger.log(`Ошибка отправки email: ${e.message}`);
}
}
/**
* Ищет письма по запросу и логирует темы найденных писем.
* @param {string} searchQuery Поисковый запрос Gmail (например, "from:sender@example.com is:unread").
* @param {number} maxThreads Максимальное количество цепочек для обработки.
* @returns {void}
*/
function processEmails(searchQuery: string, maxThreads: number = 10): void {
const threads = GmailApp.search(searchQuery, 0, maxThreads);
Logger.log(`Найдено ${threads.length} цепочек писем по запросу "${searchQuery}".`);
threads.forEach(thread => {
const firstMessage = thread.getMessages()[0]; // Берем первое сообщение в цепочке
Logger.log(` - Тема: ${firstMessage.getSubject()}, От: ${firstMessage.getFrom()}`);
// Здесь можно добавить логику обработки: извлечение данных, добавление метки и т.д.
// thread.addLabel(GmailApp.getUserLabelByName('Processed'));
// thread.moveToArchive();
});
}
Управление событиями в Google Calendar
Сервис CalendarApp позволяет работать с Google Calendar. Можно получать доступ к календарям, создавать, изменять и удалять события, управлять приглашениями и напоминаниями.
/**
* Создает событие в основном календаре пользователя.
* @param {string} title Название события.
* @param {Date} startTime Время начала.
* @param {Date} endTime Время окончания.
* @param {CalendarApp.EventOptions | undefined} options Дополнительные параметры (описание, местоположение, гости и т.д.).
* @returns {GoogleAppsScript.Calendar.CalendarEvent | null} Созданное событие или null.
*/
function createCalendarEvent(title: string, startTime: Date, endTime: Date, options?: CalendarApp.EventOptions): GoogleAppsScript.Calendar.CalendarEvent | null {
try {
const calendar = CalendarApp.getDefaultCalendar();
const event = calendar.createEvent(title, startTime, endTime, options);
Logger.log(`Событие "${title}" создано (ID: ${event.getId()}).`);
return event;
} catch (e: any) {
Logger.log(`Ошибка создания события: ${e.message}`);
return null;
}
}
/**
* Находит предстоящие события на сегодня.
* @returns {GoogleAppsScript.Calendar.CalendarEvent[]} Массив событий.
*/
function getTodaysEvents(): GoogleAppsScript.Calendar.CalendarEvent[] {
const today = new Date();
const startOfDay = new Date(today.setHours(0, 0, 0, 0));
const endOfDay = new Date(today.setHours(23, 59, 59, 999));
const calendar = CalendarApp.getDefaultCalendar();
const events = calendar.getEvents(startOfDay, endOfDay);
Logger.log(`Найдено ${events.length} событий на сегодня.`);
return events;
}
Создание напоминаний и автоматизация рассылок
- Напоминания: Создание событий в календаре для задач с дедлайнами из Google Sheets.
- Автоматизация рассылок: Персонализированная рассылка писем на основе списка контактов и данных из таблицы (например, отчеты клиентам, уведомления пользователям).
Примеры скриптов для автоматического ответа на письма и создания событий
- Автоответчик: Скрипт, который отвечает на письма с определенной темой стандартным сообщением.
- Создание событий из Sheets: Скрипт, который читает строки из таблицы (например, план маркетинговых активностей с датами) и создает соответствующие события в календаре.
Расширенные возможности и интеграция с другими сервисами
Работа с HTML Service: создание пользовательских интерфейсов
HtmlService позволяет создавать веб-интерфейсы с использованием HTML, CSS и JavaScript (на стороне клиента). Эти интерфейсы могут отображаться как диалоговые окна или боковые панели в Google Sheets, Docs, Forms, или как самостоятельные веб-приложения.
GAS позволяет передавать данные из серверного скрипта в клиентский JavaScript (google.script.run) и наоборот.
// Код в файле Code.gs
/**
* Отображает простую боковую панель в Google Sheets.
*/
function showSidebar(): void {
const htmlOutput = HtmlService.createHtmlOutputFromFile('Sidebar')
.setTitle('Моя панель');
SpreadsheetApp.getUi().showSidebar(htmlOutput);
}
/**
* Серверная функция, вызываемая из клиентского скрипта.
* @param {string} name Имя пользователя.
* @returns {string} Приветствие.
*/
function getServerGreeting(name: string): string {
Logger.log(`Запрос приветствия для ${name}`);
return `Привет с сервера, ${name}!`;
}
// Код в файле Sidebar.html
/*
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Тестовая панель</h1>
<p>Введите имя:</p>
<input type="text" id="nameInput" />
<button onclick="callServer()">Отправить</button>
<p id="response"></p>
<script>
function callServer() {
const name = document.getElementById('nameInput').value;
google.script.run
.withSuccessHandler(updateResponse)
.withFailureHandler(showError)
.getServerGreeting(name);
}
function updateResponse(greeting) {
document.getElementById('response').innerText = greeting;
}
function showError(error) {
document.getElementById('response').innerText = 'Ошибка: ' + error.message;
}
</script>
</body>
</html>
*/
Использование внешних API: получение данных и интеграция с другими сервисами
Сервис UrlFetchApp позволяет отправлять HTTP(S) запросы к внешним API. Это открывает возможности для интеграции с практически любыми сторонними сервисами: CRM, аналитическими платформами, платежными системами и т.д.
Требуется обработка ответов (часто в формате JSON) и управление аутентификацией (API-ключи, OAuth2).
/**
* Получает данные из внешнего JSON API.
* @param {string} apiUrl URL API-эндпоинта.
* @param {GoogleAppsScript.URL_Fetch.URLFetchRequestOptions | undefined} options Параметры запроса (метод, заголовки, payload).
* @returns {any | null} Распарсенный JSON-ответ или null в случае ошибки.
*/
function fetchExternalApi(apiUrl: string, options?: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions): any | null {
try {
const response = UrlFetchApp.fetch(apiUrl, options);
const responseCode = response.getResponseCode();
const responseBody = response.getContentText();
if (responseCode === 200) {
return JSON.parse(responseBody);
} else {
Logger.log(`Ошибка API запроса (${responseCode}): ${responseBody}`);
return null;
}
} catch (e: any) {
Logger.log(`Ошибка UrlFetchApp: ${e.message}`);
return null;
}
}
/**
* Пример: получение данных о курсе валют (использует публичное API).
*/
function getExchangeRates(): void {
const apiUrl = 'https://api.exchangerate-api.com/v4/latest/USD'; // Пример API
const ratesData = fetchExternalApi(apiUrl);
if (ratesData && ratesData.rates) {
Logger.log(`Курс EUR к USD: ${ratesData.rates.EUR}`);
Logger.log(`Курс RUB к USD: ${ratesData.rates.RUB}`);
// Данные можно записать в Google Sheets
// writeSheetData('Курсы валют', 'A1', [[new Date(), ratesData.rates.EUR, ratesData.rates.RUB]]);
}
}
Развертывание скриптов как веб-приложений
Скрипт можно развернуть как веб-приложение, доступное по уникальному URL. Такие приложения могут обслуживать GET и POST запросы, возвращая HTML (с помощью HtmlService) или текстовые данные (например, JSON, используя ContentService).
Развертывание настраивается в редакторе скриптов. Можно выбрать, кто имеет доступ к приложению (только вы, пользователи домена, любой пользователь) и от чьего имени будет выполняться скрипт (пользователя, обращающегося к приложению, или разработчика).
/**
* Обрабатывает GET запросы к веб-приложению.
* Возвращает простой HTML ответ.
* @param {GoogleAppsScript.Events.DoGet} e Объект события.
* @returns {GoogleAppsScript.HTML.HtmlOutput} HTML ответ.
*/
function doGet(e: GoogleAppsScript.Events.DoGet): GoogleAppsScript.HTML.HtmlOutput {
Logger.log(`GET запрос: Параметры = ${JSON.stringify(e.parameter)}`);
const name = e.parameter.name || 'Гость';
return HtmlService.createHtmlOutput(`<h1>Привет, ${name}!</h1><p>Это веб-приложение на Google Apps Script.</p>`);
}
/**
* Обрабатывает POST запросы к веб-приложению.
* Возвращает JSON ответ.
* @param {GoogleAppsScript.Events.DoPost} e Объект события.
* @returns {GoogleAppsScript.Content.TextOutput} JSON ответ.
*/
function doPost(e: GoogleAppsScript.Events.DoPost): GoogleAppsScript.Content.TextOutput {
Logger.log(`POST запрос: Данные = ${e.postData.contents}`);
let responseData;
try {
const requestData = JSON.parse(e.postData.contents);
// Обработка данных...
responseData = { status: 'success', received: requestData };
} catch (err: any) {
responseData = { status: 'error', message: 'Invalid JSON format.' };
}
return ContentService.createTextOutput(JSON.stringify(responseData))
.setMimeType(ContentService.MimeType.JSON);
}
Отладка и обработка ошибок в Google Apps Script
- Логирование:
Logger.log()иconsole.log()для вывода информации в лог выполнения. Логи доступны в редакторе скриптов. - Отладчик: Встроенный отладчик позволяет устанавливать точки останова, пошагово выполнять код и проверять значения переменных.
- Обработка ошибок: Использование стандартных конструкций
try...catch...finallyдля перехвата и обработки исключений. - Stackdriver Logging/Error Reporting: Для более продвинутого мониторинга и анализа ошибок в проектах Google Cloud Platform (GCP), связанных со скриптом.
Тщательная обработка ошибок и логирование критически важны для надежной работы скриптов, особенно тех, что выполняются по триггерам или как веб-приложения.