(いわゆる宣伝エントリーなので余裕のある方はお読みください)

お世話になっております。ソーシャルグラフ開発チーム asannou です。
Gmailとmixiがつながりました」ということで、Gmail™のアドレス帳(連絡先)からマイミクシィを追加したり、友人をmixiに招待したりできるようになりました。以前から、メールアドレスでマイミク登録という機能がありますが、ここにアドレス帳のメールアドレスを一個ずつコピペするかわりに、まとめてインポートしてサクサクとマイミク申請&招待できるようになるイメージですね。
今回は技術的な部分のご紹介をさせていただきたいと思います。

アクセス権限を委譲する

本機能では、Gmail™のアドレス帳をインポートする際に、OAuthという仕組みを利用してアクセスをおこなっているので、mixiに、Googleアカウントのユーザー名とパスワードを入力する必要がなく、Gmail™のアドレス帳のみにアクセスする権限を与えられる(委譲できる)ようになっています。

Googleアカウントのログイン画面

Googleアカウントのログイン画面


OAuthの認可画面

OAuthの認可画面

こちらが実際にインポートをするときのスクリーンショットですが、Googleのログイン画面がポップアップされているのがわかります。ここに、Googleアカウントのユーザー名とパスワードを入力し、リクエストを許可することによって、アクセス権限が委譲され、アドレス帳のインポートが可能になるわけです。アドレスバーの先頭が https://www.google.com/ となっていることを確認してから、パスワードを入力するようにしてくださいね。

権限の委譲について、もうちょっと詳しく説明しますと、今回はOpenIDをベースにOAuthを乗せた形の、OpenID OAuth Extensionを採用してみました。理由としては、同時にOpenID User Interface Extensionに対応することで、前述のような、権限の委譲が直感的にわかりやすいUI(mixiとGoogleのfaviconが並んで表示されるとか)を提供する狙いがあります。Extensionとか言われてもよくわかんない、という方はとりあえず、「OAuth単体で使うより、OpenIDと組み合わせたほうが、おしゃれなポップアップウィンドウを出せるから、そうした。あとOpenIDを流行らせたい」とご理解ください。

とにかく、これにてmixiは、一気にOAuth ConsumerおよびOpenID Relying Partyになることができました。技術的に、mixiにOpenIDでログインしたり、新規登録するための条件が整ったということですので、希望される方はどこかでつぶやくと、私の来期あたりのコミットメントに「OpenIDによるログイン機能のリリース」が追加されるかもしれません。
もうお忘れになっている方もいらっしゃるかもしれませんが、mixiはOpenID Providerでもあるので、よろしければそちらもあわせてご利用ください。

ODF

そもそも、ウェブメールのアドレス帳をインポートする機能なんていうのは、今やSNSでは標準装備だったりします。
実は、2年ほど前にODFで取り組んだネタが発端だったのですが、紆余曲折がありまして、一旦ペンディングになっていたのでした。そんなプロジェクトを拾い上げてくれた、今のチームのリーダーや、一緒に仕様を考えてくれたディレクターには感謝です。
mixiのユーザー層で、Gmail™を利用されている方の割合は多くありませんが、スマートフォンのシェアが伸びていき、サーバサイドでアドレス帳を管理するのが一般的になれば、このような機能も活きてくるのではないかと思っています。
それにしても、当時の資料のタイムスタンプが2008年などとなっているのを見ると、胸が熱くなりますね。

サードパーティにパスワードを預けること

逆に、OAuthのような、限定的に権限を委譲できる仕組みを利用しないことにより、思いもよらないリスクが存在するケースもあります。
最近、mixiのリソースにアクセスするために、mixiのログインメールアドレスとパスワードを要求する、サードパーティ製のウェブサービスを多く見かけるようになりました。mixiはSNSという性質上、サードパーティにパスワードを預けてしまうと、自分のコンテンツだけでなく、マイミクが自分に対して、「友人まで公開」しているプロフィールや日記などにアクセスする権限を与えたことと等価となってしまいます。自分がリスクを負うだけならまだしも、マイミクの全員にそのことを納得してもらうのは難しいですよね。。。また、「パスワードは目的以外に使用することはありません」と但し書きがあり、それが真実だとしても、なんらかのトラブルでそのサードパーティから、mixiのパスワードが流出しないとも言い切れません。そのようなサービスにパスワードを預ける前に、上記のことを思い出していただけますよう、どうかよろしくお願いいたします。

とはいえ、mixiにはAPIでアクセスできないリソースがたくさんあります。
パスワードで認証をおこなうウェブサービスである限り、ユーザビリティを確保しながら、サードパーティからのパスワードによるアクセスを完全に防ぐ手段は現状ありません。ミクシィのエンジニアであるという立場を離れて言うと、サービス提供者は可能な限り、OAuthを利用して、サードパーティが安全に、すべてのリソースにアクセスできるAPIを用意し、そちらの利用を啓蒙していくべきだと考えます。

少し話が脱線してしまいました。
パスワードの扱いについて考えつつ、まずはこの機能でGmail™の友人たちとmixiって(つながって)みてはいかがでしょうか。

最後になりましたが、Google Contacts Data APIの提供と、ブランドの使用許諾をくださいましたGoogle社様には、心より御礼申し上げます。

はじめまして。ミュージック開発チームのtomと申します。名前はtomですが純日本人です。(本名も”tom”でちゃんと漢字があります。)

今回は、”オンラインコーヒーメーカー萌香たん”を作ったりできることでおなじみのODFをちょっとお得に使うための、「ODF繰り越し制度」の紹介と、その制度を利用して私が作っているTokyo CabinetのHaskellバインディングを紹介させていただければと思います。

ODF繰り越し制度

弊社のエンジニアは、ODF(One Day Free)という制度を使って、毎週金曜日に自分が好きなことに取り組むことができます。このODF制度、四半期ごとに実施する or しないを申告するのですが、このときになんと「繰り越す」という選択肢が用意されているのです。

普通のODFでは、四半期(3ヶ月)の間、週1日を自由な時間として確保することができます。とは言っても忙しい時期は毎週毎週時間を確保することが難しかったりします。また、1日好きなことをやっても、続きをやるまでに1週間も間があいてしまうと、集中が途切れてしまって、熱が冷めてしまったりしがちです。

そこで、ODFを「繰り越す」ということをすると、次の四半期の中のどこか1ヶ月をまるまる自分の自由な時間にすることができるのです。(3ヶ月間毎週1日を積み立てるとおおよそ12日なので、それを2回分で24日ぐらい確保できる。)One Day Freeならぬ、One Month Freeです。しかも、その1ヶ月の間は自分の好きなことに集中できるので、本当に好きなことを集中してやるには最適です。

この制度、まだまだ実験的な試みで実施者の数は多くないですが私も先月実施させていただき、1ヶ月という時間を自分の好きなことに費やすことができました。

Tokyo CabinetのHaskellバインディング

と、いうわけで作ったのがTokyo Cabinet(以下TC)のHaskellバインディングです。

あらかじめ断っておきますが、以下で紹介するライブラリは、TCの作者であるmikioさんになんの断りもなく、私個人が勝手に作ったものです。本家TCが正式にHaskellバインディングをサポートしたという話ではありません。Haskellバインディングに関する質問や不具合・バグ報告はmikioさんではなく、私の方までお願いいたします。(tom.lpsd < at > gmail.com)

インストール

PerlにはCPANという素晴らしい仕組みがありますが、Haskellにもそれに近い仕組みが用意されています。

HackageDB:   http://hackage.haskell.org/packages/hackage.html

上記サイトに、有用なライブラリが集められています。これらは、cabal-installというパッケージに含まれているcabalコマンドを使って簡単にインストールすることができます。TCのバインディングは、tokyocabinet-haskellというパッケージ名で登録してありますので、

$ cabal update
$ cabal install tokyocabinet-haskell

とコマンドを叩けばインストールできるはずです。TCのヘッダやライブラリを特殊な場所にインストールしている場合は、

$ cabal install tokyocabinet-haskell --extra-lib-dirs=/path/to/tc/lib --extra-include-dirs=/path/to/tc/include

としてください。

使い方

TCに関する操作は、ほとんどの場合、入出力や状態変化を伴いますので、基本的にIOモナドの中で行います。
関数名やデータ型は基本的にTCのパッケージに含まれるtokyocabinet.idlに準拠しているはずです。(本家に追いついていないところも多々ありますが。。)
ハッシュデータベースをいじるコード例は以下のようになります。

import Control.Monad (unless)
import Database.TokyoCabinet.HDB

main :: IO ()
main = do hdb <- new
          open hdb "casket.tch" [OWRITER, OCREAT] >>= err hdb
          put hdb "foo" "hop"  >>= err hdb
          put hdb "bar" "step" >>= err hdb
          put hdb "baz" "jump" >>= err hdb
          get hdb "foo" >>= maybe (error "get error") putStrLn
          iterinit hdb
          iternext hdb >>= maybe (error "iternext error") putStrLn
          close hdb
          return ()
    where
      err hdb = flip unless $ ecode hdb >>= print

new→open→ほげほげ→closeという流れは他の言語バインディングを使うのと変わりません。
BDB, FDBについてもほぼ同様に使うことができます。
まだまだ全然記述が不足しているのですが、リファレンスもあります。

keyとvalueの型は?

Haskellは静的な型を持つ言語です。TCでputやgetといった操作をするときのkey-value値にも型が必要です。型はHaskellでプログラムを書く上での主役になるので、その選択も非常に重要です。

候補1: String

はじめはkey-valueどちらもString型でよいかと考えました。String型は、Haskellで文字列を扱う際の選択肢としてもっとも気軽で使いやすいものです。多くの場合、keyとvalueは文字列として扱うことが予想されるため、これでも十分使えそうです。しかし、Stringの実体は文字列のリストです。TCに格納するためにバイト列にシリアライズする必要がありますが、この際にもオーバーヘッドが生じます。

候補2: ByteString

そこで次に考えたのがByteStringを使う方法です。bytestringパッケージに付属している、Data.ByteString.Unsafeというモジュールの関数を使うと、O(1)でCの文字列(バイト列)へシリアライズができます。これはよさそうです。
ということで、しばらくはByteStringをベースにした実装をしていました。しかしTCのtchdbaddintや、tchdnadddoubleといった文字列以外のvalue値を扱う関数を実装し始めた辺りで、ByteStringだけだとつらいかなと思うようになりました。keyやvalueの値として、IntやDoubleといった型も使いたくなったのです。

これを実現するために、いろいろと調べていくとbinaryというパッケージにたどり着きました。これを使えば、任意の型をByteStringに変換するできるため、TCのkey-value値もByteStringにしておけばいろいろうまく行きそうです。ただしこれでも少し気に入らない点がありました。これを使うコードでは、TCに格納したい値をユーザがいちいち明示的にByteStringに変換しなければならないという点です。それぐらいはラッパーを書けばなんとかなるとか、別に些細な問題だろうという見方もあると思いますが、個人的にはちょっとすっきりしないなぁと思ったのです。また、binaryパッケージが、ghcに付属のパッケージではないことも懸念点でした。binaryパッケージにたよって、key-valueの型をByteStringにすると、デフォルトのbinaryパッケージが入っていない状態ではInt型すら気軽にstoreできないからです。

Storable

とここまで悩んで、結局Database.TokyoCabinet.Storableというクラスを導入し、String、ByteString、Int、Doubleなどの型をそのクラスのインスタンスとすることにしました。こうすることで、

val :: Int
val = 100
put hdb "foo" val
-- ↑単純に 'put hdb "foo" 100' とすると100がDouble型と解釈されてしまうようなので、あえて型を明示しています
put hdb "bar" "baz"
put hdb (pack "hoge") (pack "fuga")

というように、これまで候補に挙がった型をそのままputやgetに渡すことができるようになります。

ただしこのやり方も完全ではありません。TCにputした後は、シリアライズする前の型が何だったのか、という情報が失われます。Intの値をputしたのに、getするときにString型で取り出すということができてしまいます。その結果int型をあらわしているバイト列を、無理やり文字列として読んでしまったり、ということが起こります。どちらにせよ、シリアライズされて一旦外の世界に出たデータを読むという性質上、静的な型検査で解決できる問題ではありません。ただ、こういった不整合は、発見しづらいバグを生んでしまう可能性があるので、なんとかしたいなと思っています。何か良い案があればアドバイスいただけると助かります。

TDBは?

リファレンスを見て気づかれた方もいるかも知れませんが、hackageにアップしているバージョンでは、テーブルデータベースをサポートしていません。単純にODF期間中に仕上がらなかったからという理由です。
が、その後も自分の時間を使って継続的に開発をし、githubにあがっている最新バージョンでは、TDBとTDBQRYもサポートしています。
以下のような感じでインストールしてください。(ただし絶賛開発中なので、タイミングによってはビルドに失敗したりバグっていたりするかもしれません。)

 $ git clone git://github.com/tom-lpsd/tokyocabinet-haskell.git
 $ cd tokyocabinet-haskell
 $ runhaskell Setup.hs configure --extra-lib-dirs=/path/to/tc/lib --extra-include-dirs=/path/to/tc/include --user
 $ runhaskell Setup.hs build
 $ runhaskell Setup.hs install

“検索結果に対するアトミックな更新”もサポートしています。少し長いですが以下のような感じで使います。

import Database.TokyoCabinet.TDB
import Database.TokyoCabinet.TDB.Query hiding (new)
import qualified Database.TokyoCabinet.Map as M
import qualified Database.TokyoCabinet.TDB.Query as Q (new)

data Profile = Profile { name :: String
                       , age  :: Int } deriving Show

insertProfile :: TDB -> Profile -> IO Bool
insertProfile tdb profile =
    do m <- M.new
       M.put m "name" (name profile)
       M.put m "age" (show . age $ profile)
       Just pk <- genuid tdb
       put tdb (show pk) m

main :: IO ()
main = do t <- new
          open t "foo.tct" [OWRITER, OCREAT]

          mapM_ (insertProfile t) [ Profile "tom" 23
                                  , Profile "bob" 24
                                  , Profile "alice" 20 ]

          q <- Q.new t
          addcond q "age" QCNUMGE "23"
          setorder q "name" QOSTRASC
          proc q $ \pk cols -> do
            Just name <- M.get cols "name"
            putStrLn name
            M.put cols "name" (name ++ "!")
            return (QPPUT cols)

          close t
          return ()

`proc'を呼んでいる部分で、Haskellの無名関数を使って更新処理の内容を渡しています。
エラー処理などをさぼっているので、完全なサンプルではありませんが、だいたいの利用イメージを持ってもらえるのではないでしょうか。

Haskellらしくない?

ここまでのサンプルを見ると、どれもIOモナドバリバリで、Haskellの純粋関数型言語としての長所が生かされている感じがしません。ライブラリを作り始めた当初、どうせHaskellでやるのだからHaskellらしい抽象的なインターフェースを提供しようとも考えました。ただ、そういう作りにしてしまうと、特殊なシチュエーションでかゆいところに手が届かないみたいなことになってしまったり、アプリケーションによっては、まったく違うインターフェースの方がマッチしたり、といったことが起こり得ると考えて、まずはナイーブにtokyocabinet.idlに準拠したインターフェースにしました。

Haskellを使っているわりにはなにかと面倒、と感じる部分もでてくると思いますが、tokyocabinet.idlに沿うことによって、TCのメインの機能はHaskellをほとんど知らなくても直感的に使えるようになっていると思います。(なってなかったらごめんなさい。)また、これらを土台にして、より抽象的な関数を作ることはいくらでもできると思います。
実用的かどうかはわかりませんが、ReaderモナドやErrorモナドと組み合わせたサンプルもリポジトリにコミットしています。

まとめ

TCのHaskellバインディングを簡単に紹介させていただきました。PerlやRubyから使えるのだからそれで十分だろうという声もあるかと思いますが、私はHaskellが好きでかつTCを使いたかったのでバインディングを書きました。
Haskellというと、まだまだ実用にはならない言語というイメージを持たれがちで、社内でもHaskellというと、"ネタでしょ"みたいな扱いを受けたりもします。
しかし、最近ではReal World Haskellという本が出版されるなど、実用的な言語としてのHaskellも注目を集めています。日本語のものでもshelarcyさんの連載など有益な情報源が増えてきています。
今回作ったTCのバインディングが、実用的なアプリを作る土台になっていけばいいなと思っています。

はじめまして。07年入社エンジニアのあまやんです。
今日はmixi Engineer’s Blog初(?)、弊社エンジニアの社外での活動レポートをお届けしてみたいと思います。

会場入口

去る3月29日、東京・お台場の「東京カルチャーカルチャー」にて、ウェブ業界の若手社員たちによる交流イベント、その名も「Web2.0 中の人ナイト」が開催され、弊社からは「オンラインコーヒーメーカー 萌香」でお馴染みのきょろと私あまやんが出演しました。

イベントには「cookpad」「livedoor」「楽天」「@nifty」「GREE」「Yahoo!」といった大手サイトの「中の人」が勢ぞろい。
普段なかなか表に出てくることの少ない作り手の顔を知ってもらおう!ということで、お互いの仕事場環境や、各自が取り組んでいる本業以外のものづくり(弊社ではOne Day Free(ODF)制度)の内容についてショートプレゼンを行いました。

会場の様子。客席はレストランも兼ねていて、食事やお酒を楽しみながらイベントを楽しめる素敵な場所でした。
会場内部の風景

弊社きょろのプレゼン。
きょろ、プレゼン中。

話題はやっぱりコーヒーメーカー。
コーヒーメーカーのシステムを説明するきょろ

オンラインコーヒーメーカー「萌香」、実はテレビCM(風の動画)まで作ってしまったのです。このイベントにて初のお披露目となりました。
キャラクターボイスを担当されているのは、声優の永井真衣さんです。

オンラインコーヒーメーカー「萌香」CM


ニコニコ動画のアカウントをお持ちの方はこちらからどうぞ(H.264/高画質)

併せて会場では「萌香」の実機と、きょろが学生時代に開発した割り箸製(!)の「どこでもペンタブレット」を展示。興味津々な来場者の皆さんと会話する彼は本当に幸せそうでした。
「萌香」の実機展示

「萌香」と「どこでもペンタブレット」を説明するきょろ

他社の皆さんのプレゼンは、さらに多彩で新鮮なものばかり!

livedoorの佐孝さん。「作っちゃいましたメソッド」といって、エンジニアが仕事以外に趣味で作った試作品が、実サービスへ採用されることが多いのだそうです。
livedoor 佐孝さん

Yahoo!の吉田さん。Hack Dayという、3日間の社内Hackathonにて、iPhoneカメラを用いたOCR翻訳ソフト「翻訳ルーペ」を開発されたそうです。
Yahoo! 吉田さん

@niftyの森藤さん。社内で繰り返しなされることの多い事項のチェックリストを共有できるサービスを開発。いまや「イタリア旅行」や「燻製の作り方」といったプライベートな項目にまでどんどん情報がアップされているそうです。
@nifty 森藤さん

ユーモアに富みながらも、細かいところまでコミュニケーションデザインがなされたアプリケーションたち。
遊ぶときも本気って、こういうことを言うのでしょうか・・・!
このバイタリティと想像力が、日々私たちの暮らしに楽しみを生むサービスを作り出す原動力になっているんだな、と強く感じることしきりでした。

ショートプレゼンのあとは、各社メンバー集合によるパネルディスカッションでした。
全員集合でのパネルトーク

「うれしかったユーザーさんは?」「サービスの予想外の使われ方」など、ウェブでご飯を食べている人ならではのナマの声が沢山。私自身、壇上に立ちながらも、他の出演者のみなさんの洞察豊かな発言にビリビリしっぱなしでした。

「何百万人と見るレシピを、あなたの母親が作ってWebに公開する時代。情報は誰にでも発信することが出来るということがWeb2.0なのではないか」
「Webに2.0も3.0もなくて、Webの進化によってみんなの生活が豊かになっていくということが大事なんだと思う」

すべては、リアルなこの世界を楽しく過ごしていくために。

ネット上に「場」を作り出していく「中の人」たちの情熱にひたすら元気をもらい、ウェブでご飯を食べていくということはどういうことなのだろう、ということを深く考えさせられた1日でした。
バーチャル世界であるウェブをきっかけに、こうしてリアルなイベントという形でアウトプットをするということ自体新鮮で、とても刺激になりました。今後も積極的にこのような機会を設けていければと思います。
ご来場いただきました皆様、本当に有難うございました!

 はじめまして!08年度新卒エンジニアの「きょろ」こと井上恭輔と申します。ミクシィではコミュニケーション開発チームというところで、mixi上の色々なコミュニケーションサービスの開発を担当しています。
 就職で東京に出てきて早10ヶ月、最初は周囲の歩く速度に付いて行けなくて悩んでいましたが、今では新宿駅を迷わず歩けるまでに成長しました。本日は慣れたついでに、そろろそエンジニアブログにも仲間入りしたいなと思いましたので、記事の初投稿に挑戦してみようと思います。
 曰く「ハードボイルドな技術ネタ」の多い当ブログですが、今回は頭を使わずに読める、文字通り「コーヒーブレイク」的な記事をお届けできればと思います。駄文ではありますが、お付き合い頂ければ幸いです。

エンジニアのガソリン「コーヒー」

 みなさんコーヒーはお好きですか?私はコーヒーが大好きで、1日にかなりの量のカフェインを摂取します。朝はブラックコーヒーを飲まないと始まりませんし、コーヒーが無ければコーディングの質も量も低下するような気がします。学生時代からの感覚値ではありますが、どうも研究者やエンジニアという生物にはコーヒー好きが多いようで、「コーヒーが無いと生きていけない!」と思っている人もきっと少なくは無いはず。ある意味「プログラマとはコーヒーに含まれるカフェインをコードに変換する職業」だと言っても過言ではありません。コーヒーは言わばエンジニアを動かすガソリンのようなものであり、私たちの「生命の源」だと言えるでしょう。

エンジニアの朝は一杯のコーヒーからはじまる

図1 エンジニアの朝は一杯のコーヒーからはじまる

マイ・コーヒーメーカーから始まった物語

 配属当時、残念ながらミクシィ開発部には美味しいブラックコーヒーを飲める環境がありませんでした。ティーサーバで紅茶・緑茶・玄米茶・烏龍茶、コーヒーサーバでラテ・カプチーノ・エスプレッソなどを自由に飲むことは出来ましたが、私が求めるのは“穢れ(けがれ)”を知らない純粋で無垢な無糖のブラックコーヒーであり、ミルクやシュガーは不純物以外の何者でもありません。 「美味しいブラックコーヒーを毎日浴びるように飲みたい!」 この想いは日々強くなっていき、ある時、カッとなった私は自腹でコーヒーメーカーを購入し、自席の横に設置することにしました。

図2 導入されたコーヒーメーカー

図2 導入されたコーヒーメーカー

 毎朝漂うコーヒーを炒れる豊潤な香り。 出社後にメールチェックをしながら飲む至福の一杯。  私の導入したコーヒーメーカーは意外にもチームメンバーや周りのエンジニアの方々に暖かく迎えられ、次第にコーヒーメーカーを利用してくれる方も増えてきました。しかし、全てが幸せに思われた一方で、何日か運用する過程でいくつかの問題点も出てきました。

  • 仕事に集中してるとコーヒーが入ったことに気づかない
  • やはりコーヒーは炒れたてが美味いので抽出直後に飲みたい
  • 遠くの人にコーヒーが入ったことを連絡するのが面倒
  • 一日にどのくらいの回数炒れているのか、今ストックしてあるコーヒーはいつ炒れたものなのかわからない

 弊社のエンジニアは私も含め、モニタに向かいヘッドホンで音楽を聴きながら仕事をしていることが多いので、コーヒーメーカーが近くにあっても、なかなか抽出完了に気が付きません。また、コーヒーが出来たことを離れた席の人に毎回伝えるのも面倒ですし、運用上は抽出記録が残らないのも何かと不便です。そこで私は、金曜日が自由研究時間になるODF(One Day Free)制度を利用して、コーヒーのドリップ状況をネットワークを介して通知してくれる機能を持った「オンラインコーヒーメーカー」を開発しようと考えました。

オンラインコーヒーメーカー「萌香」

 オンラインコーヒーメーカー「萌香(もか)」は、コーヒーのドリップ開始と完了時に、社内のIRC及びtwitterでコーヒーの抽出状況を教えてくれる機能を持った次世代コーヒーメーカーです。ドリップ完了時には抽出時間などに応じて一言メッセージも付け加えるようにしました。 利用者は既存のIRCクライアントやtwitterクライアントを使用することで、手軽にドリップ状況を知る事ができます。

図3 「萌香」によるIRC及びtwitter通知動作画面

図3 「萌香」によるIRC及びtwitter通知動作画面

 萌香の発言内容はtwitterでリアルタイムにご覧頂く事ができます。地球の裏側からミクシィ開発部のコーヒーメーカー動作状況を確認する場合などにご利用ください。


【Twitter/mixi_mocha】 http://twitter.com/mixi_mocha

 既製品のコーヒーメーカーを改造し、センサーと自作の制御回路を組み合わせることでコーヒーのドリップ状況を検出し、情報を私のPCに伝えます。私のPCでは萌香の制御ソフトがバックグラウンドで動作しており、検出状況に応じてIRCやtwitterにメッセージを投稿する仕組みです。

図4 「萌香」のシステム構成図

図4 「萌香」のシステム構成図

 コーヒーメーカーは安全性の観点から分解が難しい作りになっている場合が多く、改造は思ったよりも大変な作業でした。ドリップ状況の検知は、衛生上の観点からもタンクの残り水量を外付けセンサーで取得することはナンセンスです。また、抽出時は内部の部品が非常に高温になるため、物理的なセンサーの接触は極力避けなければいけないという制約事項もありました。 そこで、コーヒーメーカーのドリップ終了時の「自動電源OFF機能」に着目しました。パイロットランプの点状状況を光センサ(CdS光導電セル)で検出し、マイコン(今回はAVR-ATmega88を使用)を用いてA/D変換を行っあと、その値をUSBを経由してPCに送り、検出状況を制御用プログラムで判別してIRCやtwitterへの各種投稿処理を行います。パイロットランプが消灯→点灯で「ドリップ開始」、点灯→消灯で「ドリップ終了」と言った具合です。抽出量などは点灯時間を計測することで把握できます。

図5 「萌香」の制御回路はブレットボード上に実装

図5 「萌香」の制御回路はブレットボード上に実装

 萌香の導入後、チーム内のコーヒーコミュニケーションが劇的に効率化しました。離れた席でも炒れたてのコーヒーを常に知る事ができ、私もコーヒーを入れるたびにお知らせをする面倒から開放されました。光センサーゆえ、お昼時の直射日光が差し込むと、たまに暴走して発言が止まらなくなることもありますが、そこは「ドジっ子」という設定でフォローできちゃうのも擬人化ゆえの素敵なところです。萌香の設定に関して下記にまとめまておきますので、興味のある方はご覧ください。

図6 萌香たん

図6 萌香たん

名前 美釧 萌香
読み みくし もか / Mikushi Mocha
由来 「ミクシィ」とコーヒーの銘柄「モカ」から
性別 女性
血液型 AB型(Rh +)
年齢 16歳(高校生)
身長 152cm
好きなもの もちろん、美味しいコーヒー
将来の夢 Webエンジニアとしてインターネットの未来を作ること

 萌香のイラストは友人のつてを借りてイラストレータの「さもに凰花」さんにお願いさせて頂きました。あまりのかわいさに、ついカッとなって壁紙も作ってしまいましたので、ご興味のある物好きな方はご利用ください(笑)

萌香たん壁紙サムネイル

萌香たん壁紙1280×1024 (439KB)
萌香たん壁紙1024×768(289KB)

従来までのコーヒーポット状況通知システム

 実は、今日までのコンピュータ発展の歴史の中において「コーヒーメーカーの状況通知」というテーマはいつの時代にも考えられてきた事であり、様々な手法が提案されてきました。しかし、現代的な実装という点で考えた場合、どの手法もニーズを満たすものではありませんでした。

ケンブリッジコーヒーポット方式の問題点

 「コーヒーポットをネットワーク越しに監視する」というアイデアの最初期、かつ最も有名な実装として「ケンブリッジコーヒーポット」というものがあります。これは、1993年にイギリスのケンブリッジ大学のコンピュータ研究室に所属する学生たちによって作られたものです。「コーヒーを飲むためにポットのところに行ったら、まだコーヒーがたまっていなかった!」という非常に残念な問題を解決するために、コーヒーポットの前にビデオカメラを設置し、その画像をリアルタイムにウェブにアップロードすることで、自席に居ながらにしてコーヒーポットの残量を確認することができるという画期的なシステムです。今では「それ、ustreamでできるよ。」と軽く流されてしまいそうなものですが、当時はWindows95すらも発売されていない時代。日本の家庭にはまだインターネットがなく、当時の最新機PC-9821とパソコン通信が花形の時代です。地球の裏側のコーヒーポットの状況をリアルタイムに把握できるというのはまさに革命的な出来事で、新しい時代の到来を予感させるものでした。ケンブリッジコーヒーポットは設置からその後8年間稼動を続け、2001年の大学移転に伴ってスイッチが切られました。このコーヒーポットはeBayのオークションにおいて83万円の値が付き落札されたそうです。
 さて、このケンブリッジコーヒーポット、Webカメラを使った一見シンプルかつスマートで、エレガントな解決策のように思われますが、1つの大きな構造上の問題を抱えています。それは「コーヒー残量が目視できるガラス製のコーヒーポットでしか使用することが出来ない」ということです。ガラス製コーヒーポットは安価に入手可能ですが、その構造上、保温性が低く、残量がある限り常に底部のヒーターでコーヒーを加熱し続けなければいけません。コーヒーの保温には多くの電力を消費するため、エコが叫ばれる昨今の社会的情勢にマッチした解決策とは言いがたいものがあります。また、常に加熱を続けることでコーヒーが煮立ち、本来の味を損なってしまうのもコーヒー好きには許しがたいことで、現在ではポットに魔法瓶を採用した保温性の高いコーヒーメーカーが市販されています。オフィスにおいて非同期的に消費されるコーヒーには、魔法瓶式コーヒーメーカーの方が適しているため、ケンブリッジコーヒーポット方式は現実的なソリューションではありません。

図7 ケンブリッジコーヒーポットの確認ページ

図7 ケンブリッジコーヒーポットの確認ページ

HTCPCPの問題点

 HTCPCP(ハイパーテキストコーヒーポット制御プロトコル)はRFC2324で定められた世界標準のコーヒーポット制御用プロトコルです。 いわゆるジョークRFCと呼ばれるものの一種ですが、仕様自体は実装可能なものであり、HTCPCPに準拠したコーヒーメーカーの制作例なども存在します。しかし、実際の現場においてHTCPCPはあくまで「ジョーク」の領域を出るものではなく、次に上げるような問題点があり使い物になりません。

  • HTTPの拡張であるため、プロトコルシーケンスはクライアント駆動であり、コーヒーメーカー側から非同期にメッセージを送ることができない
  • たとえば、コーヒーメーカーから「コーヒーが入ったよ!」という通知を送るはできない
  • コーヒー炊き立て通知を実装するにはCOMETなどによるロングポーリングの手法を用いる必要があるが、コーヒーポットへの組み込みサーバは一般的に貧弱なため現実的な解決策ではない
  • IE、Firefox、Safari等、主要なブラウザはcoffee://URIスキームに対応していない。デファクトなクライアント実装も無い。開発しても利用者にインストールしてもらうのは面倒
  • というか、コーヒー粉をセットするときに席を立つんだから、その時にスイッチを操作したほうが便利だろ常識的に考えて
  • そもそも、RFCの内容がふざけており、適当すぎる。(ジョークRFCなので仕方ない)
  • ミルクやシロップを設定する拡張フィールドがあるが、俺はブラック以外をコーヒーとは認めない

 上記のような問題を解決した「萌香」は、Web時代におけるモダンなコーヒーメーカー状況通知システムの実装なのではないかなと勝手に考えております。

まとめ

 Web時代における現代的なコーヒーメーカー状況通知システムとして、オンラインコーヒーメーカー「萌香」を開発し、その開発背景と歴史、実現機能、実装方法などを紹介させて頂きました。また、「ミクシィのODF(OneDayFree)制度ってどのくらいFreeなんですか?」とよく聞かれることがあるのですが、「会社で朝からハンダこてを握って電子回路を組んでコーヒーメーカーを改造できるくらい自由です!」という事が少しでもお伝えできたなら幸いに思います。 Web企業でのハードウェア制作というのは、一見して異質な畑違いの行為のような感じもしますが、コミュニケーションを創造する仕事に従事するからには、ヒューマンインタフェースに関する研究やデバイスを通してのコミュニケーションのあり方についても積極的に考えて行きたいと個人的には思っています。コミュニケーションはブラウザの上で完結するものではないのですから。

図8 金曜日の私のデスクはWeb企業っぽくない

図8 金曜日の私のデスクはWeb企業に見えない

 この他にも、色々とハードウェアを絡めたデモプロダクトなんかを作っていたりします。機会があれば、今後もご紹介して行けたらいいなと思っていますので、生暖かい目で見守って頂ければ幸いです。  ハードウェアに興味を持たれる方がどれほどいるか不安で仕方ないのですが、もしこんな記事でもブクマなどが付くようでしたら、次回は「萌香」の実装に関して回路の制作方法、マイコン制御用プログラムの開発方法やソースコード、壁紙第2弾なんかを晒してみようかなと思っています。 それでは、最後までお読み頂き誠にありがとうございました!

はじめまして。mixi開発部・運用グループでアプリケーションの運用を担当しているmikiokatoといいます。週に一日興味があることについて研究や開発ができるOneDayFree の制度を使って開発し、12月25日にリリースしたインディーズ機能「おすすめ マイミクシィ/コミュニティ」について書いてみたいと思います。

おすすめ マイミクシィ/コミュニティとは

マイミクシィやコミュニティのリンクを分析して、マイミクシィになる可能性の高い人や興味がありそうなコミュニティをおすすめします。膨大な情報の中から検索などでユーザーにいろいろと探してもらうよりも、データを分析して興味がありそうなものをシステムからおすすめする試みです。

実際の画面はこちらです

人によって精度は差があるので、結果がいい場合もよくない場合もありますが、マイミクシィやコミュニティの発見につながればと思います。では、どういった仕組みでおすすめしているかを説明していきます。

おすすめ マイミクシィ/コミュニティの仕組み

おすすめマイミクシィ

親しい人から招待を受けてミクシィに参加し、よく知っている人からマイミクシィになっていく場合が多いため、一般にマイミクシィの数が少ないほど、親しい関係だと考えられます。
マイミクシィの数によってポイントを加算して集計することで、おすすめマイミクシィの候補を決定しています。

つまり、下の図のように、マイミクシィBさんのマイミクシィの数が10人だったとすると、マイミクシィのマイミクシィDさん、Eさんのポイントにそれぞれ1/10が加算されます。基本的には、それをマイミクシィの数だけ集計してランキングをつけているというわけです。例では、Dさんよりポイントの高いEさんの方が親しいだろうと予測されます。

recommend

おすすめコミュニティ

おすすめマイミクシィと同様に、親しいユーザーを分析し、そのマイミクシィが参加しているコミュニティをおすすめします。
また、マイミクシィがよく参加しているコミュニティや、参加者の多いコミュニティもあわせておすすめしています。

こちらはおすすめマイミクシィの計算方法に加えて、マイミクシィがよく参加しているコミュニティという要素も取り入れていて、適度な割合になるように両方の要素のポイントを合計しています。

このように、分析に使っているデータはマイミクシィのリンクとコミュニティに参加しているかどうかのリンク情報だけで、プロフィールなどの文章的な情報は全く使っていませんが、文章的な解析をしなくてもある程度の精度を出すことができています。こういったリンク情報の解析の研究は、リンクマイニングと呼ばれる研究分野となっています。

システム的な仕組み

解析の考え方は上記のとおりですが、こういった単純なアルゴリズムでも、マイミクシィの多いユーザーの場合は、処理時間がかかったり、システムに負荷がかかってしまいます。ですので、バッチ処理で定期的に結果のみデータベースに格納するようにしています。

mixi はユーザ数が1000万人以上いるので、単純に直列的なバッチ処理を考えると、1人あたりの処理に0.5秒かかったとしても・・・

1000万人×0.5秒=500万秒=約58日

と、これくらいの日数がかかる計算になります。

実際には、おすすめマイミクシィ/コミュニティの場合はID別に並列処理が可能なので、複数のプロセスで処理したり、同じ内容のデータベースを複数用意したりして、72時間程度で初回の解析を完了することができました。その後はアクセスの有無やマイミクシィの数の変動等を基準にして再度解析することでデータを更新しています。

まとめ

新しくマイミクシィになったり、コミュニティに参加したという声も聞かれる一方、こういったような問題もあります。

  • マイミクシィじゃなくなったユーザーや退会したコミュニティが表示される
  • 興味がないマイミクシィやコミュニティが表示される
  • アクセスブロックしているユーザーが表示される
  • 今後は機能追加やアルゴリズムの改善などでこういった問題を対処していきたいと思います。