イベントを作成する

ユーザーが最適なハイキング ルートを見つけるのに役立つアプリがあるとします。ハイキングの計画をカレンダーの予定として追加すると、ユーザーは自動的に整理された状態を維持できます。Google カレンダーでは、計画を共有したり、リマインダーを設定したりできるため、ストレスなく準備を進めることができます。また、Google サービスがシームレスに統合されているため、Google ナウが出発時間を伝え、Google マップが会議場所に時間通りに案内してくれます。

この記事では、カレンダー イベントを作成し、ユーザーのカレンダーに追加する方法について説明します。

予定を追加

イベントを作成するには、少なくとも次のパラメータを指定して events.insert() メソッドを呼び出します。

  • calendarId はカレンダー ID です。予定を作成するカレンダーのメールアドレスか、ログイン中のユーザーのメインカレンダーを使用する特別なキーワード 'primary' のいずれかです。使用するカレンダーのメールアドレスがわからない場合は、Google カレンダーのウェブ UI のカレンダーの設定([カレンダーのアドレス] セクション)で確認するか、calendarList.list() 呼び出しの結果で確認できます。
  • event は、開始日や終了日など、必要なすべての詳細情報とともに作成するイベントです。必須フィールドは startend の 2 つだけです。イベント フィールドの完全なセットについては、event リファレンスをご覧ください。

イベントを正常に作成するには、次のことを行う必要があります。

  • OAuth スコープを https://www.googleapis.com/auth/calendar に設定して、ユーザーのカレンダーへの編集アクセス権を取得します。
  • 認証されたユーザーに、指定した calendarId を使用してカレンダーへの書き込みアクセス権があることを確認します(calendarIdcalendarList.get() を呼び出して accessRole を確認するなど)。

イベント メタデータを追加する

必要に応じて、カレンダー イベントを作成するときにイベントのメタデータを追加できます。作成時にメタデータを追加しない場合、events.update() を使用して多くのフィールドを更新できます。ただし、イベント ID などの一部のフィールドは、events.insert() オペレーション中にのみ設定できます。

場所

住所を [場所] フィールドに追加すると、次のような機能が利用できるようになります。

出発時間や、ルートが表示された地図を表示する。

イベント ID

イベントを作成するときに、独自のイベント ID を生成できます

フォーマット要件を満たすこれにより、ローカル データベース内のエンティティを Google カレンダーの予定と同期できます。また、カレンダーのバックエンドでオペレーションが正常に実行された後、ある時点でオペレーションが失敗した場合に、重複する予定が作成されるのを防ぎます。イベント ID が指定されていない場合は、サーバーが ID を生成します。詳細については、イベント ID リファレンスをご覧ください。

参加者

作成した予定は、

同じイベント ID で追加した参加者。挿入リクエストで sendNotificationstrue に設定すると、参加者にもイベントのメール通知が届きます。詳しくは、複数の参加者がいるイベントのガイドをご覧ください。

次の例は、イベントを作成し、そのメタデータを設定する方法を示しています。

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'))

Ruby

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 ドライブ ファイルを添付できます。添付ファイルを追加するには、events.insert() 以降でイベントを作成するときに、events.patch() などの更新の一部として追加します。

Google ドライブのファイルを予定に添付する手順は次の 2 つです。

  1. 通常は files.get() メソッドを使用して、 Drive API Files リソースからファイルの alternateLink URL、titlemimeType を取得します。
  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 で示されているように 3 つのタイプがあります。

  1. 一般ユーザー向けのハングアウト(eventHangout
  2. 従来のハングアウト( Google Workspace ユーザー向け)(非推奨、eventNamedHangout
  3. Google Meet(hangoutsMeet

ユーザーの特定のカレンダーでサポートされている会議の種類を確認するには、calendars コレクションと calendarList コレクションの conferenceProperties.allowedConferenceSolutionTypes を確認します。また、settings コレクションの autoAddHangouts 設定を確認することで、新しく作成されたすべてのイベントにハングアウトを作成するようにユーザーが設定しているかどうかを確認することもできます。

conferenceSolution には、type のほかに、次に示すように会議ソリューションの表現に使用できる name フィールドと iconUri フィールドも用意されています。

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 であることからわかります。カンファレンス情報が入力されると、ステータス コードが success に変わります。entryPoints フィールドには、ユーザーがダイヤルインできる動画 URI と電話 URI に関する情報が含まれます。

同じ会議の詳細を使用して複数のカレンダー イベントをスケジュールする場合は、conferenceData 全体を 1 つのイベントから別のイベントにコピーできます。

コピーは特定の状況で役立ちます。たとえば、応募者と面接者向けに個別のイベントを設定する採用アプリを開発しているとします。その場合、面接者が特定されないようにしつつ、すべての参加者が確実に同じカンファレンスの通話に参加できるようにする必要があります。