Google Apps脚本:event.setTime错误和时间格式

时间:2015-06-04 19:15:23

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

我正在创建几乎完整的预订系统。目前我正在从表单中收集数据,将其传递给工作表,然后使用其中一些信息来创建日历事件。一切正常。

在创建事件时,我还收集了eventID,以便我可以使用它来识别事件并从电子表格中更新它。这些更新也有效,但更新导致以下错误的开始/结束日期和时间除外:

TypeError:在对象CalendarEventSeries中找不到函数setTime。

这是我正在使用的代码:

var eventStart =  sh.getRange("D"+rowNumber).getValues();
var eventEnd =  sh.getRange("E"+rowNumber).getValues();
event.setTime(eventStart, eventEnd);

我正在使用setLocation和setTitle做同样的事情而没有问题。

我是新手,我不知道对象是什么,所以错误信息对我来说意义不大!但我可以看到setTime是类'CalendarEvent'(https://developers.google.com/apps-script/reference/calendar/calendar-event#setTime(Date,Date))中概述的方法,但不在'CalendarEventSeries'中。我的所有活动都是开场活动吗?

提前感谢任何指示。

更新

我已经集成了Mogsdad的高级日历服务代码,之后

"var endTime = parseDate(event.end.date||event.end.dateTime);"

我正在检查/记录'startTime'和'event'。 'startTime'作为'无效日期'回来了(坏事?)和'event'会带着我能想象的所有日历条目信息回来(我希望好的东西?!)。

parseDate函数应该去哪里?也许我把它放在了错误的地方(我已经在整个地方试过了!)并且没有使用它?

此外,现在我想要编辑的事件已被识别,是否已解析日期并用于搜索我已经找到的事件,以便返回我最终可以使用setTime的日历事件?这是关键吗?

感谢您的支持。

更新2 - 无效日期?

如果我跳过解析并按如下方式记录变量:

var startTime = event.start.dateTime;

结果是2015-05-24T02:00:00 + 01:00,我认为是现货。因此,无效日期肯定是在解析函数期间出现问题的情况,因为它只返回“无效日期”。

下面的代码。

function onOpen() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var menuEntries = [{name: "Create Event Document Manually", functionName: "addSheet"},{name: "Update Calendar Entry", functionName: "getEventById"}
  ];


  ss.addMenu("Select Row & Click Here", menuEntries);
}



/**
 * Retrieve a CalendarApp CalendarEvent object from IDs.
 * This version utilizes the Advanced Calendar Service, which must be
 * enabled before use.
 *
 * @param {string} calendarId   ID of calendar to be searched
 * @param {string} eventId      Event ID to match
 *
 * @returns {CalendarEvent}     CalendarApp CalendarEvent object or null
 */


function getEventById(calendarId, eventId) {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();
  var rowNumber = sh.getActiveRange().getRowIndex();
  var myEventId = "q8q533oioluipirksmno88qv2g";
  var calendarId = "mydomain.tv_q9608ku2min78rasgt2s2n233c@group.calendar.google.com";


  // Get event by ID.
  var event = Calendar.Events.get(calendarId, myEventId);
  // This isn't a CalendarApp CalendarEvent though, so use the info
  // in the event to find it AGAIN as the right type.




  // Get start & end times of event. All-day events start at start.date,
  // while other events start at start.datetime. Likewise for end.

  var startTime = parseDate(event.start.date||event.start.dateTime);
  var endTime = parseDate(event.end.date||event.end.dateTime);



   Logger.log('Variables: ' + startTime + ' and ' + endTime);

  // Get array of events that fall between startTime & endTime
  var calEvents = CalendarApp.getEvents(startTime, endTime);

  // Search through those events, looking for a match by ID
  for (var i=0; i<calEvents.length; i++) {
    var curId = calEvents[i].getId().split('@')[0];  // extract id from id@calendar.google.com
    if (curId == eventId) {
      // Mission accomplished; we have an Event object with given id!
      return calEvents[i];

    }
  }
  // We did not find matching event
  return null;


}




  function parseDate(string) {
  var parts = string.split('T');
  parts[0] = parts[0].replace(/-/g, '/');
  return new Date(parts.join(' '));
}

2 个答案:

答案 0 :(得分:2)

Serge说得对 - 问题是你检索到了CalendarEventSeries个对象,而不是CalendarEvent。由于服务中唯一按ID查找事件的方法是getEventSeriesById(iCalId),因此您有点卡住了。

一种选择是改为使用Advanced Calendar Service

var event = Calendar.Events.get(calendarId, eventId);

对于新代码,这是一个很好的选择,特别是对于已经习惯使用Javascript API的开发人员。但是,如果您是初学者或不熟悉高级服务,您会发现学习曲线比日历服务更陡峭。

在这种情况下,这些实用程序应该通过满足getEventById()函数的需要来帮助您坚持使用CalendarApp及其类和方法。

引擎盖下的高级日历服务

getEventById()有两个版本。第一个使用高级日历服务,必须是enabled before use。代码非常简单。您必须明确提供日历ID,因为这不是类方法。例如:

var calendarId = CalendarApp.getDefaultCalendar().getId();
var eventId = "smmd8h1dfe9lo9bip52hidnqk0";
var event = getEventById(calendarId, eventId);

代码:

/**
 * Retrieve a CalendarApp CalendarEvent object from IDs.
 * This version utilizes the Advanced Calendar Service, which must be
 * enabled before use.
 *
 * @param {string} calendarId   ID of calendar to be searched
 * @param {string} eventId      Event ID to match
 *
 * @returns {CalendarEvent}     CalendarApp CalendarEvent object or null
 */
function getEventById(calendarId, eventId) {
  // Get event by ID.
  var event = Calendar.Events.get(calendarId, eventId);
  // This isn't a CalendarApp CalendarEvent though, so use the info
  // in the event to find it AGAIN as the right type.

  // Get start & end times of event. All-day events start at start.date,
  // while other events start at start.datetime. Likewise for end.
  var startTime = parseDate(event.start.date||event.start.dateTime);
  var endTime = parseDate(event.end.date||event.end.dateTime);

  // Get array of events that fall between startTime & endTime
  var calEvents = CalendarApp.getEvents(startTime, endTime);

  // Search through those events, looking for a match by ID
  for (var i=0; i<calEvents.length; i++) {
    var curId = calEvents[i].getId().split('@')[0];  // extract id from id@calendar.google.com
    if (curId == eventId) {
      // Mission accomplished; we have an Event object with given id!
      return calEvents[i];
    }
  }
  // We did not find matching event
  return null;
}

通过UrlFetchApp

的日历API

此版本通过UrlFetchApp使用Calendar API,不需要任何特殊启用。但是,代码比以前的版本更复杂。

/**
 * Retrieve a CalendarApp CalendarEvent object from IDs.
 * This version utilizes the Calendar API via UrlFetchApp, so
 * requires no enablement. However, it's more complex.
 *
 * @param {string} calendarId   ID of calendar to be searched
 * @param {string} eventId      Event ID to match
 *
 * @returns {CalendarEvent}     CalendarApp CalendarEvent object or null
 */
function getEventById(calendarId, eventId) {
  // Prepare a GET request to API URL, to Get event by ID.
  var url = "https://www.googleapis.com/calendar/v3/calendars/calendarId/events/eventId"
            .replace("calendarId",calendarId)
            .replace("eventId",eventId);

  var options = {
    headers: {
      'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken()
    }
  }

  // Send request
  var response = UrlFetchApp.fetch(url, options);
  var rc = response.getResponseCode();
  var text = response.getContentText();

  // If result code is 200OK, process response text
  if (rc == 200) {
    // The event is contained in the response text; parse it into an object
    var event = JSON.parse(text);
    // This isn't a CalendarApp CalendarEvent though, so use the info
    // in the event to find it AGAIN as the right type.

    // Get start & end times of event. All-day events start at start.date,
    // while other events start at start.datetime. Likewise for end.
    var startTime = parseDate(event.start.date||event.start.dateTime);
    var endTime = parseDate(event.end.date||event.end.dateTime);

    // Get array of events that fall between startTime & endTime
    var calEvents = CalendarApp.getEvents(startTime, endTime);

    // Search through those events, looking for a match by ID
    for (var i=0; i<calEvents.length; i++) {
      var curId = calEvents[i].getId().split('@')[0];  // extract id from id@calendar.google.com
      var desc = calEvents[i].getDescription();
      if (curId == eventId) {
        // Mission accomplished; we have an Event object with given id!
        return calEvents[i];
      }
    }
    // We did not find matching event
    return null;
  }
  else
    // An error in fetch, anything BUT 200
    throw new Error( ""+rc+JSON.parse(text).message );
}

辅助功能

getEventById()的两个版本都需要Google's documentation中提供的辅助函数。

/**
 * From https://developers.google.com/apps-script/advanced/calendar#listing_events
 *
 * Parses an RFC 3339 date or datetime string and returns a corresponding Date
 * object. This function is provided as a workaround until Apps Script properly
 * supports RFC 3339 dates. For more information, see
 * https://code.google.com/p/google-apps-script-issues/issues/detail?id=3860
 * @param {string} string The RFC 3339 string to parse.
 * @return {Date} The parsed date.
 */
function parseDate(string) {
  var parts = string.split('T');
  parts[0] = parts[0].replace(/-/g, '/');
  return new Date(parts.join(' '));
}

答案 1 :(得分:1)

当您从其ID中检索事件时,您(很可能)使用方法getEventSerieById(ID),该方法返回CalendarEventSeries,而不是CalendarEvent

如果您查看这3个引用的文档,您会注意到CalendarEventSeries类没有def hash_diff(first, second) first. dup. delete_if { |k, v| second[k] == v }. merge!(second.dup.delete_if { |k, v| first.has_key?(k) }) end hash_diff({1 => 2}, {1 => 2}) # => {} hash_diff({1 => 2}, {1 => 3}) # => {1 => 2} hash_diff({}, {1 => 2}) # => {1 => 2} hash_diff({1 => 2, 3 => 4}, {1 => 2}) # => {3 => 4} 方法。

在这种情况下,您获得的错误消息实际上非常明确。

您应该找到一些处理此问题的帖子,例如:Create Google Calendar Events from Spreadsheet but prevent duplicates