建立事件

假設有一個應用程式可協助使用者找到最佳健行路線,將健行計畫新增為日曆活動,使用者就能輕鬆自動安排行程。Google 日曆可協助他們分享計畫,並提醒他們準備,讓他們不必為此感到壓力。此外,由於 Google 產品整合得非常順暢,Google 即時通訊會提醒他們何時出門,而 Google 地圖也會準時將他們帶往會議地點。

本文將說明如何建立日曆活動,並將活動新增至使用者的日曆。

新增活動

如要建立事件,請呼叫 events.insert() 方法,並至少提供下列參數:

  • calendarId 是日曆 ID,可以是建立活動的日曆的電子郵件地址,或是特殊關鍵字 'primary',後者會使用登入使用者的主日曆。如果您不知道要使用的日曆電子郵件地址,可以前往 Google 日曆網頁式 UI 的日曆設定 (在「日曆地址」部分) 查看,也可以在 calendarList.list() 呼叫的結果中查看。
  • event 是您要建立的事件,其中包含開始和結束等所有必要詳細資料。startend 時間為唯一兩個必填欄位。如需完整的事件欄位清單,請參閱 event 參考資料

如要順利建立事件,您必須:

  • 將 OAuth 範圍設為 https://www.googleapis.com/auth/calendar,即可編輯使用者的日曆。
  • 請確認已驗證的使用者透過您提供的 calendarId 具備日曆的寫入權限 (例如,呼叫 calendarIdcalendarList.get(),並檢查 accessRole)。

新增事件中繼資料

建立日曆活動時,您可以選擇新增活動中繼資料。如果您選擇在建立期間不新增中繼資料,可以使用 events.update() 更新許多欄位;不過,某些欄位 (例如事件 ID) 只能在 events.insert() 作業期間設定。

位置

在位置欄位中新增地址,即可啟用以下功能:

「出發時間」或顯示路線地圖。

事件 ID

建立事件時,您可以選擇自行產生事件 ID

符合格式規定。這樣一來,您就能讓本機資料庫中的實體與 Google 日曆中的活動保持同步。這項功能還可避免在日曆後端成功執行作業後,在某個時間點上發生作業失敗的情況,進而避免重複建立活動。如果未提供事件 ID,伺服器會為您產生一個。詳情請參閱事件 ID 參考資料

參與者

您建立的活動會顯示在所有主要 Google 日曆中

您透過相同活動 ID 加入的與會者。如果您在插入要求中將 sendNotifications 設為 true,與會者也會收到活動的電子郵件通知。詳情請參閱多位與會者的活動指南。

以下範例說明如何建立事件並設定中繼資料:

Go

// Refer to the Go quickstart on how to setup the environment:
// https://developers.google.com/calendar/quickstart/go
// Change the scope to calendar.CalendarScope and delete any stored credentials.

event := &calendar.Event{
  Summary: "Google I/O 2015",
  Location: "800 Howard St., San Francisco, CA 94103",
  Description: "A chance to hear more about Google's developer products.",
  Start: &calendar.EventDateTime{
    DateTime: "2015-05-28T09:00:00-07:00",
    TimeZone: "America/Los_Angeles",
  },
  End: &calendar.EventDateTime{
    DateTime: "2015-05-28T17:00:00-07:00",
    TimeZone: "America/Los_Angeles",
  },
  Recurrence: []string{"RRULE:FREQ=DAILY;COUNT=2"},
  Attendees: []*calendar.EventAttendee{
    &calendar.EventAttendee{Email:"lpage@example.com"},
    &calendar.EventAttendee{Email:"sbrin@example.com"},
  },
}

calendarId := "primary"
event, err = srv.Events.Insert(calendarId, event).Do()
if err != nil {
  log.Fatalf("Unable to create event. %v\n", err)
}
fmt.Printf("Event created: %s\n", event.HtmlLink)

Java

// Refer to the Java quickstart on how to setup the environment:
// https://developers.google.com/calendar/quickstart/java
// Change the scope to CalendarScopes.CALENDAR and delete any stored
// credentials.

Event event = new Event()
    .setSummary("Google I/O 2015")
    .setLocation("800 Howard St., San Francisco, CA 94103")
    .setDescription("A chance to hear more about Google's developer products.");

DateTime startDateTime = new DateTime("2015-05-28T09:00:00-07:00");
EventDateTime start = new EventDateTime()
    .setDateTime(startDateTime)
    .setTimeZone("America/Los_Angeles");
event.setStart(start);

DateTime endDateTime = new DateTime("2015-05-28T17:00:00-07:00");
EventDateTime end = new EventDateTime()
    .setDateTime(endDateTime)
    .setTimeZone("America/Los_Angeles");
event.setEnd(end);

String[] recurrence = new String[] {"RRULE:FREQ=DAILY;COUNT=2"};
event.setRecurrence(Arrays.asList(recurrence));

EventAttendee[] attendees = new EventAttendee[] {
    new EventAttendee().setEmail("lpage@example.com"),
    new EventAttendee().setEmail("sbrin@example.com"),
};
event.setAttendees(Arrays.asList(attendees));

EventReminder[] reminderOverrides = new EventReminder[] {
    new EventReminder().setMethod("email").setMinutes(24 * 60),
    new EventReminder().setMethod("popup").setMinutes(10),
};
Event.Reminders reminders = new Event.Reminders()
    .setUseDefault(false)
    .setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);

String calendarId = "primary";
event = service.events().insert(calendarId, event).execute();
System.out.printf("Event created: %s\n", event.getHtmlLink());

JavaScript

// Refer to the JavaScript quickstart on how to setup the environment:
// https://developers.google.com/calendar/quickstart/js
// Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
// stored credentials.

const event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles'
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'}
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10}
    ]
  }
};

const request = gapi.client.calendar.events.insert({
  'calendarId': 'primary',
  'resource': event
});

request.execute(function(event) {
  appendPre('Event created: ' + event.htmlLink);
});

Node.js

// Refer to the Node.js quickstart on how to setup the environment:
// https://developers.google.com/calendar/quickstart/node
// Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
// stored credentials.

const event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'},
  ],
  'reminders': {
    'useDefault': false,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10},
    ],
  },
};

calendar.events.insert({
  auth: auth,
  calendarId: 'primary',
  resource: event,
}, function(err, event) {
  if (err) {
    console.log('There was an error contacting the Calendar service: ' + err);
    return;
  }
  console.log('Event created: %s', event.htmlLink);
});

PHP

$event = new Google_Service_Calendar_Event(array(
  'summary' => 'Google I/O 2015',
  'location' => '800 Howard St., San Francisco, CA 94103',
  'description' => 'A chance to hear more about Google\'s developer products.',
  'start' => array(
    'dateTime' => '2015-05-28T09:00:00-07:00',
    'timeZone' => 'America/Los_Angeles',
  ),
  'end' => array(
    'dateTime' => '2015-05-28T17:00:00-07:00',
    'timeZone' => 'America/Los_Angeles',
  ),
  'recurrence' => array(
    'RRULE:FREQ=DAILY;COUNT=2'
  ),
  'attendees' => array(
    array('email' => 'lpage@example.com'),
    array('email' => 'sbrin@example.com'),
  ),
  'reminders' => array(
    'useDefault' => FALSE,
    'overrides' => array(
      array('method' => 'email', 'minutes' => 24 * 60),
      array('method' => 'popup', 'minutes' => 10),
    ),
  ),
));

$calendarId = 'primary';
$event = $service->events->insert($calendarId, $event);
printf('Event created: %s\n', $event->htmlLink);

Python

# Refer to the Python quickstart on how to setup the environment:
# https://developers.google.com/calendar/quickstart/python
# Change the scope to 'https://www.googleapis.com/auth/calendar' and delete any
# stored credentials.

event = {
  'summary': 'Google I/O 2015',
  'location': '800 Howard St., San Francisco, CA 94103',
  'description': 'A chance to hear more about Google\'s developer products.',
  'start': {
    'dateTime': '2015-05-28T09:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'end': {
    'dateTime': '2015-05-28T17:00:00-07:00',
    'timeZone': 'America/Los_Angeles',
  },
  'recurrence': [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  'attendees': [
    {'email': 'lpage@example.com'},
    {'email': 'sbrin@example.com'},
  ],
  'reminders': {
    'useDefault': False,
    'overrides': [
      {'method': 'email', 'minutes': 24 * 60},
      {'method': 'popup', 'minutes': 10},
    ],
  },
}

event = service.events().insert(calendarId='primary', body=event).execute()
print 'Event created: %s' % (event.get('htmlLink'))

小茹

event = Google::Apis::CalendarV3::Event.new(
  summary: 'Google I/O 2015',
  location: '800 Howard St., San Francisco, CA 94103',
  description: 'A chance to hear more about Google\'s developer products.',
  start: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2015-05-28T09:00:00-07:00',
    time_zone: 'America/Los_Angeles'
  ),
  end: Google::Apis::CalendarV3::EventDateTime.new(
    date_time: '2015-05-28T17:00:00-07:00',
    time_zone: 'America/Los_Angeles'
  ),
  recurrence: [
    'RRULE:FREQ=DAILY;COUNT=2'
  ],
  attendees: [
    Google::Apis::CalendarV3::EventAttendee.new(
      email: 'lpage@example.com'
    ),
    Google::Apis::CalendarV3::EventAttendee.new(
      email: 'sbrin@example.com'
    )
  ],
  reminders: Google::Apis::CalendarV3::Event::Reminders.new(
    use_default: false,
    overrides: [
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'email',
        minutes: 24 * 60
      ),
      Google::Apis::CalendarV3::EventReminder.new(
        reminder_method: 'popup',
        minutes: 10
      )
    ]
  )
)

result = client.insert_event('primary', event)
puts "Event created: #{result.html_link}"

在活動中新增雲端硬碟附件

您可以將 Google 雲端硬碟 檔案附加到日曆活動中,例如 Google 文件中的會議記錄、試算表中的預算、簡報中的簡報,或任何其他相關的 Google 雲端硬碟檔案。您可以在使用 events.insert() 或更新後的版本建立活動時,在更新 (例如使用 events.patch()) 時加入附件。

將 Google 雲端硬碟檔案附加至活動的兩個部分如下:

  1. Drive API 檔案資源取得檔案 alternateLink 網址、titlemimeType,通常會使用 files.get() 方法。
  2. 建立或更新事件時,請在要求主體中設定 attachments 欄位,並將 supportsAttachments 參數設為 true

以下程式碼範例說明如何更新現有事件以新增附件:

Java

public static void addAttachment(Calendar calendarService, Drive driveService, String calendarId,
    String eventId, String fileId) throws IOException {
  File file = driveService.files().get(fileId).execute();
  Event event = calendarService.events().get(calendarId, eventId).execute();

  List<EventAttachment> attachments = event.getAttachments();
  if (attachments == null) {
    attachments = new ArrayList<EventAttachment>();
  }
  attachments.add(new EventAttachment()
      .setFileUrl(file.getAlternateLink())
      .setMimeType(file.getMimeType())
      .setTitle(file.getTitle()));

  Event changes = new Event()
      .setAttachments(attachments);
  calendarService.events().patch(calendarId, eventId, changes)
      .setSupportsAttachments(true)
      .execute();
}

PHP

function addAttachment($calendarService, $driveService, $calendarId, $eventId, $fileId) {
  $file = $driveService->files->get($fileId);
  $event = $calendarService->events->get($calendarId, $eventId);
  $attachments = $event->attachments;

  $attachments[] = array(
    'fileUrl' => $file->alternateLink,
    'mimeType' => $file->mimeType,
    'title' => $file->title
  );
  $changes = new Google_Service_Calendar_Event(array(
    'attachments' => $attachments
  ));

  $calendarService->events->patch($calendarId, $eventId, $changes, array(
    'supportsAttachments' => TRUE
  ));
}

Python

def add_attachment(calendarService, driveService, calendarId, eventId, fileId):
    file = driveService.files().get(fileId=fileId).execute()
    event = calendarService.events().get(calendarId=calendarId,
                                         eventId=eventId).execute()

    attachments = event.get('attachments', [])
    attachments.append({
        'fileUrl': file['alternateLink'],
        'mimeType': file['mimeType'],
        'title': file['title']
    })

    changes = {
        'attachments': attachments
    }
    calendarService.events().patch(calendarId=calendarId, eventId=eventId,
                                   body=changes,
                                   supportsAttachments=True).execute()

為活動新增視訊和電話會議

您可以將活動與 HangoutsGoogle Meet 會議建立關聯,讓使用者透過電話或視訊通話進行遠端會議。

conferenceData 欄位可用於讀取、複製及清除現有的會議詳細資料,也可以用於要求產生新的會議。如要建立及修改會議詳細資料,請將 conferenceDataVersion 要求參數設為 1

目前支援三種 conferenceData,如 conferenceData.conferenceSolution.key.type 所示:

  1. 消費者版 Hangouts (eventHangout)
  2. 使用者的傳統版 Hangouts (已淘汰;eventNamedHangout)
  3. Google Meet (hangoutsMeet)

如要瞭解使用者任何指定日曆支援哪種會議類型,請查看 calendarscalendarList 集合中的 conferenceProperties.allowedConferenceSolutionTypes。您也可以查看 settings 集合中的 autoAddHangouts 設定,瞭解使用者是否偏好為所有新建立的活動建立 Hangouts。

除了 type 之外,conferenceSolution 還提供 nameiconUri 欄位,可用於代表會議解決方案,如下所示:

JavaScript

const solution = event.conferenceData.conferenceSolution;

const content = document.getElementById("content");
const text = document.createTextNode("Join " + solution.name);
const icon = document.createElement("img");
icon.src = solution.iconUri;

content.appendChild(icon);
content.appendChild(text);

您可以為事件建立新的會議,方法是為 createRequest 提供新產生的 requestId (可以是隨機 string)。會議是異步建立的,但您隨時可以查看要求狀態,讓使用者瞭解目前的情況。

舉例來說,如要要求為現有活動產生會議:

JavaScript

const eventPatch = {
  conferenceData: {
    createRequest: {requestId: "7qxalsvy0e"}
  }
};

gapi.client.calendar.events.patch({
  calendarId: "primary",
  eventId: "7cbh8rpc10lrc0ckih9tafss99",
  resource: eventPatch,
  sendNotifications: true,
  conferenceDataVersion: 1
}).execute(function(event) {
  console.log("Conference created for event: %s", event.htmlLink);
});

對這項呼叫的即時回應可能尚未包含完整填入的 conferenceData;這會在 status 欄位中以 pending 狀態碼表示。填入會議資訊後,狀態碼會變更為 successentryPoints 欄位包含哪些視訊和電話 URI 可供使用者撥入的資訊。

如果您想安排多個含有相同會議詳細資料的 Google 日曆活動,可以將整個 conferenceData 從一個活動複製到另一個活動。

在某些情況下,複製功能非常實用。舉例來說,假設您正在開發招募應用程式,為應徵者和面試官設定個別事件,您想保護面試官的身份,但也想確保所有參與者加入同一個電話會議。