Analog Studio

カレンダー共有アプリ「TimeTree」のAPIを使おう!~イベント登録編~

概要

1500万人のユーザが利用するカレンダー共有アプリの「TimeTree」が外部サービスとの連携の為に API をリリースしました。(2019年5月30日)
そこで、そんなできたての API を使ってみましたので使い方を PHP や Javascript によるサンプルを使って解説します。

TimeTree API は、2023年12月22日をもって終了しました。本記事の内容はすでに利用できません。
https://timetreeapp.com/intl/ja/newsroom/2023-12-14/connect-app-api-202312

前回から大分間が空いてしまいましたが、今回はイベントの登録方法についてまとめます。

第1回「アクセストークン取得編」と第2回「カレンダー情報取得編」は以下のリンクからご確認下さい。

カレンダーにイベント(予定)を追加する

カレンダーにイベント (予定) を追加していきます。
PHP からの登録も Javascript からの追加も用途的には考えられるのでどちらもサンプルに示していきます。

Javascript から追加する場合は XHR Level.2 が使えるブラウザを前提としています。
管理画面など特定の管理者やそれに準じる人以外が使う場合には PHP をおススメします。

PHPを使ったサンプルコード

まずはブラウザに依らない PHP を使ったサンプルです。
今回も cURL は使用しないで file_get_contents() 関数を使いデータを送信します。
お使いのサーバが cURL に対応していれば使った方が楽です。(TimeTree 公式のサンプル通りに作れる)

登録するカレンダーの calendar_id が必要になるので事前に ID を取得しておいて下さい。
カレンダー情報取得編

送信するパラメータ詳細は公式ドキュメントをご確認下さい。
POST /calendars/:calendar_id/events

// アクセストークン // 事前にアプリ認証して取得しておく $access_token = '**************************'; // 登録するカレンダーのID // カレンダー情報一覧などから事前に取得しておく $calendar_id = '12345678'; // 登録するカレンダーのラベルID // カレンダー情報一覧などから事前に取得しておく $label_id = '12345678,1234'; // APIのリクエストURL $url = "https://timetreeapis.com/calendars/{$calendar_id}/events"; // 送信メソッド $method = 'POST'; // ヘッダ $header = array( 'Accept: application/vnd.timetree.v1+json', 'Content-Type: application/json', 'Authorization: Bearer '. $access_token, ); // 送信データ $param = array( 'data' => array( 'attributes' => array( 'title' => '登録するイベントのタイトル', 'category' => 'schedule', 'all_day' => false, 'start_at' => (new DateTime('2019-10-28 17:00'))->format(DateTime::ATOM), // ISO8601形式 ※format(DateTime::ISO8601)は正しくないので使えない 'start_timezone' => 'UTC', // DateTime::ATOMならUTCをしておけば正しく認識されるっぽい 'end_at' => (new DateTime('2019-10-28 19:00'))->format(DateTime::ATOM), // ISO8601形式 ※format(DateTime::ISO8601)は正しくないので使えない 'end_timezone' => 'UTC', // DateTime::ATOMならUTCをしておけば正しく認識されるっぽい 'description' => '予定の詳細情報', ), 'relationships' => array( 'label' => array( 'data' => array( 'id' => $label_id, 'type' => 'label', ), ), ), ), ); // file_get_contens関数でPOST送信する準備 $options = array( 'http' => array( 'method' => $method, 'header' => implode("\r\n", $header), 'content' => json_encode($param), 'ignore_errors' => true, // エラー発生時でも結果を受け取れるようにするフラグ 'protocol_version' => '1.1', ) ); // 送信する $result = json_decode(file_get_contents($url, false, stream_context_create($options)) ?: '[]', true);

上記コードを実行すれば $result に登録した結果が入ります。
結果の JSON は以下のようになります。

// 引用:https://developers.timetreeapp.com/ja/docs/api#post-calendarscalendar_idevents { "data": { "id": "c9c8e0fd66c34505a876d88cb4bb3b2a", "type": "event", "attributes": { "category": "schedule", "title": "Event title", "all_day": false, "start_at": "2019-03-18T09:00:00.000Z", "start_timezone": "UTC", "end_at": "2019-03-18T10:00:00.000Z", "end_timezone": "UTC", "recurrences": [], "description": "blah blah blah", "location": "Tokyo", "url": "https://example.com", "updated_at": "2019-03-18T09:53:33.123Z", "created_at": "2019-03-18T09:53:33.123Z" }, "relationships": { "creator": { "data": { "id": "1234,12345", "type": "user" } }, "label": { "data": { "id": "1234,1", "type": "label" } }, "attendees": { "data": [ { "id": "1234,12345", "type": "user" }, { "id": "1234,56789", "type": "user" } ] } } } }

ここで注意点が2つあります。ご注意下さい。

注意点1:日付のフォーマットは"DateTime::ISO8601"ではなく"DateTime::ATOM"を使う

PHP の DateTime クラスには ISO8601 形式の日付に整形してくれそうな "DateTime::ISO8601" が定義されています。
しかし、実際には ISO8601 とは互換性がありませんので、"DateTime::ATOM" を指定する必要があります。

PHP.net - DateTime クラス

イベントIDはDBなどに記録しておかないと再取得できない

登録したイベント ID ($result['data']['id']) は後から取得できないので必ずデータベースなどに記録しておいて下さい。
今後、TimeTree の API が拡大されれば後からでもイベント ID が取得できるようになるかもしれませんが、現時点ではできないのでデータ更新などをする場合はイベント ID を自分のサーバ等で管理する必要があります。

Javascriptを使ったサンプルコード

PHP よりも手軽に扱いたい時は Javascript の非同期通信を使うと良いでしょう。
管理画面などからページ遷移なく予定を追加したりデータ更新ができます。

// TimeTreeにイベントを追加する // 引数にはイベント情報とTimeTree情報の配列を与える const timetreeSetEvent = function($data, $tt){ const XHR = new XMLHttpRequest(); XHR.timeout = 10 * 1000; XHR.open("POST", "https://timetreeapis.com/calendars/" + $tt.calendar + "/events", true); XHR.setRequestHeader("Accept", "application/vnd.timetree.v1+json"); XHR.setRequestHeader("Content-Type", "application/json"); XHR.setRequestHeader("Authorization", "Bearer " + $tt.token); XHR.send(JSON.stringify($data)); XHR.onload = function(){ const result = XHR.responseText; console.log(result); const resultData = JSON.parse(result); console.log(resultData); // 以下必要な処理を実行 // resultDataに各種情報が配列で格納される }; }; // 実行する const data = { data : { attributes : { title : "登録するイベントのタイトル", category : "schedule", all_day : false, start_at : (new Date("2019-10-28 17:00")).toISOString(), start_timezone : "UTC", end_at : (new Date("2019-10-28 19:00")).toISOString(), end_timezone : "UTC", description : "予定の詳細情報", }, relationships : { label : { data : { id : "12345678,1234", // カレンダー情報一覧などからIDを事前に取得しておく type : "label", }, }, }, }, }; const tt = { token : "取得したアクセストークン", calendar : "12345678", // カレンダー情報一覧などからIDを事前に取得しておく }; timetreeSetEvent(data, tt);

Javascript なのでブラウザによっては動かないこともあるのでコード上で各メソッドが使用可能か確認して使うようにして下さい。
若しくは Chrome の最新版のみ動作保証するなどして下さい。

PHP と同様にイベント ID は現時点では再取得できないので DB などに記録しておきましょう。

イベントの更新や削除

更新は API へのリクエストメソッドである "POST" を "PUT" に変更してイベント ID を追加するだけです。簡単です。

削除はリクエストメソッドを "DELETE" にして下さい。
送信データは不要です。

Javascriptでのサンプルコード

メソッドを変更するだけなので手軽に試せるように Javascript のサンプルを以下に示します。PHP も同様です。

イベントの更新
// TimeTreeのイベント情報を更新する // 引数にはイベント情報の配列を与える const timetreeUpdateEvent = function($data, $tt){ const XHR = new XMLHttpRequest(); XHR.timeout = 10 * 1000; XHR.open("PUT", "https://timetreeapis.com/calendars/" + $tt.calendar + "/events/" + $tt.event, true); XHR.setRequestHeader("Accept", "application/vnd.timetree.v1+json"); XHR.setRequestHeader("Content-Type", "application/json"); XHR.setRequestHeader("Authorization", "Bearer " + $tt.token); XHR.send(JSON.stringify($data)); XHR.onload = function(){ const result = XHR.responseText; console.log(result); const resultData = JSON.parse(result); console.log(resultData); // 以下必要な処理を実行 // resultDataに各種情報が配列で格納される }; }; // 実行する const data = { data : { attributes : { title : "【更新】登録するイベントのタイトル", category : "schedule", all_day : false, start_at : (new Date("2019-10-29 17:15")).toISOString(), start_timezone : "UTC", end_at : (new Date("2019-10-29 19:15")).toISOString(), end_timezone : "UTC", description : "予定の詳細情報\n更新したよ", }, relationships : { label : { data : { id : "12345678,4321", // カレンダー情報一覧などからIDを事前に取得しておく type : "label", }, }, }, }, }; const tt = { token : "取得したアクセストークン", calendar : "12345678", // カレンダー情報一覧などからIDを事前に取得しておく event : "a3ad…943d4", // イベント登録時に取得したID }; timetreeUpdateEvent(data, tt);
イベントの削除
// TimeTreeのイベントを削除する const timetreeDeleteEvent = function($tt){ const token = "取得したアクセストークン"; const XHR = new XMLHttpRequest(); XHR.timeout = 10 * 1000; XHR.open("DELETE", "https://timetreeapis.com/calendars/" + $tt.calendar + "/events/" + $tt.event, true); XHR.setRequestHeader("Accept", "application/vnd.timetree.v1+json"); XHR.setRequestHeader("Authorization", "Bearer " + $tt.token); XHR.send(); // 引数は不要 XHR.onload = function(){ // レスポンスボディは無し if(XHR.status == 200 || XHR.status == 201 || XHR.status == 204){ console.log("Delete Completed!!"); } else if(XHR.status >= 400){ console.log("An error has occurred...."); } // 以下必要な処理を実行 }; }; // 実行する const tt = { token : "取得したアクセストークン", calendar : "12345678", // カレンダー情報一覧などからIDを事前に取得しておく event : "a3ad…943d4", // イベント登録時に取得したID }; timetreeDeleteEvent(tt);

まとめ

以上、カレンダーへのイベント追加の方法でした。
難しくはありませんが、PHP での ISO8601 形式の日付だけ注意が必要ですね。