Dịch vụ Lịch nâng cao

Dịch vụ Lịch nâng cao cho phép bạn sử dụng API Lịch Google công khai trong Apps Script. Tương tự như dịch vụ Lịch tích hợp sẵn của Apps Script, API này cho phép các tập lệnh truy cập và sửa đổi Lịch Google của người dùng, bao gồm cả các lịch bổ sung mà người dùng đăng ký. Trong hầu hết các trường hợp, dịch vụ tích hợp sẵn sẽ dễ sử dụng hơn, nhưng dịch vụ nâng cao này cung cấp một số tính năng bổ sung, bao gồm cả việc đặt màu nền cho từng sự kiện.

Tài liệu tham khảo

Để biết thông tin chi tiết về dịch vụ này, hãy xem tài liệu tham khảo cho API Lịch Google công khai. Giống như tất cả các dịch vụ nâng cao trong Apps Script, dịch vụ Lịch nâng cao sử dụng cùng các đối tượng, phương thức và tham số như API công khai. Để biết thêm thông tin, hãy xem phần Cách xác định chữ ký phương thức.

Để báo cáo vấn đề và tìm các dịch vụ hỗ trợ khác, hãy xem Hướng dẫn hỗ trợ về Lịch.

Tiêu đề yêu cầu HTTP

Dịch vụ Lịch nâng cao có thể chấp nhận các tiêu đề yêu cầu HTTP If-MatchIf-None-Match. Để biết thông tin chi tiết, hãy xem tài liệu tham khảo.

Mã mẫu

Mã mẫu bên dưới sử dụng phiên bản 3 của API.

Tạo sự kiện

Ví dụ sau đây minh hoạ cách tạo một sự kiện trong lịch mặc định của người dùng.

advanced/calendar.gs
/**
 * Creates an event in the user's default calendar.
 * @see https://developers.google.com/calendar/api/v3/reference/events/insert
 */
function createEvent() {
  const calendarId = 'primary';
  const start = getRelativeDate(1, 12);
  const end = getRelativeDate(1, 13);
  // event details for creating event.
  let event = {
    summary: 'Lunch Meeting',
    location: 'The Deli',
    description: 'To discuss our plans for the presentation next week.',
    start: {
      dateTime: start.toISOString()
    },
    end: {
      dateTime: end.toISOString()
    },
    attendees: [
      {email: 'gduser1@workspacesample.dev'},
      {email: 'gduser2@workspacesample.dev'}
    ],
    // Red background. Use Calendar.Colors.get() for the full list.
    colorId: 11
  };
  try {
    // call method to insert/create new event in provided calandar
    event = Calendar.Events.insert(event, calendarId);
    console.log('Event ID: ' + event.id);
  } catch (err) {
    console.log('Failed with error %s', err.message);
  }
}

/**
 * Helper function to get a new Date object relative to the current date.
 * @param {number} daysOffset The number of days in the future for the new date.
 * @param {number} hour The hour of the day for the new date, in the time zone
 *     of the script.
 * @return {Date} The new date.
 */
function getRelativeDate(daysOffset, hour) {
  const date = new Date();
  date.setDate(date.getDate() + daysOffset);
  date.setHours(hour);
  date.setMinutes(0);
  date.setSeconds(0);
  date.setMilliseconds(0);
  return date;
}

Liệt kê lịch

Ví dụ sau đây minh hoạ cách truy xuất thông tin chi tiết về các lịch xuất hiện trong danh sách lịch của người dùng.

advanced/calendar.gs
/**
 * Lists the calendars shown in the user's calendar list.
 * @see https://developers.google.com/calendar/api/v3/reference/calendarList/list
 */
function listCalendars() {
  let calendars;
  let pageToken;
  do {
    calendars = Calendar.CalendarList.list({
      maxResults: 100,
      pageToken: pageToken

    });
    if (!calendars.items || calendars.items.length === 0) {
      console.log('No calendars found.');
      return;
    }
    // Print the calendar id and calendar summary
    for (const calendar of calendars.items) {
      console.log('%s (ID: %s)', calendar.summary, calendar.id);
    }
    pageToken = calendars.nextPageToken;
  } while (pageToken);
}

Liệt kê sự kiện

Ví dụ sau đây minh hoạ cách liệt kê 10 sự kiện sắp tới tiếp theo trong lịch mặc định của người dùng.

advanced/calendar.gs
/**
 * Lists the next 10 upcoming events in the user's default calendar.
 * @see https://developers.google.com/calendar/api/v3/reference/events/list
 */
function listNext10Events() {
  const calendarId = 'primary';
  const now = new Date();
  const events = Calendar.Events.list(calendarId, {
    timeMin: now.toISOString(),
    singleEvents: true,
    orderBy: 'startTime',
    maxResults: 10
  });
  if (!events.items || events.items.length === 0) {
    console.log('No events found.');
    return;
  }
  for (const event of events.items) {
    if (event.start.date) {
      // All-day event.
      const start = new Date(event.start.date);
      console.log('%s (%s)', event.summary, start.toLocaleDateString());
      continue;
    }
    const start = new Date(event.start.dateTime);
    console.log('%s (%s)', event.summary, start.toLocaleString());
  }
}

Sửa đổi sự kiện theo điều kiện

Ví dụ sau đây cho thấy cách cập nhật có điều kiện một sự kiện Lịch bằng tiêu đề If-Match. Tập lệnh này tạo một sự kiện mới, đợi 30 giây, sau đó chỉ cập nhật sự kiện nếu không có thông tin chi tiết nào về sự kiện thay đổi kể từ khi sự kiện được tạo.

advanced/calendar.gs
/**
 * Creates an event in the user's default calendar, waits 30 seconds, then
 * attempts to update the event's location, on the condition that the event
 * has not been changed since it was created.  If the event is changed during
 * the 30-second wait, then the subsequent update will throw a 'Precondition
 * Failed' error.
 *
 * The conditional update is accomplished by setting the 'If-Match' header
 * to the etag of the new event when it was created.
 */
function conditionalUpdate() {
  const calendarId = 'primary';
  const start = getRelativeDate(1, 12);
  const end = getRelativeDate(1, 13);
  let event = {
    summary: 'Lunch Meeting',
    location: 'The Deli',
    description: 'To discuss our plans for the presentation next week.',
    start: {
      dateTime: start.toISOString()
    },
    end: {
      dateTime: end.toISOString()
    },
    attendees: [
      {email: 'gduser1@workspacesample.dev'},
      {email: 'gduser2@workspacesample.dev'}
    ],
    // Red background. Use Calendar.Colors.get() for the full list.
    colorId: 11
  };
  event = Calendar.Events.insert(event, calendarId);
  console.log('Event ID: ' + event.getId());
  // Wait 30 seconds to see if the event has been updated outside this script.
  Utilities.sleep(30 * 1000);
  // Try to update the event, on the condition that the event state has not
  // changed since the event was created.
  event.location = 'The Coffee Shop';
  try {
    event = Calendar.Events.update(
        event,
        calendarId,
        event.id,
        {},
        {'If-Match': event.etag}
    );
    console.log('Successfully updated event: ' + event.id);
  } catch (e) {
    console.log('Fetch threw an exception: ' + e);
  }
}

Truy xuất sự kiện có điều kiện

Ví dụ sau đây cho thấy cách tìm nạp một sự kiện Lịch theo điều kiện bằng cách sử dụng tiêu đề If-None-Match. Tập lệnh này tạo một sự kiện mới, sau đó thăm dò ý kiến về sự kiện đó để biết các thay đổi trong 30 giây. Bất cứ khi nào sự kiện thay đổi, phiên bản mới sẽ được tìm nạp.

advanced/calendar.gs
/**
 * Creates an event in the user's default calendar, then re-fetches the event
 * every second, on the condition that the event has changed since the last
 * fetch.
 *
 * The conditional fetch is accomplished by setting the 'If-None-Match' header
 * to the etag of the last known state of the event.
 */
function conditionalFetch() {
  const calendarId = 'primary';
  const start = getRelativeDate(1, 12);
  const end = getRelativeDate(1, 13);
  let event = {
    summary: 'Lunch Meeting',
    location: 'The Deli',
    description: 'To discuss our plans for the presentation next week.',
    start: {
      dateTime: start.toISOString()
    },
    end: {
      dateTime: end.toISOString()
    },
    attendees: [
      {email: 'gduser1@workspacesample.dev'},
      {email: 'gduser2@workspacesample.dev'}
    ],
    // Red background. Use Calendar.Colors.get() for the full list.
    colorId: 11
  };
  try {
    // insert event
    event = Calendar.Events.insert(event, calendarId);
    console.log('Event ID: ' + event.getId());
    // Re-fetch the event each second, but only get a result if it has changed.
    for (let i = 0; i < 30; i++) {
      Utilities.sleep(1000);
      event = Calendar.Events.get(calendarId, event.id, {}, {'If-None-Match': event.etag});
      console.log('New event description: ' + event.start.dateTime);
    }
  } catch (e) {
    console.log('Fetch threw an exception: ' + e);
  }
}

Đồng bộ hoá sự kiện

Ví dụ sau đây minh hoạ cách truy xuất sự kiện bằng mã thông báo đồng bộ hoá. Khi bạn đưa mã thông báo đồng bộ hoá vào yêu cầu dịch vụ nâng cao của Lịch, phản hồi thu được sẽ chỉ bao gồm các mục đã thay đổi kể từ khi mã thông báo đó được tạo, cho phép xử lý hiệu quả hơn. Hãy xem phần Đồng bộ hoá tài nguyên một cách hiệu quả để biết thêm thông tin chi tiết về quá trình đồng bộ hoá.

Ví dụ sau đây sử dụng cùng một phương thức getRelativeDate(daysOffset, hour) được xác định trong các ví dụ trên.

advanced/calendar.gs
/**
 * Retrieve and log events from the given calendar that have been modified
 * since the last sync. If the sync token is missing or invalid, log all
 * events from up to a month ago (a full sync).
 *
 * @param {string} calendarId The ID of the calender to retrieve events from.
 * @param {boolean} fullSync If true, throw out any existing sync token and
 *        perform a full sync; if false, use the existing sync token if possible.
 */
function logSyncedEvents(calendarId, fullSync) {
  const properties = PropertiesService.getUserProperties();
  const options = {
    maxResults: 100
  };
  const syncToken = properties.getProperty('syncToken');
  if (syncToken && !fullSync) {
    options.syncToken = syncToken;
  } else {
    // Sync events up to thirty days in the past.
    options.timeMin = getRelativeDate(-30, 0).toISOString();
  }
  // Retrieve events one page at a time.
  let events;
  let pageToken;
  do {
    try {
      options.pageToken = pageToken;
      events = Calendar.Events.list(calendarId, options);
    } catch (e) {
      // Check to see if the sync token was invalidated by the server;
      // if so, perform a full sync instead.
      if (e.message === 'Sync token is no longer valid, a full sync is required.') {
        properties.deleteProperty('syncToken');
        logSyncedEvents(calendarId, true);
        return;
      }
      throw new Error(e.message);
    }
    if (events.items && events.items.length === 0) {
      console.log('No events found.');
      return;
    }
    for (const event of events.items) {
      if (event.status === 'cancelled') {
        console.log('Event id %s was cancelled.', event.id);
        return;
      }
      if (event.start.date) {
        const start = new Date(event.start.date);
        console.log('%s (%s)', event.summary, start.toLocaleDateString());
        return;
      }
      // Events that don't last all day; they have defined start times.
      const start = new Date(event.start.dateTime);
      console.log('%s (%s)', event.summary, start.toLocaleString());
    }
    pageToken = events.nextPageToken;
  } while (pageToken);
  properties.setProperty('syncToken', events.nextSyncToken);
}