gpt4 book ai didi

javascript - Google Apps 脚本中的去抖动或限制事件处理程序

转载 作者:行者123 更新时间:2023-12-05 00:46:04 25 4
gpt4 key购买 nike

我正在寻找一种巧妙的解决方案来消除或限制 Google Sheets Apps 脚本处理程序中使用的 webhook 调用。为其他更改创建像 onEdit 这样的简单触发器或“可安装触发器”是直截了当的,但两者都会为每个更改调用处理程序。如果有人正在编辑工作表并在几秒钟内更新了许多行,我只想触发一个事件而不是淹没我的 webhook 服务。 Javascript 中的常规模式是使用 setTimeoutclearTimeout 来确保事件处理程序的主体只被调用一次,但 setTimeout 不会在 Google Apps 脚本运行时中可用。

最佳答案

这是我的工作解决方案。它使用 Utilities.sleep() 等待 10 秒,然后使用 ScriptProperties 检查此事件是否是在此期间调用的最后一个事件。

如果您想解决类似问题,请分享给其他人:

/*

Set the following project properties (File -> Project properties):

SheetsToWatch: comma separated list of sheets to watch for events
WebhookUrl: URL of web service to POST update to
WebhookToken: Authorization bearer token for POST request
SendLastValue: [optional] set if you wish last value in updated sheet to be posted


Then create the "installable trigger" (Edit -> Current project's triggers -> Add Trigger):

Choose which function to run: "handleChangeOrEdit"
Select event type: "On change" or "On edit"


A simple trigger like `onEdit` won't work have the privileges to call `UrlFetchApp.fetch`.

*/


function handleChangeOrEdit(event) {
var sheetId = event.source.getId();
var sheetUrl = event.source.getUrl();
var sheetName = (event.range ? event.range.getSheet() : SpreadsheetApp.getActiveSheet()).getName();

// Trigger only on those sheets we're configured to watch (or all if not specified)
var sheetsToWatch = PropertiesService.getScriptProperties().getProperty("SheetsToWatch");
if (sheetsToWatch && sheetsToWatch.split(",").indexOf(sheetName) == -1) {
return;
}

var eventId = Utilities.getUuid();
setEventTriggerWinner(eventId);
// OPTIONAL: You might want to save values from each edit here, to be dealt with by the "winner"
Utilities.sleep(10000); // Wait to see if another Change/Edit event is triggered
if (getEventTriggerWinner() == eventId) {
Logger.log(`Trigger Winner: ${eventId}`);
callWebhook({eventId, sheetId, sheetUrl, sheetName});
}
}

function setEventTriggerWinner(value) {
// Wrapping setProperty in a Lock probably isn't necessary since a set should be atomic
// but just in case...
var lock = LockService.getScriptLock();
if (lock.tryLock(5000)) {
PropertiesService.getScriptProperties().setProperty("eventTriggerWinner", value);
lock.releaseLock();
}
}

function getEventTriggerWinner() {
return PropertiesService.getScriptProperties().getProperty("eventTriggerWinner");
}

function callWebhook(data) {
var url = PropertiesService.getScriptProperties().getProperty("WebhookUrl");
var token = PropertiesService.getScriptProperties().getProperty("WebhookToken");
UrlFetchApp.fetch(url, {
headers: {"Authorization": `Bearer ${token}`},
method: "post",
contentType: "application/json",
payload: JSON.stringify(data)
});
}

关于javascript - Google Apps 脚本中的去抖动或限制事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62105238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com