如何在另一个文档上创建新的时钟触发器 [英] How to create a new clock trigger on another document

查看:121
本文介绍了如何在另一个文档上创建新的时钟触发器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有30多个用户,每个用户都有自己的电子表格.每个用户的绑定脚本都引用了一个自定义库脚本,我使用该脚本可以使代码集中并易于更新.

I have 30+ users each with their own spreadsheet. Each user's bound script references a custom library script that I use to keep my code centralized and easy to update.

我正在尝试使用应用程序脚本来创建在特定时间运行特定功能的触发器.但是,我不知道如何指定安装时钟触发器的脚本文件.

I'm trying to use apps script to create triggers that run a specific function at a specific time. However, I can't figure out how to specify which script document the clock trigger is installed on.

这是我首先尝试的方法:

Here's what I tried first:

createTimeTrigger("sendTimesheetsToHeads",1440);

function createTimeTrigger(functionToRun,minutesToWait) {
  ScriptApp.newTrigger(functionToRun)
  .timeBased()
  .at(new Date(new Date().getTime()+minutesToWait*60*1000))
  .create();
}

以上代码位于库文件中,但是由于用户正在运行该代码,因此它将触发器安装在用户的容器绑定脚本文件上,而不是库文件上.触发器运行时失败,因为触发器使用了用户没有直接引用的库中的函数.

The above code is in the library file, but since the user is running the code, it installs the trigger on the user's container-bound script file, and not the library file. When the trigger runs, it fails because the trigger uses a function in the library that the user doesn't have direct reference to.

我需要能够以编程方式在独立的库脚本文件上安装触发器,就像我可以手动执行的一样.因此,在查看了应用程序脚本文档之后( https://developers.google.com/apps-script/reference/script/trigger-builder#forDocument(String)),我找到了触发器生成器的forDocument()函数,并尝试了以下方法:

I need to be able to install the trigger programmatically on the independent library script file just like I can do manually. So after reviewing the apps script documentation (https://developers.google.com/apps-script/reference/script/trigger-builder#forDocument(String)), I found the forDocument() function for the trigger builder and tried this:

createTimeTrigger("sendTimesheetsToHeads",1440);

function createTimeTrigger(functionToRun,minutesToWait) {
  ScriptApp.newTrigger(functionToRun)
  .forDocument(<library script id here>)
  .timeBased()
  .at(new Date(new Date().getTime()+minutesToWait*60*1000))
  .create();
}

但是上面的代码产生以下错误:"TypeError:在对象DocumentTriggerBuilder中找不到函数timeBase."

But the above code produces the following error: "TypeError: Cannot find function timeBased in object DocumentTriggerBuilder."

因此,我尝试切换顺序:

So then I tried switching the order around:

function createTimeTrigger(functionToRun,minutesToWait) {
  ScriptApp.newTrigger(functionToRun)
  .timeBased()
  .at(new Date(new Date().getTime()+minutesToWait*60*1000))
  .forDocument(<library script id here>)
  .create();
}

并收到此错误:"TypeError:在对象ClockTriggerBuilder中找不到文档的函数".看起来触发器构造器中的forDocument()和timeBased()函数不兼容吗?

And received this error: "TypeError: Cannot find function forDocument in object ClockTriggerBuilder." It looks like the forDocument() and timeBased() functions are incompatible in the trigger builder?

是否可以使用我的应用脚本来完成我所要求的?

Is it possible to do what I'm asking with apps script?

推荐答案

请查看 TriggerBuilder引用再次-您的函数createTimeTrigger()应该创建两个触发器,一个使用timeBased(),另一个使用forDocument().这两种方法在调用时分别返回不同的类实例-ClockTriggerBuilderDocumentTriggerBuilder(因此,第一个问题的答案是-是,它们不兼容.

Please, take a look at the TriggerBuilder reference again - your function createTimeTrigger() should create two triggers, one with timeBased() and the other with forDocument(). Both methods, when invoked, return different class instances - ClockTriggerBuilder and DocumentTriggerBuilder respectively (so, the answer to your first question is - yes, they are incompatible.

第一种方法假设您有权访问用户文档的apps脚本项目,或者可以向文档中添加wrapperInDoc()函数(此解决方案将保留,以防有人需要):

First approach assumes you have access to user document's apps script project or can otherwise add the wrapperInDoc() function to the document (this solution is retained in case someone needs it):

  1. 用户以运行您的库脚本yourLib.createTimeTrigger();
  2. 要在用户文档上安装的基于时间的触发器
  3. 基于时间的 触发器在库中触发函数;
  1. the user to run your library script yourLib.createTimeTrigger();
  2. the time-based trigger to be installed on user document;
  3. the time-based trigger to fire a function in library;

您的库函数应该创建一个触发器,以运行包装器函数,该触发器的名称对于在库中引用 target函数的所有用户文档都是通用的.像这样:

Your library function should create a trigger to run wrapper function with a name common for all user documents that references target function in your library. Like so:

图书馆范围的样本

function createTimeTrigger(functionToRun,minutesToWait) {
  ScriptApp.newTrigger('wrapperInDoc').timeBased().at(yourCond).create();
}

function wrapperInLib() {
  sendTimesheetsToHeads(); //function calls go here;
}

文档范围的示例

function wrapperInDoc() {
  yourLib.wrapperInLib();
}

自调用库

正如评论中所阐明的,您想要:

Self-calling library

As clarified in comments, you want:

  1. 用户以运行您的库脚本yourLib.createTimeTrigger();
  2. createTimeTrigger()yourLib上安装基于的基于时间的触发器
  3. 基于时间的 触发器在库中触发函数;
  1. the user to run your library script yourLib.createTimeTrigger();
  2. createTimeTrigger() to install the time-based trigger on yourLib;
  3. the time-based trigger to fire a function in library;

容器绑定的样本

function testLib() {
 var r = PG.createTimeTrigger(); //PG is how I named lib in my project;
 //do anything else;
}

图书馆样本

我设置了从现在"到触发器的1分钟任意偏移量,只需根据需要创建触发器即可.另外,请确保您的脚本以WebApp的形式发布,并且任何人都可以访问,甚至可以匿名访问(在您将其用作库时也可以).您应该使用部署Url进行抓取(使用/exec的抓取).

I set an arbitrary offset of 1 minute from "now" to trigger, just create your trigger as needed. Also, make sure that your script is published as a WebApp and anyone, even anonymous access is set on it (which should be ok as you use it as a library). You should use deployment Url for the fetch (the one with /exec).

/**
 * Runs on a get request;
 * @param {Object} e event object;
 * @returns {Content} text output to conform to being a web app;
 */
function doGet(e) {
  createTrigger();
  return ContentService.createTextOutput('success!');
}

/**
 * Self-run library project;
 */
function createTimeTrigger() {
  UrlFetchApp.fetch('yourLibraryUrl');
}

/**
 * Create trigger on self;
 */
function createTrigger() {
  var tr = ScriptApp.newTrigger('doSomething');
      tr.timeBased().at(new Date(new Date().valueOf()+60000)).create();
}

/**
 * Actual trigger callback;
 */
function doSomething() {
  //do something;
}

这篇关于如何在另一个文档上创建新的时钟触发器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆