Как исправить ошибку превышения максимального времени выполнения в скрипте электронной почты

Вопросы и ответы

Предыстория:

Я использую скрипт таймера для отправки электронных писем, когда выбирается запись. Имена и адреса электронной почты добавляются на страницу запросов. Скрипт проходит по любым именам в списке. Для любых имен, где поле “Уведомлен” пусто, он составляет письмо с некоторым индивидуальным текстом, а затем добавляет запись “Уведомлен” в поле таблицы. В следующий раз, когда скрипт будет запущен, он пропустит отправку письма этому человеку.

Скрипт запускается каждые 10 минут. Это связано с двумя причинами: (a) я хочу, чтобы пользователи имели минуту-две, чтобы отменить действия, если они случайно запросили неправильное имя, и (b) я не хочу дополнительно замедлять систему с помощью триггера на редактирование, когда у нее уже есть другие функции на редактирование, которые потребляют ресурсы.

Проблема:

У меня есть несколько различных таблиц, использующих одинаковую настройку, по одной для каждого пользователя. Каждый день я получаю сообщения об ошибках от многих из этих таблиц, информирующие меня о том, что в скрипте произошла ошибка “Превышено максимальное время”.

Я не знаю, почему это происходит, разве что слишком много скриптов выполняется одновременно. Тем не менее, скрипт довольно короткий, на странице запросов никогда не более 40 записей одновременно, и часто гораздо меньше; на самом деле, много раз ошибка возникает, когда записей для поиска вообще нет, например, посреди ночи или по выходным.

Я хочу оставить уведомления в случае, если скрипт вызовет постоянную ошибку, но, честно говоря, мне все равно, если он иногда будет терпеть неудачу; он все равно отправит следующее письмо. Однако я перегружен сообщениями об ошибках.

Желаемое решение:

Я хочу либо исправить код, чтобы улучшить производительность выполнения скрипта и избежать этих ошибок, либо найти способ добавить строку кода, чтобы тайм-аут скрипта происходил без генерации отчета об ошибках скрипта в таблице.

Код:

Функция отправки письма выглядит следующим образом:

function SendEmail2() {
var ss = SpreadsheetApp.getActiveSpreadsheet()
var sheet1 = ss.getSheetByName('Dumbledore requests page');
var data = sheet1.getDataRange().getValues();
var subject = "Приглашение на задержание";
for (var i = 1; i < data.length; i++) {
var email = data[i][9]; // Адрес электронной почты из столбца J
var notifiedStatus = data[i][10]; // Статус из столбца K
    if (email && !notifiedStatus) { 
      var studentName = data[i][0];
      var teacherName = data[i][3];
      var homeTeacher = data[i][2];
      var message = "Здравствуйте " + studentName + ",<br><br>Это письмо информирует вас о том, что у вас задержание с одним из ваших преподавателей (" + teacherName + "), во время вашего следующего свободного периода. Пожалуйста, свяжитесь с вашим куратором свободного периода (" + homeTeacher + ") сразу после обеда, или с вашим замещающим учителем, если таковой имеется, затем идите прямо в кабинет " + teacherName + ", как только вам скажут это сделать.<br><br>Спасибо.<br><br>С уважением,<br>таблица Спарка из Хогвартса";
      var replyTo = "[email protected]"; // Адрес электронной почты для ответа
  MailApp.sendEmail({
        to: email,
        subject: subject,
        htmlBody: message,
        replyTo: replyTo
      });
  sheet1.getRange(i + 1, 11).setValue("Уведомлен");}}
}

Вопрос:

Как мне оптимизировать код для повышения его эффективности и устранить эти ошибки, или же позволить ему корректно завершить работу, не создавая отчета об ошибке тайм-аута?

Спасибо!

Ответ

Как исправить ошибку "превышено максимальное время" в скрипте отправки электронных писем

Предпосылки:
Ваша текущая ошибка "превышено максимальное время" может возникать из-за нескольких причин, включая количество записей, с которыми обрабатывает скрипт, время выполнения обработки и саму структуру кода. Поскольку скрипт может занимать слишком много времени при выполнении, давайте оптимизируем его.

Решение:

  1. Оптимизация цикла: Избегайте вызова setValue в каждом проходе цикла. Вместо этого собирайте все значения, которые нужно установить в массив, и устанавливайте их за один раз после завершения обработки всех данных.

  2. Проверка объема данных: На случай, если данных нет, добавьте проверку перед выполнением всей логики.

  3. Исключение лишних строк кода: Многие вызовы API требуют времени на выполнение. Мы можем минимизировать их количество.

Отредактированный код может выглядеть следующим образом:

function SendEmail2() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet1 = ss.getSheetByName('Dumbledore requests page');
    var data = sheet1.getDataRange().getValues();
    var subject = "Detention appointment";
    var notifiedStatusUpdates = []; // Массив для хранения обновлений статуса

    for (var i = 1; i < data.length; i++) {
        var email = data[i][9]; // Электронная почта из столбца J
        var notifiedStatus = data[i][10]; // Статус из столбца K

        if (email && !notifiedStatus) { 
            var studentName = data[i][0];
            var teacherName = data[i][3];
            var homeTeacher = data[i][2];
            var message = "Hello " + studentName + ",<br><br>This email is to inform you that you have a detention with one of your professors (" + teacherName + "), during your next free period. Check in with your free period supervisor (" + homeTeacher + ") immediately after your lunch, or your substitute teacher if there is one, then go straight to " + teacherName + "'s room as soon as you're told to do so.<br><br>Thank you.<br><br>Sincerely,<br>the Hogwarts Spreadsheet";
            var replyTo = "your_email@example.com"; // Замените своим адресом

            MailApp.sendEmail({
                to: email,
                subject: subject,
                htmlBody: message,
                replyTo: replyTo
            });

            notifiedStatusUpdates.push([i + 1, "Notified"]); // Сохраняем данные для обновления
        }
    }

    // Обновление статуса "Notified" в одном вызове
    for (var j = 0; j < notifiedStatusUpdates.length; j++) {
        sheet1.getRange(notifiedStatusUpdates[j][0], 11).setValue(notifiedStatusUpdates[j][1]);
    }
}

Объяснение внесенных изменений:

  • Вместо немедленного обновления значения "Notified", мы собираем все обновления в массив notifiedStatusUpdates и затем применяем все изменения за один проход. Это значительно снижает количество обращений к API.

  • Проверка, есть ли записи для обработки, таким образом браузер не будет ожидать ненужные данные.

  • Убедитесь, что адрес replyTo заменен на актуальный.

Другие рекомендации:

  1. Периодическая проверка: Убедитесь, что скрипт запускается не слишком часто. Если вы заметили, что количество данных часто уменьшается, вы можете подумать о более длительных интервалах запуска.

  2. Обработка ошибок: Если вы все еще получаете ошибки, оберните основной код в try-catch блок для обработки исключений и чтобы избежать уведомлений, если ошибка не критична.
try {
    // основной код
} catch (e) {
    Logger.log('Произошла ошибка: ' + e.message);
    // возможно, необходимо решить, что делать с ошибкой
}

Эти изменения помогут вам оптимизировать код и, в конечном счете, уменьшить количество ошибок "Maximum time exceeded".

Оцените материал
Добавить комментарий

Капча загружается...