イベントを作成する

ユーザーが最適なハイキング ルートを見つけるのに役立つアプリを考えてみましょう。ハイキングの計画をカレンダーの予定として追加すると、ユーザーは自動的に整理された状態を維持できます。Google カレンダーで予定を共有し、リマインダーを設定しておけば、ストレスなく準備できます。また、Google サービスのシームレスな統合により、Google Now から出発時刻が通知され、Google マップから会議場所への経路が時間どおりに案内されます。

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

イベントの追加

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

  • calendarId はカレンダーの識別子です。予定を作成するカレンダーのメールアドレスか、ログインしているユーザーのメインカレンダーを使用する特別なキーワード '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
イベントを作成する際に、Google の形式要件に準拠した独自のイベント ID を生成することもできます。これにより、ローカル データベース内のエンティティを Google カレンダーのイベントと同期させることができます。また、カレンダー バックエンドでオペレーションが正常に実行された後、どこかの時点で失敗した場合に、重複する予定が作成されるのを防ぎます。イベント ID が指定されていない場合、サーバーによって生成されます。詳細については、イベント ID リファレンスをご覧ください。
参加者
作成した予定は、同じ予定 ID で追加した参加者のメインの Google カレンダーすべてに表示されます。挿入リクエストで sendUpdates"all" または "externalOnly" に設定すると、対応する出席者にイベントのメール通知が届きます。詳しくは、複数の参加者がいるイベントをご覧ください。

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

Go

// Refer to the Go quickstart on how to setup the environment:
// https://developers.google.com/workspace/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/workspace/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/workspace/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/workspace/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/workspace/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 ドキュメントの会議メモ、Google スプレッドシートの予算、Google スライドのプレゼンテーションなど、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()

予定にビデオ会議と電話会議を追加する

予定を ハングアウトGoogle 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 設定を確認することで、ユーザーが新しく作成したすべての予定でハングアウトを作成することを希望しているかどうかを確認することもできます。

type の他に、conferenceSolution には、会議ソリューションを表すために使用できる 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);

イベントの新しい会議を作成するには、新しく生成された requestId(ランダムな string にすることも可能)を含む createRequest を指定します。会議は非同期で作成されますが、リクエストのステータスを常に確認して、ユーザーに状況を知らせることができます。

たとえば、既存のイベントの会議の生成をリクエストするには:

JavaScript

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

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

この呼び出しに対するレスポンスには、完全に設定された conferenceData が含まれていない場合があります。これは、status フィールドのステータス コード pending で示されます。会議情報が入力されると、ステータス コードが success に変わります。entryPoints フィールドには、ユーザーがダイヤルインできる動画と電話の URI に関する情報が含まれています。

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

コピーは、特定の状況で役立ちます。たとえば、候補者と面接官用に別々のイベントを設定する採用アプリケーションを開発しているとします。面接官の身元を保護しつつ、すべての参加者が同じ電話会議に参加できるようにする必要があります。