GAS передает переменные триггерам, основанным на времени

У меня есть таблица Google с onEdit() триггером для создания второго триггера.

Проще говоря: когда столбец статуса изменяется на «Утверждено», создается триггер для отправки электронного письма с обратной связью в указанную дату завершения проекта.

var oneTimeOnly = ScriptApp.newTrigger("emailFeedback").timeBased().at(endDate).create();

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

Когда я вставляю какие-либо дополнительные символы в кавычки newTrigger, это приводит к тому, что все содержимое функции сохраняется в триггере (который впоследствии терпит неудачу).

var oneTimeOnly = ScriptApp.newTrigger("emailFeedback<strong>(regEmail)</strong>").timeBased().at(endDate).create();

.

Есть ли способ сохранить переменную внутри триггера?


person Eoin    schedule 20.07.2012    source источник
comment
‹Snicker› ГАЗ проходит ‹/snicker›   -  person j08691    schedule 13.03.2013


Ответы (5)


Используя ScriptDB и новую функцию (), я смог создать метод для создания динамических функций триггера.

Суть решения состоит в том, чтобы сохранить код, который вы хотите запустить, - это база данных с параметрами, которые вы хотите передать:

"myFunction('Hello world')"

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

globalFunctions.callThisOne = new Function("e", "myFunction("Hello world"));

Наконец, когда вы создаете свой триггер, вы создали его, используя глобально доступную функцию как таковую:

ScriptApp.newTrigger("globalFunctions.callThisOne").timeBased().everyDay(1).create();

Я написал небольшой пост об этом и разместил источник. Надеюсь, это будет полезно.

Подробнее об этом можно прочитать здесь: http://goo.gl/wbUqH6.

Или посмотрите код здесь: http://goo.gl/zjUiYe

person fooby    schedule 26.08.2013
comment
Это сработало, но похоже, что команда GAS удалила возможность вызова функций так, как я описал. - person fooby; 28.08.2013
comment
Я еще не проверял это, но теория выглядит здравой. Будет здорово, если заработает! :) - person John; 21.02.2014

К сожалению, это невозможно.

person Corey G    schedule 20.07.2012

Как я правильно понимаю, вопрос заключался в том, как передать данные в функцию, запускаемую по времени в проекте скрипта Google. Эоин описал ситуацию, но вы можете столкнуться со многими. Классическая ситуация, когда ваш скрипт обрабатывает сложную электронную таблицу, которая может работать долгие минуты. Как вы, наверное, знаете, каждый сценарий имеет ограничение по времени выполнения около 6 минут. В этой ситуации вам следует разбить свой сценарий на более мелкие логические разделы, и в конце каждого из них можно создать новый триггер для следующей части. Хорошо, но следующая часть должна знать некоторые данные переменных текущего запущенного скрипта. Поскольку нет возможности передать эти данные через newTrigger (), вы можете создать моментальный снимок и поместить его в контекст свойства скрипта сериализованным способом. Простой способ сделать это с помощью ScriptProperties.setProperty ().

person Rix Beck    schedule 14.03.2013

Используйте ScriptProperties.setProperty () для хранения сериализованных параметров, к которым можно получить доступ с помощью метода триггера.

person user2166613    schedule 13.03.2013
comment
Не могли бы вы указать контекст, в котором вам нужно установить это свойство? - person Qpirate; 13.03.2013

@ user2166613 прав, но немного короче. Вот как это сделать.

Я показываю пример, в котором используется триггер after (). Это действительно интересный вариант использования, поскольку он позволяет отделить трудоемкие задачи, например, от вызовы веб-приложения, поэтому вызовы немедленно возвращают управление, а обработка выполняется в фоновом режиме.

В моем примере я адаптирую ширину столбцов листа в функции, выполнение которой задерживается.

// call this function to set a time based trigger and transfer parameters
function setTimeTrigger_AdaptColumnWidths() {  
  var ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
  var wsId = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getSheetId();

  var scriptProperties = PropertiesService.getScriptProperties();
  scriptProperties.setProperty('spreadsheetId', ssId);
  scriptProperties.setProperty('worksheetId', wsId);

  // Delay 10 secs, but real execution time may vary up to 15 min!
  ScriptApp.newTrigger('adaptColumnWidths').timeBased().after(10000).create();  
}

// this function is called by the trigger
function adaptColumnWidths() {  
  var scriptProperties = PropertiesService.getScriptProperties();
  ssId = scriptProperties.getProperty('spreadsheetId');
  wsId = scriptProperties.getProperty('worksheetId');

  // getSheetById() is a custom function – see below – not yet in Spreadsheet Class!
  sheet = getSheetById(SpreadsheetApp.openById(ssId), wsId);  

  // now do what we want to do in the timeBased trigger
  for (var i = 1; i <= sheet.getLastColumn(); i++){
    sheet.autoResizeColumn(i);
  }
}

// -----

// custom function – hopefully this will become a method of Spreadsheet Class any time soon
function getSheetById(ss, wsId) {
  var sheets = ss.getSheets();
  for (var i=0; i<sheets.length; i++) {
    if (sheets[i].getSheetId() == wsId)  return sheets[i];
  }
}

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

В моем случае это не проблема, так как таблица и рабочий лист не изменятся. Но НЕ пытайтесь передавать данные, которые могут меняться от звонка к звонку.

Реальный момент выполнения может варьироваться до 15 минут (независимо от того, какое точное время вы запрашиваете), поэтому есть много места для нескольких вызовов функций, которые могут мешать друг другу !!!

person Jpsy    schedule 26.02.2016