Google Apps Script:如何检测手动删除的日历事件?
我完全理解你的困扰——CalendarApp.getEventById()这个方法设计得确实有点反直觉,哪怕事件被手动删除(甚至永久清空回收站),它依然会返回一个看似有效的CalendarEvent对象,导致你没法通过null判断事件是否存在。不过有几个靠谱的办法可以解决这个问题:
方法1:通过尝试访问事件属性捕获异常
当事件被真正删除后,虽然getEventById()返回了对象,但调用任何需要读取事件数据的方法(比如getTitle()、getStartTime())都会抛出异常。我们可以利用这一点来判断事件是否存在:
var calendarId = "abc123@group.calendar.google.com"; var calendar = CalendarApp.getCalendarById(calendarId); var eventId = "the-deleted-event-id"; var event = calendar.getEventById(eventId); let eventExists = true; try { // 尝试访问一个事件的核心属性,比如标题 event.getTitle(); } catch (e) { // 如果抛出异常,说明事件已被删除 eventExists = false; } if (!eventExists) { // 重建事件的逻辑 console.log("事件已删除,正在重建..."); calendar.createEvent(...); } else { // 更新事件的逻辑 console.log("事件存在,正在更新..."); event.setTitle("更新后的标题"); // 其他更新操作 }
这个方法的好处是不需要额外配置,直接用现有的CalendarApp服务就能实现,缺点是依赖异常捕获,代码稍微有点绕,但胜在简单直接。
方法2:使用Calendar Advanced Service(推荐)
如果想要更可靠、更符合API设计的方式,建议启用Calendar Advanced Service,它直接调用Google Calendar的REST API,当事件不存在时会明确返回404错误,判断逻辑更清晰:
步骤1:启用Calendar Advanced Service
在Google Apps Script编辑器中,点击服务 -> 添加服务,找到Calendar并添加。
步骤2:编写判断逻辑
var calendarId = "abc123@group.calendar.google.com"; var eventId = "the-deleted-event-id"; let eventExists = true; try { // 调用Advanced Service的events.get方法 Calendar.Events.get(calendarId, eventId); } catch (e) { // 如果返回404,说明事件不存在 if (e.message.includes("404")) { eventExists = false; } else { // 处理其他类型的错误 throw e; } } if (!eventExists) { // 重建事件 console.log("事件已删除,正在重建..."); // 用Advanced Service创建事件的示例: var event = { summary: "新事件标题", start: { dateTime: "2024-05-20T10:00:00", timeZone: "Asia/Shanghai" }, end: { dateTime: "2024-05-20T11:00:00", timeZone: "Asia/Shanghai" } }; Calendar.Events.insert(event, calendarId); } else { // 更新事件 console.log("事件存在,正在更新..."); var updatedEvent = { summary: "更新后的标题" }; Calendar.Events.patch(updatedEvent, calendarId, eventId); }
这个方法的优势是逻辑更明确,API返回的状态码直接告诉你事件是否存在,而且Advanced Service的功能比CalendarApp更丰富,适合复杂的日历操作。唯一的小麻烦是需要先启用服务,但操作一次就搞定了。
关于你提到的get/setTag()方法
这个思路其实也可以试试,但局限性比较大:如果事件被删除,你调用event.getTag()同样会抛出异常,本质上和方法1的逻辑类似,而且tag是你自己设置的,万一之前没设置过tag,这个方法就失效了,所以不如直接用方法1或方法2靠谱。
另外你提到的遍历回收站事件的方法,确实不太理想——不仅效率低,而且永久删除的事件不会出现在回收站里,根本检测不到,所以不推荐使用。
总结一下,优先推荐方法2(Advanced Service),如果不想启用额外服务,方法1也能很好解决问题。
内容的提问来源于stack exchange,提问作者inkychris

