Правильно ли настроен триггер в Google Sheets для ежедневного выполнения скрипта?
Я создал скрипт в Google Таблицах, который должен автоматически выводить значение ячейки каждый день. Скрипт, кажется, работает правильно, но триггер, настроенный на выполнение в 9:00 ежедневно, не активируется. Можете помочь определить, что не так?
Вот код скрипта:
/**
*
*/
function createTrigger() {
ScriptApp.getProjectTriggers().forEach(
(trigger) =>
trigger.getHandlerFunction() === 'saveData' &&
trigger.getEventType() === ScriptApp.EventType.CLOCK &&
(ScriptApp.deleteTrigger(trigger) ||
console.info(`Tirgger ${trigger.getUniqueId()} was deleted`))
);
// every minutes for testing
// ScriptApp.newTrigger('saveData').timeBased().everyMinutes(1).create();
// at 17 o'clock every days
ScriptApp.newTrigger('saveData').timeBased().atHour(9).everyDays(1).create();
}
/**
*
*/
function saveData() {
const book = SpreadsheetApp.openById(
'1a32sJMp-zd7boprGAqAyw68fWpxtuzQmowdjjHTVwQk'
);
const sheet = book.getSheetByName('Лист2');
const value = sheet.getRange('M4').getValue();
book.getSheetByName('Лист5').appendRow([new Date(), value]);
console.info(`saveData was called successful`);
}
Что нужно исправить, чтобы скрипт выполнялся автоматически каждый день в указанное время?
Основная проблема заключается в отсутствии настройки часового пояса и метода nearMinute() в конфигурации триггера. Ваш скрипт не выполняется автоматически, потому что триггер использует системный часовой пояс без указания точной минуты выполнения, что приводит к расхождениям во времени.
Содержание
- Основные проблемы с триггерами в Google Apps Script
- Настройка часового пояса для триггера
- Использование метода nearMinute()
- Проверка и отладка существующих триггеров
- Решение: исправленный код скрипта
- Дополнительные проверки и рекомендации
- Источники
Основные проблемы с триггерами в Google Apps Script
Ваш код содержит несколько распространенных ошибок, из-за которых триггер не работает правильно:
- Отсутствие настройки часового пояса - Триггеры используют системный часовой пояс Google Apps Script, который может отличаться от часового пояса вашей таблицы
- Нет метода
nearMinute()- Без указания точной минуты выполнения триггер может срабатывать с отклонением до ±15 минут - Некорректная логика удаления триггеров - Ваша функция удаления может не работать должным образом
Как указано в документации Google, неверная строка часового пояса вызывает ошибку выполнения скрипта.
Настройка часового пояса для триггера
Самая распространенная проблема с триггерами - это несоответствие часовых поясов. Google Таблицы и Google Apps Script могут использовать разные часовые пояса по умолчанию.
// Неправильно - без указания часового пояса
ScriptApp.newTrigger('saveData').timeBased().atHour(9).everyDays(1).create();
// Правильно - с указанием часового пояса
ScriptApp.newTrigger('saveData')
.timeBased()
.atHour(9)
.everyDays(1)
.inTimezone('Europe/Moscow') // Укажите ваш часовой пояс
.create();
Важно использовать корректные строки часового пояса в формате IANA (например, ‘Europe/Moscow’, ‘America/New_York’). Как отмечено на Stack Overflow, метод inTimezone() является обязательным для точной настройки времени выполнения.
Использование метода nearMinute()
Метод nearMinute() критически важен для точного времени выполнения триггера. Без него Google Apps Script добавляет случайное отклонение до ±15 минут.
// Неправильно - без указания минуты
ScriptApp.newTrigger('saveData')
.timeBased()
.atHour(9)
.everyDays(1)
.inTimezone('Europe/Moscow')
.create();
// Правильно - с указанием конкретной минуты
ScriptApp.newTrigger('saveData')
.timeBased()
.atHour(9)
.nearMinute(0) // Выполнять ровно в 9:00
.everyDays(1)
.inTimezone('Europe/Moscow')
.create();
Согласно официальной документации, метод nearMinute() определяет минуту выполнения (плюс-минус 15 минут). Если этот метод не вызывается, используется случайное значение минуты.
Проверка и отладка существующих триггеров
Ваша функция createTrigger() имеет логическую ошибку в условии удаления. Текущая реализация может не работать корректно:
// Проблемный код
ScriptApp.getProjectTriggers().forEach(
(trigger) =>
trigger.getHandlerFunction() === 'saveData' &&
trigger.getEventType() === ScriptApp.EventType.CLOCK &&
(ScriptApp.deleteTrigger(trigger) ||
console.info(`Tirgger ${trigger.getUniqueId()} was deleted`))
);
Исправленная версия:
function createTrigger() {
// Получаем все триггеры проекта
const triggers = ScriptApp.getProjectTriggers();
// Удаляем существующие триггеры для saveData
triggers.forEach((trigger) => {
if (trigger.getHandlerFunction() === 'saveData' &&
trigger.getEventType() === ScriptApp.EventType.CLOCK) {
ScriptApp.deleteTrigger(trigger);
console.info(`Trigger ${trigger.getUniqueId()} was deleted`);
}
});
// Создаем новый триггер
ScriptApp.newTrigger('saveData')
.timeBased()
.atHour(9)
.nearMinute(0)
.everyDays(1)
.inTimezone('Europe/Moscow') // Укажите ваш часовой пояс
.create();
console.info('New trigger created successfully');
}
Решение: исправленный код скрипта
Вот полная исправленная версия вашего скрипта с учетом всех проблем:
/**
* Создает или обновляет триггер для ежедневного выполнения скрипта
*/
function createTrigger() {
// Удаляем существующие триггеры для saveData
const triggers = ScriptApp.getProjectTriggers();
triggers.forEach((trigger) => {
if (trigger.getHandlerFunction() === 'saveData' &&
trigger.getEventType() === ScriptApp.EventType.CLOCK) {
ScriptApp.deleteTrigger(trigger);
console.info(`Trigger ${trigger.getUniqueId()} was deleted`);
}
});
// Создаем новый триггер на 9:00 ежедневно с указанием часового пояса
ScriptApp.newTrigger('saveData')
.timeBased()
.atHour(9)
.nearMinute(0) // Точное время без отклонения
.everyDays(1)
.inTimezone('Europe/Moscow') // ВАЖНО: Укажите ваш часовой пояс
.create();
console.info('New trigger created for 9:00 daily');
}
/**
* Основная функция для сохранения данных
*/
function saveData() {
try {
const book = SpreadsheetApp.openById(
'1a32sJMp-zd7boprGAqAyw68fWpxtuzQmowdjjHTVwQk'
);
const sheet = book.getSheetByName('Лист2');
const value = sheet.getRange('M4').getValue();
book.getSheetByName('Лист5').appendRow([new Date(), value]);
console.info(`saveData executed successfully at ${new Date()}`);
} catch (error) {
console.error(`Error in saveData: ${error.message}`);
// Отправка уведомления об ошибке
MailApp.sendEmail('your-email@example.com', 'Google Apps Script Error',
`Error in saveData: ${error.message}\nStack: ${error.stack}`);
}
}
Дополнительные проверки и рекомендации
-
Проверка квоты потребителя: Если у вас потребительский аккаунт Google, общий лимит времени выполнения всех триггеров составляет 90 минут в день. Как отмечено на Stack Overflow, превышение этого лимита может приводить к пропуску выполнения.
-
Проверка часового пояса таблицы: Убедитесь, что часовой пояс в настройках Google Таблицы совпадает с указанным в триггере. Настройки часового пояса таблицы можно изменить в меню
Файл → Настройки таблицы. -
Тестирование триггера: Для тестирования используйте минутный триггер:
// Временный триггер для тестирования
ScriptApp.newTrigger('saveData').timeBased().everyMinutes(1).create();
-
Проверка журналов выполнения: Проверяйте журналы выполнения скрипта в разделе
Выполнение → Триггерыредактора Apps Script. -
Обработка ошибок: Добавьте обработку ошибок в функцию
saveData()для отслеживания проблем. -
Проверка прав доступа: Убедитесь, что у скрипта есть необходимые разрешения на доступ к таблице.
Источники
- Class ClockTriggerBuilder | Apps Script | Google for Developers
- Setting the Timezone for timed triggers - Stack Overflow
- Time-Driven triggers not working properly - Stack Overflow
- Google Apps Script Simple Time Triggers - YouTube
- Change the time zone of your Google Apps Script Project - Yagisanatode
Заключение
Основные проблемы в вашем скрипте были связаны с отсутствием настройки часового пояса и метода nearMinute(). Для исправления:
- Добавьте метод
.inTimezone('Europe/Moscow')с указанием вашего часового пояса - Используйте метод
.nearMinute(0)для точного времени выполнения - Исправьте логику удаления существующих триггеров
- Добавьте обработку ошибок в основную функцию
- Проверьте лимиты выполнения для вашего типа аккаунта
После этих изменений триггер должен корректно запускать скрипт каждый день в 9:00 указанного часового пояса.