OpenPNE3プラグインで簡単マッシュアップ!
03 / 15 月曜日 2010
OpenPNE開発チームの深町です。
カヤックさんの多すぎるWebサービスの中に、im.kayac.comというサービスがあります。「I’m Kayac? 自己紹介?」とか思ってたんですが、どうやらInstant Messageの略でIMのようです。
im.kayac.comは、APIにリクエストを投げるだけで他のサービスに通知を飛ばせる便利なサービスです。専用のiPhoneアプリを入れることでiPhoneにポップアップ通知をすることができます。ちなみに僕はiPhoneは持っていません。Touchです。
おぉ、なんか便利そうだ。問題は使い道だなぁ。何に使おう。
製品テストにいいかも?
最近、OpenPNE3の単体テストを走らせていたのですが、時間の長いこと長いこと。その間ぼーっとしてるわけにもいかないのでTumblrでせっせとリブログを繰り返しているのですが、気づいたら終わってる。非効率だ。終わったら通知させるようにしよう。
$ symfony test:unit; curl -d ‘message=OpenPNE3 Unit Tests were done.’ http://im.kayac.com/api/post/nitro_idiot
こうして単体テストを走らせておくと、終わったタイミングで御苑で花見をしている僕のiPhoneがピコンとなるわけです。あ、僕はiPhoneは持ってませんでした。Touchです。
とてもクールなサービスですね。
OpenPNEとの連携
以上、im.kayac.comの紹介でした。カヤックでは製品テストが好きなプログラマを募集しています!
…あ、僕はカヤック社員ではありませんでした。OpenPNE開発者です。
やっぱ他社のサービス紹介だけでもあれなのでOpenPNEとの連携でも考えたほうがいいですよねー :p
opImKayacComPluginってのはどう?
普段僕はOpenPNE3のプラグインなんて作らないのですが、「えー、深町さんひょっとして作れないんじゃないですかぁ?きゃははー」とか言われると嫌なのでチュートリアルがてら作ってみたいと思います。いや、作れるんだって!本気出せば!
今回作るのはフレンドが日記を書いたり、自分のにコメントがついたときにim.kayac.comを使ってiPhoneに通知できるようにするプラグイン「opImKayacComPlugin」です。
0. 実装方針
OpenPNE3で使われているフレームワークsymfonyには「イベントディスパッチャ」という機構があります。これは、拡張可能なプログラムを書ける大変クールな機構です。
OpenPNE3ではこの機構を使って、ページの読み込みの前後(正確にはアクションの前後)で、好きなコードを走らせることができます。たとえばopAshiatoPluginでは、メンバーのホーム・日記などを見たときに”あしあと”をつける処理をしています。
今回も同じ要領で、日記の作成のあとにim.kayac.comに通知を投げる処理を加えたいと思います。
1. config.phpでイベントを受け取る
OpenPNEのプラグインを作るときに、必ず実行させたいコードってたまにありますよね。そういうコードは config/config.php に書くといいです。今回イベントのリスナーは必ず追加したいのでここに書きます。
※追記 : 卜部さんから、sfPluginConfigurationを継承するクラスを作ることで、リスナーと処理を一緒のファイルに書けるよ、というアドバイスをもらいました。以下の例ではconfig/opImKayacComConfiguration.class.php というファイルに記述するといいプログラムになるかもしれません。参考 : http://github.com/ebihara/opPluginChannelServerPlugin/blob/master/config/opPluginChannelServerPluginConfiguration.class.php
・config/config.php
<?php // 日記が書き込まれたら // opImKayacComListener::listenToPostDiaryCreate()を実行してね $this->dispatcher->connect( 'op_action.post_execute_diary_create', array('opImKayacComListener', 'listenToPostDiaryCreate') );
OpenPNEのアクションが実行されると、アクションの前にop_action.pre_execute_{module}_{action}、アクションの後にop_action.post_execute_{module}_{action}という名前のイベントが発生します。これに対してconnect()を使ってリスナーを登録します。listenじゃなくてconnectなのが紛らわしいです。
opImKayacComListenerクラスはまだ作っていないので、この状態だとエラーになりますが、とりあえずここは放っておきましょう。
2. im.kayac.comに通知を投げるには
まずはim.kayac.comに通知を投げる必要があります。im.kayac.comはPOSTメソッドでHTTPリクエストを飛ばせばいいです。PHPからはfile_get_contents()を使います。
static public function postToImKayacCom() { $params = array( 'password' => 'hogehoge', 'message' => '[op3] うべー', ); $header = array( 'Content-Type: application/x-www-form-urlencoded', 'Content-Length: '.strlen($params), ); $options = array( 'http' => array( 'method' => 'POST', 'header' => implode("\r\n", $header), 'content' => $params, ) ); file_get_contents('http://im.kayac.com/api/post/nitro_idiot', false, stream_context_create($options)); }
うべー。
こういうstaticなユーティリティ関数を使いたい場合は、慣習としてlib/util/にファイルを置きます。ここではlib/util/opImKayacComPluginToolkit.class.phpというファイルを作りました。
さて、いよいよ受け取ったイベントで通知処理をする段階です。
3. opImKayacComListenerクラスを作る
さて、いよいよメインの処理です。といっても大したことをするわけじゃなくて、さっき作ったopImKayacComPluginToolkit::postToImKayacCom()を呼び出して通知するくらいです。
・lib/opImKayacComListener.class.php
<?php class opImKayacComListener { static public function listenToPostDiaryCreate() { opImKayacComPluginToolkit::postToImKayacCom('nitro_idiot'); } }
ここで通知するユーザの選択もできます。たとえば、自分が日記を書いたときまでiPhoneに通知されたらうざいですよね。その場合は sfContext::getInstance()->getUser()->getMemberId() でアクセスしているユーザのMemberIdを取得して判定することができます。
さぁ、これで日記を投稿すれば僕に通知がくるようになりました。最後まで書いてると上司から肩を叩かれそうなのでチュートリアルはここまで!
まとめ
・必ず実行したいコードは config/config.php に書く
・ユーティリティ関数はlib/util以下に置く
・イベントディスパッチャを使えば既存の機能を簡単に拡張できる
さらに改良するには
ただ、このままだと僕(nitro_idiot)にしか通知を送れません。POSTするURLのユーザ名を引数で受け取ることでそれぞれのユーザに通知することができます。
その場合、それぞれのユーザにim.kayac.comのアカウントを設定させる必要もあります。これはconfig/doctrine/schema.yml に新規テーブルの記述を加えて、config/member_config.yml と lib/form/MemberConfigForm/MemberConfigImKayacComForm.class.php を追加すれば実現できます。
他には日記コメントがついたら知りたい!とか、メッセージをすぐ確認したい!とかにも同じように対応することができます。
今あるOpenPNEのプラグインは、opDiaryPluginとかopMessagePluginとか、大きなものが多いですが、これくらい小さなものでも面白いものが作れるとわかっていただけたでしょうか?
今日作ったプラグインは…
今日作ったopImKayacComPluginはもちろんオープンソースです!
http://github.com/fukamachi/opImKayacComPlugin
この記事のコードからかなり変わっちゃっていますが、原型は同じなので参考にしていただけると幸いです。わからないことがあれば公式SNSやTwitter宛に気軽に聞いてください :)