Google Calendar API を使って1日の予定を一覧するPHPスクリプトを作る
そんなスクリプトをわざわざ作らなくても,Settings -> Calendars -> CALENDAR -> Notifications -> Daily agenda にチェックを入れておけば,5am(実際は4:30am頃?)にメールで予定一覧を送ってくれる.が,フォーマットが気に入らない(携帯メールに転送すると文字数制限をオーバーする),好きなメールアドレスに送れない(G-mailのフィルタで転送すればいいが)といった問題があるので, Google Calendar API を使って,1日の予定を一覧するPHPスクリプトを作ってみた.
Google Calendar API
Google Calendar の Settings -> Calendars -> CALENDAR -> Private Address: -> XML を選択すると,
http://www.google.com/calendar/feeds/USERID/private-MAGICCOOKIE/basic
のようなフォーマットのURLが表示される.USERID,MAGICCOOKIE は個々のユーザのカレンダーに固有の値(他人に知られるとよろしくない).ここで,basic の代わりに適当なパラメタを設定してやることで,例えばある日の予定をXML形式で得ることができる.Data API Reference Guideを参考に,11月4日の予定を取得するようにパラメタを設定すると,
こんな感じになる.
この結果のXMLを適当にソートするなどして表示すれば,目的は達せられる.
本日の予定を一覧するPHPスクリプト
以下のPHPスクリプトでは,複数のカレンダーを統合できるようにした(カレンダーごとに USERID と MAGICCOOKIE が異なり,個別にXMLを取得しなければならない).
<?php class TEvent { public $StartTime = ''; public $EndTime = ''; public $Title = ''; public $Description = ''; } function CmpEvents($a, $b) { if ($a->StartTime == $b->StartTime) return 0; if ($a->StartTime=="all day") return -1; if ($b->StartTime=="all day") return 1; return ($a->StartTime < $b->StartTime) ? -1 : 1; } function agenda_of_google_calendar($htitle,$userid,$magicCookie,&$events) { // $date= '2009-09-30'; // for test $date= date("Y-m-d"); $target= 'http://www.google.com/calendar/feeds/' . $userid . '/private-' . $magicCookie . '/full?' . 'start-min='.$date.'T00:00:00' . '&start-max='.$date.'T23:59:59' . '&orderby=starttime&sortorder=a' .'&singleevents=true'; $xml = simplexml_load_file($target); // 2009-05-15T14:30:00.000+09:00 $date_pattern='([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{2}:[0-9]{2})(:[0-9]{2})'; foreach ($xml->entry as $item) { $gd = $item->children('http://schemas.google.com/g/2005'); $startTime = $gd->when->attributes()->startTime; $endTime = $gd->when->attributes()->endTime; $title = $item->title; $description = $item->content; if (ereg($date_pattern, $startTime, $sregs) && ereg($date_pattern, $endTime, $eregs)) { $event= new TEvent(); $event->StartTime=$sregs[2]; $event->EndTime=$eregs[2]; $event->Title=$title; $event->Description=$description.$htitle; $events[]=$event; } else { $event= new TEvent(); $event->StartTime='all day'; $event->Title=$title; $event->Description=$description.$htitle; $events[]=$event; } } } $events= array(); $userid= 'USERID1'; $magicCookie= 'MAGICCOOKIE1'; agenda_of_google_calendar(' (Akihiko)', $userid, $magicCookie, $events); $userid= 'USERID2'; $magicCookie= 'MAGICCOOKIE2'; agenda_of_google_calendar(' (Lab.)', $userid, $magicCookie, $events); usort($events, CmpEvents); // style(hrml): // $eol="<br>\n"; // $date_style=array('<font color="#882222">','</font>'); // $cont_style=array('<font color="#0000ff">','</font>'); // $indent=''; // $space=' '; // style(text): $eol="\n"; $date_style=array('',''); $cont_style=array('',''); $indent=''; $space=' '; echo "Agenda@".date("Y-m-d(D)")."$eol"; $prev_is_allday=false; $delim=''; foreach ($events as $item) { if ($item->StartTime!='all day') { echo $delim; echo $indent.$date_style[0].$item->StartTime.'-'.$item->EndTime.': '.$date_style[1] .$eol .$indent.$space.$cont_style[0].$item->Title.'; '.$item->Description.$cont_style[1].$eol; } else { if (!$prev_is_allday) { echo $delim; echo $indent.$date_style[0].'all day: '.$date_style[1] .$eol; $prev_is_allday=true; } echo $indent.$space.$cont_style[0].$item->Title.'; '.$item->Description.$cont_style[1].$eol; } $delim=$eol; } ?>
すべてのイベントを開始時間でソートできるようにイベントクラス(TEvent)を定義している.CmpEvents は開始時間でソートするための比較関数.開始時間が all day(終日)の場合は最初にくるようにしている.
関数 agenda_of_google_calendar($htitle,$userid,$magicCookie,&$events) で予定を取得し,TEventクラスの配列 $events に保存する.$htitle には Description の最後に追加する文字列, $userid には USERID, $magicCookie には MAGICCOOKIE をそれぞれ指定する.
複数のカレンダーを統合するには,それぞれのカレンダーごとに USERID と MAGICCOOKIE を取得して,複数回 agenda_of_google_calendar を実行する.上のサンプルでは2つのカレンダーを統合している.
usort でイベントの配列を開始時間でソートする.それ以降は,出力のコード.ここではテキストフォーマットで出力するようにしているが, style(text): 以下5行をコメントアウトし, style(html): 以下5行をアンコメントすれば,HTML形式で出力できる.
おまけ:毎日メールで送信
CRON を使うのがてっとりばやいと思う. crontab -e で,以下のような一文を追加すれば,毎日4:30amにメールが(MAILADDRESSに)送られる.
30 4 * * * php /home/akihiko/bin/php/google-calendar.php | nkf -s | mail -s "Agenda(`/home/akihiko/bin/linux/today`)" MAILADDRESS
なお, /home/akihiko/bin/php/google-calendar.php は上記のスクリプト,/home/akihiko/bin/linux/today は日付を返すbashスクリプト:
#!/bin/bash LANG=C date +'%m/%d(%a)'
メールで送信するためには,常時稼働しているサーバマシン上で CRON を実行する必要がある.Debian でのメール送信には Exim4 を使うとよいようだ(以下の参考URLを参照).