【问题标题】:Checking a Google Calendar Event's Existence检查 Google 日历活动是否存在
【发布时间】:2018-01-11 03:55:47
【问题描述】:

我的整个代码中有一个非常基本的问题,这让我头疼了几天。我已经对这个问题进行了广泛的研究,但是无法找到确切的解决方案(或者我错过了我可能找到的解决方案)。这里是:

我有一个电子表格,用于登录 Google 日历活动及其属性,包括活动 ID。有时,我手动清理 Google 日历,只想运行一个代码来检查日历中是否存在事件,如果不删除该行。我的代码是:

function cleanCal(calid, eventid) {
  var calid = 'my calendar id';
  var eventid = 'event id';
  var event = CalendarApp.getOwnedCalendarById(calid).getEventById(eventid);

  if (event) {
    event.deleteEvent();
    // clean-up sheet
  } else {
    // clean-up sheet
  }
}

基本上如果事件在日历中,代码应该先删除它然后清理工作表,如果它不存在,它应该只清理工作表。但是,在执行代码时,虽然日历事件不存在,但 if 语句返回 true 并在尝试删除事件时引发错误,因为它实际上不存在。尽管事件不存在,但我一直无法找出 event 对象返回 true 的原因、方式和原因。我哪里做错了??感谢您的回复,非常感谢您的帮助。

[编辑] 这是我用来检查日历 API v3 是否存在的代码

function verifyCalendarEvent_OLD(calid, eventid) {
  var cal = CalendarApp.getCalendarById(calid)
  var exists = true;
  var response = Calendar.Events.list(
  calid, {
    showDeleted: true,
    fields: "items(id,status,summary)"
    }
  );

  for (var i = 0; i < response.items.length; i++) {
    if (response.items[i].id == eventid.split("@")[0] && response.items[i].status == "cancelled") {
      exists = false;
      break;
    }
  }
  return exists;
}

【问题讨论】:

标签: google-apps-script google-calendar-api


【解决方案1】:

这个答案怎么样?

修改点:

例如,如果没有事件ID的事件,CalendarApp.getOwnedCalendarById(calid).getEventById(eventid)返回null。当这是由if 评估时,它被用作false

所以我认为您可能会尝试检索已删除的事件。因为在 Google 日历中,即使删除了活动,活动 ID 也会保留。因此,尽管事件 ID 没有事件,但脚本中的 if (event) {} 会返回 true。我确认CalendarApp.getOwnedCalendarById(calid).getEventById(eventid) 检索到已删除的事件。对于这种情况,您可以通过确认事件状态来知道该事件是否被移除。

  • 当事件状态为confirmed时,表示该事件仍未移除。
  • 当事件状态为已取消时,表示该事件已被移除。

准备使用这个修改后的示例脚本:

当您使用此修改后的脚本时,请在高级 Google 服务和 API 控制台中启用日历 API。

在高级 Google 服务中启用 Calendar API v3

  • 在脚本编辑器上
    • 资源 -> 高级 Google 服务
    • 开启日历 API v3

Enable Calendar API at API console

  • 在脚本编辑器上
    • 资源 -> 云平台项目
    • 查看 API 控制台
    • 在开始时,单击启用 API 并获取密钥等凭据。
    • 点击左侧的库。
    • 在搜索 API 和服务时,输入“日历”。然后点击日历 API。
    • 点击启用按钮。
    • 如果API已经开启,请不要关闭。
    • 运行此脚本时,如果出现错误,您可能需要等待几分钟才能启用 API。

修改后的脚本:

function cleanCal(calid, eventid) {
  var calid = 'my calendar id';
  var eventid = 'event id';
  var status = Calendar.Events.get(calid, eventid).status; // Added

  if (status == "confirmed") { // Modified
    var event = CalendarApp.getOwnedCalendarById(calid).getEventById(eventid); // Added
    event.deleteEvent();
    // clean-up sheet
  } else {
    // clean-up sheet
  }
}

如果我误解了你的问题,我很抱歉。

编辑:

在我的环境中,手动和脚本删除的事件可以检索为status=cancelled。由于我不知道您的情况,所以我准备了一个示例脚本。此示例脚本是一个简单的流程。

  1. 创建新事件。
  2. 删除创建的事件。
  3. 确认删除的事件。
    • 这里使用了您的附加脚本。

示例脚本:

function deleteeventa() {
  // Create new event
  var calid = 'my calendar id';
  var c = CalendarApp.getCalendarById(calid);
  var r = c.createEvent("sample event for deleting", new Date(2018,0,11,00,00), new Date(2018,0,11,01,00));

  // Delete the created new event
  var eventid = r.getId().split('@')[0];
  var event = c.getEventById(eventid);
  event.deleteEvent();

  // Your additional script
  var exists = true;
  var response = Calendar.Events.list(
  calid, {
    showDeleted: true,
    fields: "items(id,status,summary)"
    }
  );
  for (var i = 0; i < response.items.length; i++) {
    if (response.items[i].id == eventid && response.items[i].status == "cancelled") {
      exists = false;
      break;
    }
  }
  Logger.log("%s, %s, %s", r.getTitle(), r.getId(), exists)
}

结果:

sample event for deleting, #####@google.com, false

【讨论】:

  • 感谢@Tanaike 的解决方案。在检查我相信的事件时,使用 Calendar API v3 而不是 CalendarApp Services 是一个聪明的主意。据我了解,您首先使用日历 API 获取事件的 状态,然后临时添加该事件并立即将其删除。但这种技术的缺点是日历 API 将返回一个 nullundefined 状态,用于使用脚本删除的事件。
  • 例如,对于 CalendarApp 返回 true 值的同一事件 ID,当我在无法读取其状态的情况下检查它时,日历 API 不会在项目列表中返回该事件的 ID。
  • @Levent Kulacoglu 对于给您带来的不便和不完整的回答,我深表歉意。对于这条评论For example for a same Event ID where CalendarApp returns true value, Calendar API does not return that event's id in the items list...,您是否尝试使用Calendar.Events.list() 检索状态为“已取消”的事件ID?如果是这样,则需要 showDeleted: true 来检索事件 ID。你能告诉我你现在的剧本吗?通过了解您目前的情况,我将能够想到解决方案。如果您可以显示您当前的脚本,请将其添加到您的问题中。
  • 我在我的问题正文中提供了我的代码。如您所见,我已经在有效负载中显示了 showDeleted: true 属性。当您检索 Calendar.Events.list() 时,当且仅当您手动从 Google 日历中删除事件时,它才会显示事件的 ID。但是,如果您使用 Google Apps 脚本删除事件,它不会再将该 ID 带入列表中。相反 CalendarApp.getCalendarById(calid).getEventById(eventid) 仍然返回 true 值。要么这是一个奇怪的情况,要么我正在做一个愚蠢的评估。
  • @Tanaike 最近谷歌改变了行为,使得 EventID 可以被彻底清除。以前它只是标有“已取消”,在日历和订阅上显示为删除线。这对谷歌来说是一个倒退,因为他们失去了取消活动的能力——它现在完全删除了,这可能会让人们认为它已经在日程安排中被移动或者存在故障。确认某事已取消比简单地让它消失更好!
【解决方案2】:

Tanaike 的大力帮助下,我想出了这段代码 sn-p - 据我测试 - 现在可以正常工作。希望它可能对其他用户有所帮助。这是代码片段:

function verifyCalendarEvent(calid, eventid) {
  var cal = CalendarApp.getCalendarById(calid)
  eventid = eventid.split("@")[0];
  var exists = true;
  var eventIds = [];
  var eventStats = [];

  var response = Calendar.Events.list(
  calid, {
    showDeleted: true,
    fields: "items(id,status,summary)"
    }
  );

  for (var i = 0; i < response.items.length; i++) {
    eventIds.push(response.items[i].id);
  }

  for (var i = 0; i < response.items.length; i++) {
    eventStats.push(response.items[i].status);
  }

  if (eventIds.indexOf(eventid) > 0) {
    for (var i = 0; i < eventIds.length; i++) {
      if (eventIds[i] == eventid && eventStats[i] == "cancelled") {
        exists = false;
      }
    }
  } else {
    exists = false;
  }
  Logger.log("Calendar Event ["+eventid+"] exists? >> "+exists);
  return exists;
}

【讨论】:

    猜你喜欢
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    相关资源
    最近更新 更多