고급 캘린더 서비스

고급 캘린더 서비스를 사용하면 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);
  }
}

이벤트 동기화

다음 예는 동기화 토큰을 사용하여 이벤트를 검색하는 방법을 보여줍니다. Calendar 고급 서비스 요청에 동기화 토큰을 포함하면 생성된 이후 변경된 항목만 결과 응답에 포함되므로 더 효율적으로 처리할 수 있습니다. 자세한 내용은 효율적으로 리소스 동기화에서 자세히 알아보세요. 동기화 프로세스입니다.

다음 예에서는 동일한 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);
}