如何同步Google日历&带脚本的电子表格

时间:2013-04-01 13:30:15

标签: javascript google-apps-script google-sheets synchronization google-calendar-api

我正在尝试创建一个Google Apps脚本,以便在云端硬盘上同步保存Google日历和“主电子表格” - 这可能吗?我找到了这两个帖子:

我很确定这可以使用很多if语句和逻辑来完成,但也许有一种更简单的方法?

我最后只提供了以下简单的脚本。所有真正必要的是基于两列添加事件,这将花费太长时间来开发。

function onOpen() {
  //spawns a menu with a button that triggers AddToCal
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Add event to calendar",
    functionName : "AddToCal"
  }];
  sheet.addMenu("Data To Calendar Plugin", entries);
};

function AddToCal(){

  //get the current row
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var cell = ss.getActiveCell();
  var R = cell.getRow();

  //grab values for current row to pass to calendar event
  var date_of_event = ss.getRange('G'+R).getValue();
  var date = new Date(date_of_event);
  var event_title = ss.getRange('A'+R).getValue();
  //access the calendar
  var cal = CalendarApp.getCalendarById('[IDREMOVED]');
  cal.createAllDayEvent(event_title,date);

  ss.toast("Event added to " + cal.getName());
  }

4 个答案:

答案 0 :(得分:4)

是的,可能编写一个双向事件同步脚本,但这并不简单。你提到的这两个帖子都有可以重复使用的部分,但与实际同步所面临的挑战相比,它们相当简单。您可能希望阅读基于电子表格创建日历条目的Using Google Apps Script for a event booking system (但不会执行正在进行的同步)。我过去做了一些debugging of that script

同步需要支持:

  • 在任一地点创建活动
  • 修改任一位置的事件详情(尽管您可以选择仅考虑事件详细信息的子集以进行简化)
  • 删除任一位置的事件
  • 复发,例如CalendarEvent.getEventSeries()处理(或选择避免)

这是伪代码,您可以从以下开始:

Open Calendar, Read Calendar events into calArray (will all attributes you care for)
Open Spreadsheet, Read Spreadsheet events into sheetArray

For each event in calArray:
  Search for calEvent in sheetArray.
  If found, compare lastUpdated values.
    If equal, do nothing
    Otherwise copy most recently updated to least recently updated
    Continue with next event
  If not found then copy calEvent to new sheetEvent, including lastUpdated value.
  Continue with next event

For each event in the sheetArray (...that hasn't been handled yet)
  Similar logic above.

Write updated sheetArray to spreadsheet.
Write updated calEvents to calendar API (see note 1 below)

注意:

  1. 对calEvents的所有更新都可以立即生成,并立即写入日历API,作为批量更新的替代方案。这将消除在本地跟踪更改的需要,尽管触摸lastUpdated值是个好主意。

  2. 您需要在阅读calEvents时使用CalendarEvent.getLastUpdated(),并在电子表格中存储类似的值(与onEdit触发器相关联)以便于比较。

  3. 它会简化与电子表格中事件的记录CalendarEvent.getId()的比较。您还可以使用CalendarEvent.setTag(key,value)将自定义元数据记录到日历中,例如指示源自或已与电子表格同步的事件。 (这些标签无法通过GCal UI访问,因此只能通过脚本访问。)

  4. 您应该考虑要处理的日期范围或事件数量,并限制脚本的范围。如果不这样做,您肯定会在实际操作中遇到执行时间限制。

  5. 某些日历事件特征不适合在电子表格中轻松表达,例如:

    • 访客列表
    • 提醒清单

答案 1 :(得分:4)

如前所述(感谢Henrique),我花了一些时间 - 这实际上是我最初带给GAS的 - 电子表格和日历之间的数据交换,主要是因为我曾经在那里工作的人用来组织他们的时间表(对于高中)电子表格我不得不负责过渡到Google日历。

经过一段时间后,虽然似乎在线日历界面更有效地创建事件,所以他们不再使用工作表来更新日历脚本!

另一方面,GCal中的打印和演示选项非常有限,因此另一个方向仍然非常有用,我们一直使用它!

我知道这似乎是关于原始问题的主题,也许是过于轶事但我只是想指出你应该在重新发明轮子之前彻底考虑你真正需要的东西......正如Mogsdad所说,一些事件参数在电子表格逻辑中不易描述,最后使用它可能比原始工具复杂得多。

当我需要删除或编辑大量类似事件时,我使用双向数据传输开发的唯一真正有用的工具是“批量修改工具”。

例如,如果我们因为某种原因需要在一年中更改教师姓名,我会导入一些课程的所有事件,替换电子表格中的名称并更新班级日历......这需要我5分钟并且很容易,但这些是非常具体的用例,我不确定它是非常常见的。

无论如何我不会称之为“同步”,因为它只需要一些时间来改变它们......我从来没有尝试过使用日历来保持电子表格的最新状态,从我的经验中,日历非常可靠我认为它们是原始数据源。正如我已经说过的,我们每周都会在电子表格中导入数据,仅用于打印和本地存档。

对于这个冗长而有点模糊的评论感到抱歉(这太长了,不适合普通的500个评论; - )

答案 2 :(得分:2)

不,没有。尽管有很多关于Apps脚本日历服务的问题已经解决(时区,全天事件,查询等),但它仍然是一项相当复杂的任务。

我知道Serge,the top contributor here in SO在#google-apps-script标签上,开发了很多涉及日历服务的some scripts

但我不知道在日历和电子表格之间进行了双向更新。这应该是一个艰难的。如果您这样做,请善意分享:)

答案 3 :(得分:0)

我写了一个脚本,可以在GCalendar和GSheet之间进行同步。您也许可以按原样使用它,或者可以肯定地从中借用想法。每种方式都有单独的用于复制事件的命令:https://github.com/Davepar/gcalendarsync