Pau*_*gan 2 javascript webhooks google-sheets google-apps-script
我正在寻找一种巧妙的解决方案来消除或限制 Google Sheets Apps 脚本处理程序中使用的 webhook 调用。onEdit为其他更改创建一个简单的触发器或“可安装的触发器”很简单,但两者都会为每个更改调用处理程序。如果有人正在编辑工作表并在几秒钟内更新了许多行,我只想触发一个事件而不是淹没我的 webhook 服务。Javascript 中的常规模式是使用setTimeout并clearTimeout确保事件处理程序的主体仅被调用一次,但setTimeout在 Google Apps Script 运行时中不可用。
这是我的工作解决方案。它用于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)
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
372 次 |
| 最近记录: |