고급 캘린더 서비스

고급 캘린더 서비스를 사용하면 Apps Script의 Google Calendar API 이 API는 Apps Script의 기본 제공 캘린더 서비스와 마찬가지로 을 사용하면 스크립트가 사용자의 Google Calendar에 액세스하고 수정할 수 있습니다. 사용자가 구독한 추가 캘린더가 표시됩니다. 대부분의 경우 내장된 이 고급 서비스는 사용하기 더 쉽지만, 몇 가지 추가 기능을 개별 일정의 배경 색상 설정을 비롯한 기능이 추가되었습니다.

참조

이 서비스에 대한 자세한 내용은 일반 사용자용 참조 문서 Google 캘린더 API Apps Script의 모든 고급 서비스와 마찬가지로 캘린더 서비스는 공개 캘린더 서비스와 동일한 객체, 메서드, 매개변수를 사용합니다. API에 액세스할 수 있습니다. 자세한 내용은 메서드 서명 확인 방법을 참조하세요.

문제를 신고하고 기타 지원을 받으려면 다음을 참조하세요. 캘린더 지원 가이드

HTTP 요청 헤더

고급 캘린더 서비스는 HTTP 요청 헤더를 수락할 수 있습니다. If-MatchIf-None-Match 자세한 내용은 참조 문서를 확인하세요.

샘플 코드

아래의 샘플 코드는 버전 3 생성합니다.

이벤트 만들기

다음 예에서는 사용자의 기본값에 이벤트를 만드는 방법을 보여줍니다. 있습니다.

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;
}

캘린더 나열

다음 예시는 캘린더에 관한 세부정보를 검색하는 방법을 보여줍니다. 사용자의 캘린더 목록에 표시됩니다.

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);
}

이벤트 나열

다음 예는 다음 10개의 예정된 이벤트를 나열하는 방법을 보여줍니다. 사용자의 기본 캘린더로 이동합니다.

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());
  }
}

조건부로 이벤트 수정

다음 예는 다음을 사용하여 캘린더 일정을 조건부로 업데이트하는 방법을 보여줍니다. If-Match 헤더 스크립트는 새 이벤트를 만들고 30초 동안 대기한 다음 는 일정이 시작된 후 일정 세부정보가 변경되지 않은 경우에만 일정을 업데이트합니다. 생성됨.

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);
  }
}

조건부로 이벤트 가져오기

다음 예시에서는 다음을 사용하여 캘린더 일정을 조건부로 가져오는 방법을 보여줍니다. If-None-Match 헤더 스크립트는 새 이벤트를 만든 다음 30초 동안 변경할 수 있습니다. 일정이 변경될 때마다 새 버전이 가져올 수 있습니다

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);
  }
}

이벤트 동기화

다음 예시에서는 동기화 토큰을 사용하여 이벤트를 가져오는 방법을 보여줍니다. 캘린더 고급 서비스 요청에 동기화 토큰을 포함하면 결과 응답에는 해당 토큰 이후에 변경된 항목만 포함됨 보다 효율적인 처리가 가능하도록 했습니다. 자세한 내용은 효율적으로 리소스 동기화에서 자세히 알아보세요. 동기화 프로세스입니다.

다음 예에서는 동일한 getRelativeDate(daysOffset, hour)를 사용합니다. 메서드를 호출할 수 있습니다.

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);
}