1. Прежде чем начать
В этой лаборатории кода вы узнаете, как автоматизировать задачи Google Workspace с помощью вызова функций и мультимодальных функций Gemini API .
Предварительные условия
- Базовое знание Apps Script, JavaScript или аналогичного языка программирования.
Что вы узнаете
- Как использовать возможности вызова функций и мультимодальности Gemini API.
- Как объединить несколько вызовов Gemini API.
- Как автоматизировать задачи Google Workspace с помощью Gemini API.
Что вам нужно
- Веб-браузер.
- Учетная запись Gmail. В качестве альтернативы можно использовать учетную запись Google Workspace, в которой реализована специальная настройка Gemini API.
- Соединение из поддерживаемого региона для Gemini API.
- Необязательно: интерфейс командной строки с программой
curl
для проверки прямых запросов API.
Полный код этой кодовой лаборатории доступен в кулинарной книге Gemini API на GitHub . Проверьте это, если вам нужен готовый код.
2. Настройте API Gemini.
О Близнецах
Модели Gemini — это крупнейшее и наиболее мощное семейство моделей искусственного интеллекта Google. Чтобы воспользоваться преимуществами этих моделей в своих приложениях, вы можете использовать Gemini API . Вы также можете попробовать Gemini API в Google AI Studio , веб-интерфейсе API, где вы можете попробовать подсказки, настроить параметры модели и настроить собственные модели без написания какого-либо кода.
Получить ключ
- Чтобы использовать Gemini API, создайте ключ API в Google AI Studio.
Необязательно: проверьте свой ключ
Если у вас есть доступ к командной строке с помощью Curl, добавьте свой ключ в первую строку следующего блока, а затем запустите его в своем терминале, чтобы проверить ключ API.
export GOOGLE_API_KEY=Paste_your_API_key_here
curl "https://generativelanguage.googleapis.com/v1beta/models?key=${GOOGLE_API_KEY}"
Вы должны увидеть список моделей в формате JSON, например models/gemini-1.0-pro. Это значит, что это сработало.
3. Необязательно: сделайте запрос к API Gemini.
На этом необязательном этапе вы отправляете запрос к Gemini API, чтобы лучше понять, как работает генерация контента, прежде чем добавлять его в приложение Apps Script.
О моделях
Gemini API предоставляет ряд моделей с различными возможностями и ограничениями. Каждая из моделей указана вместе с ее возможностями на странице моделей Gemini .
Оформление вашего первого запроса
Чтобы API Gemini завершил текстовое приглашение, вы создаете запрос JSON и отправляете его в конечную точку REST API.
Для этого выполните следующие действия:
- В новом файле введите следующий запрос JSON:
{
contents: [
{
parts: [
{ text: 'The most important aspects of a persuasive presentation are:' }
]
}
]
}
Запрос JSON включает следующую подсказку: The most important aspects of a persuasive presentation are:
. Модель выполнит эту инструкцию и сразу выдаст вам результат.
Запрос JSON имеет три поля верхнего уровня для заполнения: contents
, generationConfig
и safetySettings
. Требуется только contents
. Остальные предоставляют механизмы для управления выводом.
- Сохраните этот JSON в файле
presentation.txt
, а затем передайте его непосредственно вcurl
следующим образом:
curl -H 'Content-Type: application/json' -X POST -d @presentation.txt \
'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro-latest:generateContent?key='${GOOGLE_API_KEY}
В этом примере вы устанавливаете следующие значения в URL-адресе:
-
v1beta
указывает версию API. -
gemini-1.0-pro-latest
указывает Gemini 1.0 Pro в качестве модели и использует последний снимок. -
generateContent
указывает метод API, который вы вызываете.
Вы должны увидеть результаты, подобные следующим:
{
"candidates": [
{
"content": {
"parts": [
{
"text": "* **Credibility:** The audience must trust that you are an expert on the subject matter and that you have their best interests at heart.\n* **Clearness:** Your message must be easy to understand and follow. Avoid using jargon or technical terms that your audience may not be familiar with.\n* **Concreteness:** Use specific examples and data to support your arguments. Avoid making vague or general claims.\n* **Emotional appeal:** In addition to appealing to the audience's logical side, you should also try to connect with them on an emotional level. Use storytelling, humor, and personal anecdotes to make your points more memorable and engaging.\n* **Strong closing:** End your presentation with a strong call to action. Tell the audience what you want them to do and why it is important for them to do it."
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0,
"safetyRatings": [...]
}
],
"promptFeedback": {
"safetyRatings": [...]
}
}
Для удобства чтения вывод терминала регулярно форматируется:
- Достоверность: аудитория должна верить, что вы являетесь экспертом по предмету и что вы искренне заботитесь о ее интересах.
- Ясность: Ваше сообщение должно быть легко понятным и понятным. Избегайте использования жаргона или технических терминов, которые могут быть незнакомы вашей аудитории.
- Конкретность: используйте конкретные примеры и данные для подтверждения своих аргументов. Избегайте расплывчатых или общих утверждений.
- Эмоциональная привлекательность. Помимо обращения к логической стороне аудитории, вы также должны попытаться установить с ней контакт на эмоциональном уровне. Используйте рассказывание историй, юмор и личные истории, чтобы сделать ваши выступления более запоминающимися и привлекательными.
- Сильное завершение: завершите презентацию убедительным призывом к действию. Расскажите аудитории, чего вы от нее хотите и почему для нее это важно.
Чтобы узнать больше о других настройках, включая generationConfig
и safetySettings
, см. руководства по подсказкам и безопасности .
4. Вызов Gemini API из скрипта приложений.
- Посетите script.new , и файл Apps Script
code.gs
будет создан автоматически. - Наведите курсор на файл
code.gs
и нажмите кнопку > Переименовать . - Измените имя файла на
utils.gs
. - В файле удалите функцию
myFunction
, чтобы файл стал пустым.
Добавьте свой ключ API в проект
- В меню навигации выберите Настройки проекта .
- В разделе «Свойства сценария» нажмите «Добавить свойство сценария» .
- В разделе «Свойство» введите
GOOGLE_API_KEY
. - В разделе «Значение» введите свой ключ API от Google AI Studio.
- Нажмите Сохранить свойства скрипта .
- Вернитесь в редактор.
Добавьте код Gemini API
В файле utils.gs
выполните следующие действия:
Настройте ключ API и конечную точку:
const properties = PropertiesService.getScriptProperties().getProperties();
const geminiApiKey = properties['GOOGLE_API_KEY'];
const geminiEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro-latest:generateContent?key=${geminiApiKey}`;
- Добавьте следующую функцию, которая вызывает API Gemini с конкретным приглашением:
function callGemini(prompt, temperature=0) {
const payload = {
"contents": [
{
"parts": [
{
"text": prompt
},
]
}
],
"generationConfig": {
"temperature": temperature,
},
};
const options = {
'method' : 'post',
'contentType': 'application/json',
'payload': JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(geminiEndpoint, options);
const data = JSON.parse(response);
const content = data["candidates"][0]["content"]["parts"][0]["text"];
return content;
}
- Добавьте следующую функцию, которая устанавливает приглашение:
function testGemini() {
const prompt = "The best thing since sliced bread is";
const output = callGemini(prompt);
console.log(prompt, output);
}
Проверьте это
- Нажмите Сохранять.
- Выберите
testGemini
в раскрывающемся списке функций и нажмите . - Примите необходимые разрешения. Ваш код должен запуститься, и вы должны увидеть вывод консоли с результатами в журнале выполнения.
Это сработало!
5. Вызов API Gemini с изображениями
Одной из самых мощных функций семейства моделей Gemini является поддержка мультимодального ввода, что означает, что вы можете вводить больше, чем просто текст! В этом разделе вы добавите функцию, которая вызывает API Gemini с изображением.
- В верхней части файла
utils.gs
после существующего объявленияconst geminiEndpoint
добавьте следующую строку:
const geminiProVisionEndpoint = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.0-pro-vision-latest:generateContent?key=${geminiApiKey}`;
Добавьте код Gemini Vision
- Добавьте в файл
utils.gs
функцию для вызова этой недавно добавленной конечной точки:
function callGeminiProVision(prompt, image, temperature=0) {
const imageData = Utilities.base64Encode(image.getAs('image/png').getBytes());
const payload = {
"contents": [
{
"parts": [
{
"text": prompt
},
{
"inlineData": {
"mimeType": "image/png",
"data": imageData
}
}
]
}
],
"generationConfig": {
"temperature": temperature,
},
};
const options = {
'method' : 'post',
'contentType': 'application/json',
'payload': JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(geminiProVisionEndpoint, options);
const data = JSON.parse(response);
const content = data["candidates"][0]["content"]["parts"][0]["text"];
return content;
}
- Добавьте следующую тестовую функцию:
function testGeminiVision() {
const prompt = "Provide a fun fact about this object.";
const image = UrlFetchApp.fetch('https://storage.googleapis.com/generativeai-downloads/images/instrument.jpg').getBlob();
const output = callGeminiProVision(prompt, image);
console.log(prompt, output);
}
Эта функция загружает тестовое изображение из Интернета и передает его определенной вами функции. Позже вы подключаете его для использования диаграммы из электронной таблицы, так что это всего лишь проверка.
Проверьте это
- Сохраните и запустите функцию
testGeminiVision
, а затем проверьте выходные данные.
6. Вызов Gemini API с помощью инструментов
Помимо текста и изображений, вы также можете предоставить доступ к инструментам в своих подсказках.
Добавьте код обработки инструментов
- Добавьте в файл
utils.gs
функцию, которая принимает спецификацию инструмента:
function callGeminiWithTools(prompt, tools, temperature=0) {
const payload = {
"contents": [
{
"parts": [
{
"text": prompt
},
]
}
],
"tools" : tools,
"generationConfig": {
"temperature": temperature,
},
};
const options = {
'method' : 'post',
'contentType': 'application/json',
'payload': JSON.stringify(payload)
};
const response = UrlFetchApp.fetch(geminiEndpoint, options);
const data = JSON.parse(response);
const content = data["candidates"][0]["content"]["parts"][0]["functionCall"];
return content;
}
Дополнительные сведения об этой схеме и доступных полях см. в справочнике по API FunctionDeclaration
.
Проверьте это
- Определите инструмент, который модель может использовать для поиска текущей даты и времени:
function testGeminiTools() {
const prompt = "Tell me how many days there are left in this month.";
const tools = {
"function_declarations": [
{
"name": "datetime",
"description": "Returns the current date and time as a formatted string.",
"parameters": {
"type": "string"
}
}
]
};
const output = callGeminiWithTools(prompt, tools);
console.log(prompt, output);
}
Используемый здесь формат — это схема FunctionDeclaration
. На самом деле вы не вызываете функцию даты и времени. Вы получаете только указание на то, что модель запросила вызов функции. Вызовы функций обрабатываются на более позднем этапе.
- Сохраните и запустите функцию
testGeminiTools
, чтобы увидеть результат.
7. Обзор демонстрационных интеграций с Google Workspace
Теперь, когда вы понимаете, как работает вызов функций, вы можете легко расширить возможности модели Gemini на другие сервисы. В следующих нескольких разделах вы создадите интеграцию с продуктами Google Workspace, такими как Google Drive, Google Slides и Google Sheets. Вот упрощенная схема:
На высоком уровне, когда поступает пользовательский запрос, вы используете вызов функции Gemini API, чтобы определить, какой инструмент использовать. Вы создаете три инструмента, которые могут выполнять следующие действия:
- Назначьте встречу . Функция
setupMeeting()
на диаграмме вызывает API Gemini 1.0 Pro для подведения итогов блога на Google Диске и добавления сводки к вновь созданной встрече в Календаре Google. - Составьте электронное письмо на основе данных диаграммы . Функция
draftEmail()
на диаграмме вызывает Gemini 1.0 Pro Vision для анализа диаграммы в Google Sheets и составления электронного письма в Gmail на основе анализа. - Создайте скелетную колоду . Функция
createDeck()
на диаграмме вызывает Gemini 1.0 Pro для мозгового штурма по пунктам для презентации в Google Slides.
Для каждого инструмента вам необходимо сделать следующие три вещи:
- Определите, запрашивает ли ответ на вызов функции Gemini API вызов этого конкретного инструмента в блоке
if...else
. - Добавьте фактическую функцию для реализации функциональности инструмента.
- Объявите инструмент с помощью Gemini API, чтобы модель Gemini знала о существовании инструмента и могла возвращать правильный ответ на вызов функции.
8. Назначьте встречу с помощью Apps Script.
Сначала вы автоматизируете настройку встречи в Календаре Google, но также добавляете описание, которое представляет собой краткое описание файла на Google Диске.
Для этого выполните следующие действия:
- Загрузите этот текстовый файл , который является текстовой копией блога о выпуске Gemini 1.5 Pro .
- Загрузите файл в корневую папку Google Диска.
- В редакторе создайте файл
main.gs
и добавьте следующий код:
function main() {
const userQuery = "Set up a meeting at 10AM tomorrow with Helen to discuss the news in the Gemini-blog.txt file.";
var tool_use = callGeminiWithTools(userQuery, WORKSPACE_TOOLS);
Logger.log(tool_use);
if(tool_use['name'] == "setupMeeting") {
setupMeeting(tool_use['args']['time'], tool_use['args']['recipient'], tool_use['args']['filename']);
Logger.log("Your meeting has been set up.");
}
else
Logger.log("no proper tool found");
}
Здесь вы вызываете возможность вызова функций Gemini API. Далее вам необходимо определить функцию инструмента.
- В левой части редактора рядом с пунктом «Службы» нажмите + Добавить службу > API Календаря Google > Добавить . Это активирует расширенную службу Календаря Google, которую вам понадобится использовать для некоторых расширенных API позже.
- В файл
utils.gs
добавьте следующий код:
function attachFileToMeeting(event, file, fileName) {
// Get the iCal ID for the event.
const iCalEventId = event.getId();
// Log the ID and title for debugging.
console.log(`iCal event ID: ${iCalEventId}`);
console.log(`event Title: ${event.getTitle()}`);
// Set up the options for listing the event with the advanced Google Calendar service.
const options = {
iCalUID: iCalEventId,
};
// Use the primary calendar as the calendar ID to list events.
const calendarId = 'primary';
// Use the advanced Google Calendar service to list the event.
const calEvents = Calendar.Events.list(calendarId, options);
// Get the Calendar ID used by the advanced Google Calendar service.
const eventId = calEvents.items[0].id;
// Get the file URL for the attachment.
const fileUrl = file.getUrl();
// Set up the patch options to add the file.
var patch = {
attachments: [{
'fileUrl': fileUrl,
'title': fileName
}]
};
// Patch the event to add the file as an attachment.
Calendar.Events.patch(patch, 'primary', eventId, {"supportsAttachments": true});
}
function setupMeeting(time, recipient, filename) {
const files = DriveApp.getFilesByName(filename);
const file = files.next();
const blogContent = file.getAs("text/*").getDataAsString();
var geminiOutput = callGemini("Give me a really short title of this blog and a summary with less than three sentences. Please return the result as a JSON with two fields: title and summary. \n" + blogContent);
// The Gemini model likes to enclose the JSON with ```json and ```
geminiOutput = JSON.parse(geminiOutput.replace(/```(?:json|)/g, ""));
const title = geminiOutput['title'];
const fileSummary = geminiOutput['summary'];
const event = CalendarApp.getDefaultCalendar().createEventFromDescription(`meet ${recipient} at ${time} to discuss "${title}"`);
event.setDescription(fileSummary);
attachFileToMeeting(event, file, filename);
}
Этот код делает следующее:
- Функция
setupMeeting()
просматривает ваш Google Диск и находит файлGemini-blog.txt
. Это имя файла автоматически возвращается функцией Gemini API, вызывающей на шаге 3. - Функция
setupMeeting()
вызывает API Gemini для обобщения содержимого файла, настраивает встречу с CalendarApp, используя описание в свободной форме, и добавляет сводку к встрече. - Функция
setupMeeting()
вызывает функциюattachFileToMeeting()
, чтобы использовать расширенную службу Календаря Google для прикрепления файла блога к собранию.
- В верхней части файла
utils.gs
добавьте следующий код:
const WORKSPACE_TOOLS = {
"function_declarations": [
{
"name": "setupMeeting",
"description": "Sets up a meeting in Google Calendar.",
"parameters": {
"type": "object",
"properties": {
"time": {
"type": "string",
"description": "The time of the meeting."
},
"recipient": {
"type": "string",
"description": "The name of the recipient."
},
"filename": {
"type": "string",
"description": "The name of the file."
},
},
"required": [
"time",
"recipient",
"filename"
]
}
},
// You add tools here.
]
};
- В редакторе вернитесь к файлу
main.gs
и нажмите . - Если Google Workspace запросит у вас разрешение на запуск скрипта, нажмите «ОК» .
Через несколько секунд в журнале выполнения отобразится сообщение, сообщающее, что ваша встреча настроена.
- В Календаре Google найдите встречу с ее описанием и вложением.
9. Составьте электронное письмо с помощью Apps Script
Далее вы автоматизируете составление электронного письма в Gmail. Вот сценарий: Предположим, вы проводите анализ данных в Google Sheets. Вы расставляете все цифры по местам и создаете диаграмму. Вы хотите использовать API Gemini Pro Vision для составления электронного письма на основе диаграммы.
Для этого выполните следующие действия:
- Откройте этот лист и нажмите Файл -> Создать копию .
- В текстовом поле Имя диалогового окна Копирование документа замените имя по умолчанию
Copy of CollegeExpenses
наCollegeExpenses
. - В файле
main.gs
замените предыдущий пользовательский запрос новым, а затем добавьте следующий код в операторif...else
:
function main() {
// const userQuery = "Set up a meeting at 5PM with Helen to discuss the news in the Gemini-1.5-blog.txt file.";
const userQuery = "Draft an email for Mary with insights from the chart in the CollegeExpenses sheet.";
if(...) {...}
// Add this code
else if(tool_use['name'] == "draftEmail") {
draftEmail(tool_use['args']['sheet_name'], tool_use['args']['recipient']);
Logger.log("Check your Gmail to review the draft");
}
else {...}
}
- В файл
utils.gs
добавьте следующий код:
function draftEmail(sheet_name, recipient) {
const prompt = `Compose the email body for ${recipient} with your insights for this chart. Use information in this chart only and do not do historical comparisons. Be concise.`;
var files = DriveApp.getFilesByName(sheet_name);
var sheet = SpreadsheetApp.openById(files.next().getId()).getSheetByName("Sheet1");
var expenseChart = sheet.getCharts()[0];
var chartFile = DriveApp.createFile(expenseChart.getBlob().setName("ExpenseChart.png"));
var emailBody = callGeminiProVision(prompt, expenseChart);
GmailApp.createDraft(recipient+"@demo-email-provider.com", "College expenses", emailBody, {
attachments: [chartFile.getAs(MimeType.PNG)],
name: 'myname'
});
}
Эта функция извлекает из листа диаграмму расходов на обучение в колледже и отправляет ее в Gemini Pro Vision для составления электронного письма. Gemini Pro Vision извлекает информацию из диаграммы и составляет текст электронного письма от вашего имени.
- В файле
utils.gs
добавьте следующий код к объектуWORKSPACE_TOOLS
после комментарияYou add tools here
:
WORKSPACE_TOOLS = {
"function_declarations": [
// You add tools here.
{
"name": "draftEmail",
"description": "Write an email by analyzing data or charts in a Google Sheets file.",
"parameters": {
"type": "object",
"properties": {
"sheet_name": {
"type": "string",
"description": "The name of the sheet to analyze."
},
"recipient": {
"type": "string",
"description": "The name of the recipient."
},
},
"required": [
"sheet_name",
"recipient"
]
}
},
]
};
- В редакторе вернитесь к файлу
main.gs
и нажмите . - Через 10–20 секунд откройте Gmail. Вы должны увидеть примерно такой черновик письма:
Вы можете отредактировать черновик электронного письма перед его отправкой. Электронное письмо полностью написано Gemini Pro Vision после того, как вы дадите ему короткую подсказку и таблицу.
10. Создайте скелетную колоду с помощью Apps Script
Затем вы автоматизируете создание скелетной колоды в Google Slides с помощью Apps Script.
Для этого выполните следующие действия:
- В файле
main.gs
замените предыдущий пользовательский запрос новым и добавьте следующий код в операторif...else
:
function main() {
// const userQuery = "Draft an email for Mary with insights from the chart in the CollegeExpenses sheet.";
const userQuery = "Help me put together a deck about water conservation.";
if(...) {...}
// Add this code
else if(tool_use['name'] == 'createDeck') {
deckURL = createDeck(tool_use['args']['topic']);
Logger.log("Deck URL: " + deckURL);
}
else {...}
}
- В файл
utils.gs
добавьте следующий код:
function createDeck(topic) {
const prompt = `I'm preparing a ${NUM_SLIDES}-slide deck to discuss ${topic}. Please help me brainstorm and generate main bullet points for each slide. Keep the title of each slide short. Please produce the result as a valid JSON so that I can pass it to other APIs.`;
var geminiOutput = callGemini(prompt, 0.4);
// The Gemini model likes to enclose the JSON with ```json and ```
geminiOutput = geminiOutput.replace(/```(?:json|)/g, "");
const bulletPoints = JSON.parse(geminiOutput);
// Create a Google Slides presentation.
const presentation = SlidesApp.create("My New Presentation");
// Set up the opening slide.
var slide = presentation.getSlides()[0];
var shapes = slide.getShapes();
shapes[0].getText().setText(topic);
var body;
for (var i = 0; i < NUM_SLIDES; i++) {
slide = presentation.appendSlide(SlidesApp.PredefinedLayout.TITLE_AND_BODY);
shapes = slide.getShapes();
// Set title.
shapes[0].getText().setText(bulletPoints['slides'][i]['title']);
// Set body.
body = "";
for (var j = 0; j < bulletPoints['slides'][i]['bullets'].length; j++) {
body += '* ' + bulletPoints['slides'][i]['bullets'][j] + '\n';
}
shapes[1].getText().setText(body);
}
return presentation.getUrl();
}
Эта функция вызывает API Gemini для мозгового штурма по конкретной теме и возвращает пункты списка в формате
JSON, а затем используйте Apps Script для заполнения скелетной колоды.
- В файле
utils.gs
добавьте следующий код к объектуWORKSPACE_TOOLS
после комментарияYou add tools here
:
WORKSPACE_TOOLS = {
"function_declarations": [
// You add tools here.
{
"name": "createDeck",
"description": "Build a simple presentation deck with Google Slides and return the URL.",
"parameters": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"description": "The topic that the presentation is about."
},
},
"required": [
"topic"
]
}
},
]
};
- В верхней части файла
utils.gs
определите следующую константу:
const NUM_SLIDES = 3;
Это количество слайдов, которые создает модель Близнецов в дополнение к начальному слайду.
- В редакторе вернитесь к файлу
main.gs
и нажмите . Через несколько секунд вы увидите URL-адрес презентации в журнале выполнения. - Используйте браузер, чтобы открыть URL-адрес. Вы должны увидеть скелетную колоду, заполненную пунктами списка.
11. Идеи для изучения
Помимо этих трех интеграций, вы можете изучить следующие идеи:
- Создайте чат-бота в Google Chat . Одним из наиболее популярных вариантов использования моделей большого языка (LLM) является создание чат-бота. С помощью API Gemini легко создать чат-бота для Google Chat. Дополнительную информацию см. в разделе API Google Chat и кодовой лаборатории. Создание приложений для Google Chat с помощью Gemini .
- Поисково-дополненная генерация (RAG) с вашими собственными данными на Google Drive или Keep . В этой кодовой лаборатории для обобщения используется только один текстовый файл. Однако вы также можете использовать контент из вашего личного Google Диска и Keep (например, заметки, PDF-файлы и изображения) с API Gemini, векторной базой данных и, при необходимости, инструментом оркестрации, например LangChain , для выполнения RAG и персонализации ответ модели на основе ваших данных.
- Используйте возможность многоэтапного вызова функций Gemini API . Вызов функций Gemini API не ограничивается одним ходом, и вы можете выполнять многоэтапный вызов функций для еще более сложных задач.
- Выйдите за рамки Google Workspace . Теперь, когда вы понимаете, как интегрировать Gemini API с Google Workspace, вы можете выйти за рамки Google Workspace и использовать другие API в мире.
12. Поздравления
Вы узнали о мультимодальных возможностях Gemini API и вызове функций. Вы использовали их для автоматизации некоторых задач Google Workspace с помощью Apps Script!