Google Apps 脚本正在创建日历项两次
Google Apps Script is creating calendar entry twice
我混合了一个 Google Apps 脚本来根据我 Google sheet 中的值在日历中创建一个事件。该脚本应在以下条件下工作:
- 每当添加新行时(通过触发器实现 - 第一个函数)
- 仅适用于跨页的最后一行sheet
- 仅当“id”单元格 (28) 为空时才创建事件
然后应创建日历事件并使用事件 ID 填充单元格 28。
客户在我的网站上填写表格时会创建新行。我在 WordPress 中使用 Ninja Forms,它有一个 Google Sheets 插件。所以填写的表格会自动添加到 sheet,然后这个函数会触发。
一切都几乎正常工作。当我手动测试时(例如,我删除了最后一行中的 id 单元格,或者我创建了一个新行或复制了一个现有行),它工作得很好。如果单元格 28 中已经没有事件 ID,则 仅 会创建事件,并且它会使用该 ID 成功填充单元格 28。太棒了!
但是,当使用 WordPress 表单创建行时,我得到 两个 日历事件。 IE - 就像函数运行了两次。每个事件都是相同的,并且都是同时创建的。
我猜这与表单如何与 sheet 集成有关。它以某种方式触发了我的功能两次。我尝试在函数的不同点使用 Utilities.sleep 和不同的值来查看在 strps 之间等待是否有帮助,但无济于事。
谁能想出办法阻止这种情况发生?是否有某种检查可以内置到我的函数中?还是我错过了一些明显的东西?我真的很感激任何建议。
这是我的代码:
function initializeTrigger(){ // run once only to create the trigger
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("NewCalEvent")
.forSpreadsheet(sheet)
.onChange()
.create();
}
function NewCalEvent() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Bookings2');
var row = sheet.getLastRow();
var calId = "xxxyyy@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
var date = sheet.getRange(row, 1).getValue();
var title = sheet.getRange(row, 26).getValue();
var tz = sheet.getRange(row, 23).getValue();
var tstart = new Date(sheet.getRange(row, 32).getValue());
var tstop = new Date(sheet.getRange(row, 33).getValue());
var loc = sheet.getRange(row, 2).getValue();
var desc = sheet.getRange(row, 27).getValue();
var guests = sheet.getRange(row, 29).getValue();
var id = sheet.getRange(row, 28).getValue();
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
可能的解决方案:
添加检查以查看是否已为此时创建日历事件。
更多信息:
由于不清楚这个触发器重复的确切来源,一种避免事件被创建两次的方法是在日历中搜索指定时间范围的事件,其中包含您打算输入的描述,并且然后将事件创建代码包装在检查中,这样如果事件尚不存在,它只会 运行s。
代码片段:
// ...
var id = sheet.getRange(row, 28).getValue();
var events = cal.getEvents(tstart, tstop, {search: desc})
.map(function(e) {
try {
return e.getDescription();
}
catch {
return "";
}
});
if (!events.includes(desc)) {
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop,
{description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
这样,如果脚本是运行两次,那么由于第二次事件已经存在,所以不会再创建。
注意: 这会检查在时间范围 tstart
到 tstop
内是否存在所有具有 desc
描述的日历事件。如果在此时间范围内碰巧有其他具有相同描述的事件,则此脚本可能不会按预期运行。
参考文献:
我混合了一个 Google Apps 脚本来根据我 Google sheet 中的值在日历中创建一个事件。该脚本应在以下条件下工作:
- 每当添加新行时(通过触发器实现 - 第一个函数)
- 仅适用于跨页的最后一行sheet
- 仅当“id”单元格 (28) 为空时才创建事件
然后应创建日历事件并使用事件 ID 填充单元格 28。
客户在我的网站上填写表格时会创建新行。我在 WordPress 中使用 Ninja Forms,它有一个 Google Sheets 插件。所以填写的表格会自动添加到 sheet,然后这个函数会触发。
一切都几乎正常工作。当我手动测试时(例如,我删除了最后一行中的 id 单元格,或者我创建了一个新行或复制了一个现有行),它工作得很好。如果单元格 28 中已经没有事件 ID,则 仅 会创建事件,并且它会使用该 ID 成功填充单元格 28。太棒了!
但是,当使用 WordPress 表单创建行时,我得到 两个 日历事件。 IE - 就像函数运行了两次。每个事件都是相同的,并且都是同时创建的。
我猜这与表单如何与 sheet 集成有关。它以某种方式触发了我的功能两次。我尝试在函数的不同点使用 Utilities.sleep 和不同的值来查看在 strps 之间等待是否有帮助,但无济于事。
谁能想出办法阻止这种情况发生?是否有某种检查可以内置到我的函数中?还是我错过了一些明显的东西?我真的很感激任何建议。 这是我的代码:
function initializeTrigger(){ // run once only to create the trigger
var sheet = SpreadsheetApp.getActive();
ScriptApp.newTrigger("NewCalEvent")
.forSpreadsheet(sheet)
.onChange()
.create();
}
function NewCalEvent() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Bookings2');
var row = sheet.getLastRow();
var calId = "xxxyyy@group.calendar.google.com";
var cal = CalendarApp.getCalendarById(calId);
var date = sheet.getRange(row, 1).getValue();
var title = sheet.getRange(row, 26).getValue();
var tz = sheet.getRange(row, 23).getValue();
var tstart = new Date(sheet.getRange(row, 32).getValue());
var tstop = new Date(sheet.getRange(row, 33).getValue());
var loc = sheet.getRange(row, 2).getValue();
var desc = sheet.getRange(row, 27).getValue();
var guests = sheet.getRange(row, 29).getValue();
var id = sheet.getRange(row, 28).getValue();
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
可能的解决方案:
添加检查以查看是否已为此时创建日历事件。
更多信息:
由于不清楚这个触发器重复的确切来源,一种避免事件被创建两次的方法是在日历中搜索指定时间范围的事件,其中包含您打算输入的描述,并且然后将事件创建代码包装在检查中,这样如果事件尚不存在,它只会 运行s。
代码片段:
// ...
var id = sheet.getRange(row, 28).getValue();
var events = cal.getEvents(tstart, tstop, {search: desc})
.map(function(e) {
try {
return e.getDescription();
}
catch {
return "";
}
});
if (!events.includes(desc)) {
if (id == ""){
var newEvent = cal.createEvent(title, tstart, tstop,
{description:desc,location:loc,guests:guests,sendInvites:true}).getId();
sheet.getRange(row, 28).setValue(newEvent)
}
}
这样,如果脚本是运行两次,那么由于第二次事件已经存在,所以不会再创建。
注意: 这会检查在时间范围 tstart
到 tstop
内是否存在所有具有 desc
描述的日历事件。如果在此时间范围内碰巧有其他具有相同描述的事件,则此脚本可能不会按预期运行。