Краткое описание Google Apps Script и его возможностей
Google Apps Script (GAS) — это облачная платформа для разработки скриптов, основанная на JavaScript, которая позволяет автоматизировать задачи, интегрировать и расширять функциональность приложений Google Workspace (Docs, Sheets, Forms, Drive, Gmail и др.). Она предоставляет удобный способ создания пользовательских меню, диалоговых окон, автоматических обработчиков событий и взаимодействия с внешними API.
Почему важно знать имя текущего пользователя в скриптах
Определение текущего пользователя, взаимодействующего со скриптом, является ключевым аспектом для многих сценариев. Это позволяет персонализировать интерфейс, разграничивать права доступа к данным или функциям, вести журналы аудита действий пользователей, а также настраивать логику скрипта в зависимости от того, кто его запускает. Например, в системе утверждения документов важно знать, кто инициировал или утвердил запрос.
Обзор методов получения имени пользователя, которые будут рассмотрены
В этой статье мы рассмотрим основные подходы к идентификации текущего пользователя в Google Apps Script:
- Использование встроенного сервиса
Session
для получения email и имени пользователя. - Применение
Properties Service
для кэширования идентификатора пользователя. - Краткий обзор альтернативных методов, таких как Admin SDK и Google Picker API.
Использование сервиса Session для получения имени пользователя
Сервис Session
предоставляет информацию о текущем сеансе пользователя, включая его идентификационные данные. Это наиболее прямой и часто используемый способ.
Метод Session.getActiveUser().getEmail()
: получение адреса электронной почты пользователя
Метод Session.getActiveUser().getEmail()
возвращает основной адрес электронной почты пользователя, запустившего скрипт. Это наиболее надежный способ идентификации пользователя в домене Google Workspace или обычного пользователя Gmail, так как email уникален.
/**
* Получает и логирует адрес электронной почты текущего активного пользователя.
*
* @returns {string | null} Адрес электронной почты пользователя или null, если пользователь не может быть определен.
*/
function logCurrentUserEmail(): string | null {
try {
const userEmail: string = Session.getActiveUser().getEmail();
if (userEmail) {
console.log(`Электронная почта текущего пользователя: ${userEmail}`);
return userEmail;
} else {
// Это может произойти в редких случаях или при определенных режимах авторизации
console.log('Не удалось получить email активного пользователя.');
return null;
}
} catch (e: any) {
// Ошибка может возникнуть, если скрипт выполняется в контексте,
// где нет активного пользователя (например, анонимный доступ к веб-приложению)
console.error(`Ошибка при получении email пользователя: ${e.message}`);
return null;
}
}
Важно отметить, что для вызова getEmail()
скрипту требуется разрешение script.scriptapp.getuserinfo.email
.
Метод Session.getActiveUser().getUsername()
: получение имени пользователя (может потребовать авторизации)
Метод Session.getActiveUser().getUsername()
возвращает имя пользователя, как оно определено в аккаунте Google. Для пользователей Google Workspace это обычно часть email до символа @
. Для обычных аккаунтов Gmail результат может совпадать с email.
/**
* Получает и логирует имя пользователя (username) текущего активного пользователя.
*
* @returns {string | null} Имя пользователя или null, если пользователь не может быть определен.
*/
function logCurrentUsername(): string | null {
try {
// Важно: getUsername() может не всегда возвращать уникальное значение
// и его поведение может отличаться для Workspace и Gmail аккаунтов.
const username: string = Session.getActiveUser().getUsername();
if (username) {
console.log(`Имя пользователя (username): ${username}`);
return username;
} else {
console.log('Не удалось получить имя пользователя (username).');
return null;
}
} catch (e: any) {
console.error(`Ошибка при получении username пользователя: ${e.message}`);
return null;
}
}
Использование getEmail()
обычно предпочтительнее для надежной идентификации.
Ограничения использования getActiveUser()
в различных контекстах (например, триггеры)
Методы getActiveUser()
имеют ограничения:
- Простые триггеры (
onOpen
,onEdit
и т.д.): В режимеAuthMode.LIMITED
, эти триггеры не могут вызывать сервисы, требующие авторизации, включаяSession.getActiveUser().getEmail()
. Вызов вернет пустую строку или вызовет ошибку. - Устанавливаемые триггеры (Installable Triggers): Если триггер установлен пользователем, скрипт будет выполняться от имени этого пользователя, и
getActiveUser()
вернет его данные. Если триггер настроен на запуск от имени разработчика, тоgetActiveUser()
вернет данные разработчика, а не пользователя, вызвавшего событие (например, редактирование ячейки). - Веб-приложения: В веб-приложениях, развернутых с настройкой «Execute as: Me» и «Who has access: Anyone»,
getActiveUser()
вернет данные владельца скрипта. Если выбрано «Execute as: User accessing the app», тоgetActiveUser()
вернет данные пользователя, открывшего приложение, но только если доступ разрешен не анонимным пользователям («Anyone, even anonymous» не позволит получить email). - Дополнения (Add-ons): Поведение зависит от модели авторизации дополнения.
Всегда учитывайте контекст выполнения скрипта при использовании getActiveUser()
.
Использование сервиса Properties для хранения и получения имени пользователя
В сценариях, где прямой вызов Session.getActiveUser().getEmail()
невозможен или нежелателен при каждом запуске (например, в простых триггерах или для оптимизации), можно использовать Properties Service
для кэширования email пользователя.
Сохранение имени пользователя в Properties Service при первом запуске скрипта
При первом запуске скрипта пользователем (например, через пользовательское меню, требующее авторизации), можно получить его email и сохранить его в UserProperties
.
/**
* Получает email текущего пользователя и сохраняет его в UserProperties,
* если он еще не сохранен.
*/
function storeUserEmailOnce(): void {
const userProperties: GoogleAppsScript.Properties.Properties = PropertiesService.getUserProperties();
const storedEmail: string | null = userProperties.getProperty('userEmail');
if (!storedEmail) {
try {
const currentUserEmail: string = Session.getActiveUser().getEmail();
if (currentUserEmail) {
userProperties.setProperty('userEmail', currentUserEmail);
console.log(`Email пользователя ${currentUserEmail} сохранен в UserProperties.`);
} else {
console.log('Не удалось получить email пользователя для сохранения.');
}
} catch (e: any) {
console.error(`Ошибка при получении или сохранении email: ${e.message}`);
}
}
}
Эту функцию можно вызвать из функции, которая гарантированно требует авторизации.
Получение имени пользователя из Properties Service при последующих запусках
В функциях, где прямой доступ к Session.getActiveUser().getEmail()
ограничен (например, onEdit
), можно попытаться извлечь сохраненный email из UserProperties
.
/**
* Получает email пользователя из UserProperties.
*
* @returns {string | null} Сохраненный email или null, если он не найден.
*/
function getStoredUserEmail(): string | null {
const userProperties: GoogleAppsScript.Properties.Properties = PropertiesService.getUserProperties();
const storedEmail: string | null = userProperties.getProperty('userEmail');
if (storedEmail) {
console.log(`Получен сохраненный email: ${storedEmail}`);
return storedEmail;
} else {
console.log('Email пользователя не найден в UserProperties.');
// Здесь можно инициировать процесс запроса авторизации и сохранения,
// если это уместно в данном контексте.
return null;
}
}
// Пример использования в onEdit (требует осторожности)
function onEdit(e: GoogleAppsScript.Events.SheetsOnEdit): void {
const userEmail: string | null = getStoredUserEmail();
if (userEmail) {
// Логика, использующая email пользователя
console.log(`Ячейка ${e.range.getA1Notation()} отредактирована пользователем (из Properties): ${userEmail}`);
} else {
// Обработка случая, когда email не сохранен (например, первый запуск)
console.log(`Ячейка ${e.range.getA1Notation()} отредактирована неизвестным пользователем (нет в Properties).`);
}
}
Преимущества и недостатки использования Properties Service для этой цели
Преимущества:
- Позволяет получить идентификатор пользователя в контекстах с ограниченной авторизацией (после первоначального сохранения).
- Уменьшает количество запросов авторизации, если email требуется часто.
Недостатки:
- Требуется первоначальный запуск с полной авторизацией для сохранения email.
UserProperties
хранятся для каждого пользователя отдельно. Данные не будут доступны, если скрипт выполняется от имени другого пользователя (например, через триггер, установленный администратором).- Не отражает реального текущего пользователя, если скрипт выполняется не от его имени (например, триггер, запускающийся от имени создателя триггера).
- Данные могут устареть, если пользователь изменит свой основной email (хотя это редкий случай).
Альтернативные способы получения имени пользователя
Существуют и другие, более специфичные методы.
Использование Admin SDK (если есть права администратора Google Workspace)
Администраторы домена Google Workspace могут использовать сервис AdminDirectory
(часть Advanced Google Services) для получения подробной информации о пользователях домена по их email, включая полное имя, должность и т.д. Это выходит за рамки получения текущего пользователя скрипта, но позволяет обогатить данные, полученные через Session.getActiveUser().getEmail()
.
/**
* Пример получения полного имени пользователя (требует прав администратора и включения Admin SDK).
*
* @param {string} email Адрес электронной почты пользователя.
* @returns {string | null} Полное имя пользователя или null при ошибке/отсутствии данных.
*/
function getUserFullNameByEmail(email: string): string | null {
// Необходимо включить Admin Directory API в Расширенных сервисах Google
try {
const user: GoogleAppsScript.AdminDirectory.Schema.User = AdminDirectory.Users.get(email);
if (user && user.name && user.name.fullName) {
return user.name.fullName;
}
return null;
} catch (e: any) {
console.error(`Не удалось получить данные пользователя ${email} через Admin SDK: ${e.message}`);
return null;
}
}
Получение имени пользователя через Google Picker API (требуется дополнительная настройка)
Google Picker API позволяет пользователю выбирать файлы из Google Drive, но также может быть использован для получения информации о пользователе, который взаимодействует с Picker. Это требует создания клиентского интерфейса (HTML Service) и сложной настройки, поэтому редко используется только для получения имени пользователя.
Заключение и рекомендации
Сравнение различных методов получения имени пользователя
Session.getActiveUser().getEmail()
: Самый надежный и прямой способ идентификации текущего пользователя. Требует соответствующей авторизации и имеет ограничения в определенных контекстах (простые триггеры).Session.getActiveUser().getUsername()
: Менее надежен для уникальной идентификации, но может быть полезен для отображения имени пользователя.Properties Service
: Хороший способ кэширования email для использования в ограниченных контекстах, но требует первоначального сохранения и не всегда отражает реального пользователя в текущем сеансе выполнения (особенно с триггерами).Admin SDK
: Мощный инструмент для администраторов Workspace для получения детальной информации о пользователях домена, но не для определения текущего пользователя скрипта без его email.Picker API
: Слишком сложен для простой задачи получения имени пользователя.
Рекомендации по выбору оптимального метода в зависимости от сценария использования
- Стандартные скрипты, пользовательские меню, диалоги: Используйте
Session.getActiveUser().getEmail()
. Это самый надежный идентификатор. - Простые триггеры (
onOpen
,onEdit
): Прямое получение email невозможно. Либо используйтеProperties Service
(с пониманием ограничений), либо переходите на устанавливаемые триггеры. - Устанавливаемые триггеры:
Session.getActiveUser().getEmail()
вернет email пользователя, установившего триггер. Если вам нужен email пользователя, вызвавшего событие (например, редактирование), этот метод не подойдет. В таких случаях можно записать email в ячейку или использоватьProperties Service
при редактировании, если email был сохранен ранее. - Веб-приложения: Используйте
Session.getActiveUser().getEmail()
при настройке «Execute as: User accessing the app» и доступе не для анонимных пользователей. - Административные задачи в Workspace: Используйте
Session.getActiveUser().getEmail()
для идентификации администратора, запускающего скрипт, иAdmin SDK
для получения данных о других пользователях.
Наиболее универсальным и рекомендуемым методом для идентификации пользователя, взаимодействующего со скриптом в рамках сессии с достаточными правами, остается Session.getActiveUser().getEmail()
.
Дополнительные ресурсы и полезные ссылки
Для более глубокого изучения рекомендуется обратиться к официальной документации Google Apps Script по сервисам Session
, PropertiesService
и AdminDirectory
.