【问题标题】:How can I pass a parameter to a time-based Google App Script trigger?如何将参数传递给基于时间的 Google App Script 触发器?
【发布时间】:2015-12-18 07:07:18
【问题描述】:

在我的脚本中,我从电子表格中读取数据并创建一个基于时间的触发器,以便在特定时间使用其中一些数据发出 POST 请求。

问题是,我找不到任何方法将数据传递给触发器调用的函数。 Google App Script 文档提供的所有功能是能够命名要调用的函数,但无法传递参数。

 var triggerDay = new Date(2012, 11, 1);
 ScriptApp.newTrigger("makePostRequest")
   .timeBased()
   .at(triggerDay)
   .create();

有谁知道我如何传递makePostRequest 参数以便函数使用所需的数据执行?

【问题讨论】:

    标签: javascript google-apps-script triggers parameter-passing


    【解决方案1】:

    从触发器启动函数时,不能传递参数。

    您必须将此信息存储在某处以允许脚本找到它。例如,您所说的我了解您在电子表格中有一些数据,您可以将这些信息放入电子表格中。该函数将根据触发时间管理查找适当信息的方式。

    史蒂芬

    【讨论】:

    • 这让事情变得非常复杂。真可惜。不过还是谢谢你的回答
    • 这个答案是唯一的方法。为简化起见,您可以使用触发器 ID 并将其存储在脚本属性中作为地图名称
    • 如果参数只有几个可能的值(例如:WEEK、MONTH、YEAR),你可以做的就是创建 3 个函数 fooWeek()、fooMonth( ) 和 fooYear() 并为它们中的每一个设置不同的触发器。
    • 对我来说,问题是我需要通过触发器将参数传递给函数,这样我才能判断函数是否自动触发。知道有什么方法吗?
    • 嗨,当一个函数被触发器触发时,会有一个事件发送到该函数。例如函数(e),如果它由“e”中的触发器运行,您将找到触发器 id,例如,如果手动启动,则“e”中没有值。检查文档:developers.google.com/apps-script/guides/triggers/events
    【解决方案2】:

    我不确定它是否能解决您的具体问题,但我发现最方便的解决方法是将一个带有参数的函数包装在一个没有参数的函数中,然后从一个静态变量中获取参数您在脚本的顶层设置。

    您仍然需要在脚本中设置值,但至少您可以将逻辑分开,以便您可以使用具有不同值的基本函数。

    function functionAToTrigger(){
      functionToTriggerWithParams(myAParams);
    }
    var myAParams = {
      url: 'https://aurl.com',
      date: new Date(2012, 11, 1)
    };
    function functionBToTrigger(){
      functionToTriggerWithParams(myBParams);
    }
    var myBParams = {
      url: 'https://burl.com',
      date: new Date(2017, 11, 1)
    };
    function functionToTriggerWithParams(myParams){
       // Add some code to run some checks
       // Add some code here to log the results
    }
    ScriptApp.newTrigger(functionAToTrigger).timeBased().everyMinutes(10).create();
    ScriptApp.newTrigger(functionBToTrigger).timeBased().everyMinutes(10).create();
    

    【讨论】:

      【解决方案3】:

      triggerDay 是一个Trigger,它有uniqueidmakePostRequest 的第一个参数是 Time-driven event,它具有未记录的属性“triggerUid” , 因此,正如@St3ph 所说,您需要以某种方式存储“uniqueid”和“parameters”,并通过“triggerUid”从存储中获取它

      【讨论】:

        【解决方案4】:

        这是可能的,但需要多个步骤。这里最重要的是event objects(@St3ph 提到)。

        var RECURRING_KEY = "recurring";
        var ARGUMENTS_KEY = "arguments";
        
        /**
         * Sets up the arguments for the given trigger.
         *
         * @param {Trigger} trigger - The trigger for which the arguments are set up
         * @param {*} functionArguments - The arguments which should be stored for the function call
         * @param {boolean} recurring - Whether the trigger is recurring; if not the 
         *   arguments and the trigger are removed once it called the function
         */
        function setupTriggerArguments(trigger, functionArguments, recurring) {
          var triggerUid = trigger.getUniqueId();
          var triggerData = {};
          triggerData[RECURRING_KEY] = recurring;
          triggerData[ARGUMENTS_KEY] = functionArguments;
        
          PropertiesService.getScriptProperties().setProperty(triggerUid, JSON.stringify(triggerData));
        }
        
        /**
         * Function which should be called when a trigger runs a function. Returns the stored arguments 
         * and deletes the properties entry and trigger if it is not recurring.
         *
         * @param {string} triggerUid - The trigger id
         * @return {*} - The arguments stored for this trigger
         */
        function handleTriggered(triggerUid) {
          var scriptProperties = PropertiesService.getScriptProperties();
          var triggerData = JSON.parse(scriptProperties.getProperty(triggerUid));
        
          if (!triggerData[RECURRING_KEY]) {
            deleteTriggerByUid(triggerUid);
          }
        
          return triggerData[ARGUMENTS_KEY];
        }
        
        /**
         * Deletes trigger arguments of the trigger with the given id.
         *
         * @param {string} triggerUid - The trigger id
         */
        function deleteTriggerArguments(triggerUid) {
          PropertiesService.getScriptProperties().deleteProperty(triggerUid);
        }
        
        /**
         * Deletes a trigger with the given id and its arguments.
         * When no project trigger with the id was found only an error is 
         * logged and the function continues trying to delete the arguments.
         * 
         * @param {string} triggerUid - The trigger id
         */
        function deleteTriggerByUid(triggerUid) {
          if (!ScriptApp.getProjectTriggers().some(function (trigger) {
            if (trigger.getUniqueId() === triggerUid) {
              ScriptApp.deleteTrigger(trigger);
              return true;
            }
        
            return false;
          })) {
            console.error("Could not find trigger with id '%s'", triggerUid);
          }
        
          deleteTriggerArguments(triggerUid);
        }
        
        /**
         * Deletes a trigger and its arguments.
         * 
         * @param {Trigger} trigger - The trigger
         */
        function deleteTrigger(trigger) {
          ScriptApp.deleteTrigger(trigger);
          deleteTriggerArguments(trigger.getUniqueId());
        }
        
        function example() {
          var trigger = ScriptApp.newTrigger("exampleTriggerFunction").timeBased()
            .after(5 * 1000)
            .create();
        
          setupTriggerArguments(trigger, ["a", "b", "c"], false);
        }
        
        function exampleTriggerFunction(event) {
          var functionArguments = handleTriggered(event.triggerUid);
          console.info("Function arguments: %s", functionArguments);
        }
        

        如果您将脚本属性也用于其他值,您可能必须嵌套触发器值。

        此外,您可能必须使用script lock 来防止同时修改脚本属性。

        【讨论】:

        • 哇,谢谢,这对我非常有用,因为我正在使用 Google Scripts 构建很多东西!
        猜你喜欢
        • 2017-09-21
        • 2019-07-16
        • 2023-03-03
        • 1970-01-01
        • 2020-06-14
        • 1970-01-01
        • 1970-01-01
        • 2022-11-11
        • 2011-07-14
        相关资源
        最近更新 更多