2006-06
03
02:20:00
Google Calendar API のTips(覚え書き)


Google Calendar APIをC#で弄っていたんだけど、まだまだ日本語情報は少ないですね。
「Developer’s Guide」も網羅されているようで、細かいところがよく分からない。特にC#とかのライブラリを使った場合の動作とか。(英文をいまいち理解していないという話はある・・)
で、特にUpdate/Deleteあたりではまったので、自分用も含めて覚え書き。
基本的にC#前提ですが、要領は他の言語でも同じかと。

■最初のFeed取得URLでRead OnlyかWrite可能か決定される

後述になるけど、Google Calendar(以下GC)のデータをUpdate/Deleteするには最初にFeedを取り出しておく必要がある。C#ではAtomFeedクラスへ読み込むことになる。
ここでFeedを取り出すためのURLは、

http://www.google.com/calendar/feeds/userID/visibility/projection

となる。
このvisibilityとprojectionの組み合わせでFeed中のEntry(C#ではAtomEntryクラス)を用いてRead OnlyのみかWrite可能が決定してしまう。
Write可能にするためには、「Developer’s Guide」のCalendar feed typesにもあるように、visibilityを「private」としておく必要がある。
例えば、「http://www.google.com/calendar/feeds/userID/private/full」という感じ。
当然認証が事前に必要になるけど、C#ならsetUserCredentials一発で問題なし。ラクチン。
例えば、以下のようなコードになる。

CalendarService service = new CalendarService("Sample/1.0");
service.setUserCredentials("user@example.com", "password");
FeedQuery query = new FeedQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/user@example.com/private/full");
AtomFeed calFeed = service.Query(query);

因みにvisibilityがprivate-magicCookieの場合はRead Onlyなので注意。
これは多分RSSリーダーでPrivateなFeedを読みたい時用で、プログラミング向けでは無い。
また、projectionは基本的にFeedに含まれる情報量を指定する。大抵fullでいいんじゃないかなー。

■EntryがRead OnlyかWrite可能かはEditUri変数/ReadOnly変数が決定する

Atomの規定そのままなんだけど、XML的には前項のFeed中の

<link href="http://www.google.com/calendar/feeds/user@example.com/private/full/pbsclfag96hjkkno6d2mgb2gi40/53294949780" rel="edit" type="application/atom+xml" />

といったURLへPUTすることでUpdateが行える。同じURLへDELETEするとDeleteになる。
で、このURLは可変なため、事前にFeedを入手しない限りリクエスト先URLが分からないのでUpdate/Deleteが不能、というのが前項の意味。
一方C#では、AtomEntryクラスにReadOnly変数があって、上記のアトリビュート(EditUri変数に格納される)が無いとtrueとなり、UpdateやDeleteをしてもエラーになってしまう。
(但しInsertは可能。)
またAtomEntryをnewした場合もtrueのままで、かつEditUri変数自体もReadのみのようなので、何らかの方法でEditUriを入手したとしてもユーザーが作成したAtomEntryでUpdate/Deleteは不可となっている。
素直にFeedを手に入れてからUpdate/Deleteしましょう。
なお、Insertの場合は認証さえ通っていればOKなので、AtomEntryをnewして、適当に値をぶちこんでInsertしましょう。

■開始/終了時刻とロケーションの指定方法

Javaの場合はサンプルが載っているのですぐ分かるんだけど、C#は軽くスルーされているのでよく分からず。この辺は不親切。
勘で試したら、うまくいった(ので、本当にこれが正式な方法かどうかは不明・・)。
開始/終了時刻はWhenクラス、ロケーションはWhereクラスで指定できる。
これをAllayList AtomEntry.ExtensionElementsへAddしてやればいい。
こんな感じ。

When when = new When();
when.StartTime = new DateTime(2006, 6, 1, 10, 0, 0);
when.EndTime = new DateTime(2006, 6, 1, 11, 0, 0);
Where where = new Where();
where.ValueString = "Tokyo, Japan";
entry.ExtensionElements.Clear();
entry.ExtensionElements.Add(when);
entry.ExtensionElements.Add(where);

■終日予定の指定方法が分からない・・

「Developer’s Guide」のCommon Elementsによれば、

A one-day event:
<gd:when startTime="2005-06-06"/>

とある(つまり時刻を付加しない)のだけど、C#的にはWhen.StartTimeとWhen.EndTimeはDateTimeなので・・。
試しに時刻を「00:00:00」としてみたり、EndTimeを追加しなかったり、同一時刻にもしてみたけど、終日にならない。
もう少し見てみます・・。
追記しました。

Google Calendar API のTips(覚え書き)」への6件のフィードバック

  1. お返事ありがとうございます。
    そんな前からGcalと#をやってたなんて先見性ありますねー

    自分はdelphiとphp専門でして
    最近C#をやりはじめました。

    問題の時間の取得は解決いたしました。

    atomfeedではなくeventfeedを使うと参照できるようです。
    今度は、ピンポイントで予定を削除する方法がわからなくてさがしております。

    queryで期日指定で削除できるんですが同日イベントまで削除されてしまうので困ってます。
    たぶんqueryにイベントIDみたいなユニークな値を入れて削除するとおもうのですが
    その値がなになのかも・・・・(>_<)

    1. Eventのedit URLを指定してDELETEメソッドで削除できると思いますよ。
      C#から離れてAPIを見てみてはどうでしょう

      1. できましたーーーー
        イベントIDが取得できましたのでそのまま投げて、ループ中に適合するIDがあったら
        削除するようにしました。

        あと謎な部分があるのですがDataGridViewには複数行で表示されるのに
        textBoxのMultiLineにいれると開業されないのはなぜなんでしょう?

        \r\nを置き換えたりを置き換えたりためしてみましたが全部つながった状態でtextboxに
        表示されてしまいます。

      2. (>_<)
        やはりROCAさんの言うとおりedit URLでする事にしました。

        理由はeventidで指定していると色がつけられないっぽいからです。

  2. はじめまして、記事拝見させていただき自分もちょうせんしてみました。

    そこでよくわからない部分があるのですが
    starttimeやendtimeはC#で参照できないものなのでしょうか?

    海外等いろいろさがしてみたのですが動作するものがみつかりませんでした
    すいませんが、もしよろしかったらご指導いただけないでしょうか。

    1. もう4年も前の記事なので忘れてしまいました・・。ライブラリを修正すればできるのかも知れませんけど
      ごめんなさい

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください