一昨日、橋本大也氏の情報考学の記事「10月1日開催 Evernoteデベロッパーズミーティング@デジタルハリウッド大学大学院 秋葉原メインキャンパス」で、Evernoteの日本初のデベロッパーズミーティングが開催されることを知った。 会場が秋葉原で会社帰りに寄れるし、Evernote を利用している中で API についてもちょっと興味を持ち始めていたので、いい機会だと参加申し込み。 Evernote 遍歴を整理してみたり。
で、本日退勤後参加してきた。まだ若い企業であること・日本法人「エバーノート株式会社」も今年設立されたばかりであることなどもあってか、即席的だけれどフレンドリーな雰囲気のある、皆でこれから盛り上げていきましょう的な良い雰囲気の会であった。 Evernote 好き度ちょっとアップ。
以下ノート。
開会のメッセージ。
「Integrating with Evernote」
英語による発表。中島健氏が適宜通訳。
Evernoteサイトメモリー自体は思うところがあってまだ導入してみていなかったんだけれど、話を聞くことでサイトオーナーにもメリットがあることは感じられた。
OAuth も対応しているんだ。 また API を使えば Linux 版クライアントを作れる人は作れるんだな。
途中で Twitter ハッシュタグ指定が。 この時点で #EvernoteJP よりも多く Tweet れている #Evernote を推奨とのこと。
ENML については以前ドキュメントを読んだことがあるので流して聞く。
Android はやはり intent が強力だね。 今後新しい intent 対応があるとのこと。楽しみ。 個人的にははやくオフライン閲覧ができるようになってくれると嬉しい(すこし前のアップデートで準備段階としてキャッシュ機能が入ったのでもうすぐらしいんだけれど)。
デベロッパーズミーティングということで、ぜひ開発者の声をということで今朝プレゼンテーションを頼まれたとのこと。
初代 MacBook Air 用ディプレイ接続のアダプタを忘れたが、会場参加者にもっている人が貸してくれて無事プレゼンテーション。やはり Mac 率高い。
開発している iPhone RSS リーダに求められた「ニュース保存」に対応するために
と対応していった。Evernote の API 対応は1〜2日程度+テスト。工数少なく機能実装できたとのこと。メール送信によるノート新規追加を連携としているものが多いが、API 利用することでノート表示などもサポートできるという利点があるなど。
「Evernoteなう」
後ろの人が今日からオンサイト作業。 iPhone を持っているので何かあった時は電話か Google Apps の Gmail でやりとりはできるのだが、仕事中、場合によっては数時間メールチェックをしないことがある(自分)ので、通知システムを入れてみることにした。 あとオフィス待機側として、オンサイト側の着現・撤収を知りたいのでついでに Twitter の通知もセットで。
入れてみたのは、 YAPC::Asia Tokyo 2010 でもオフにしないままプレゼンテーションしていた人多数の Growl の Windows 版「Growl for Windows」。
Gmail Growl を入れてみた。 設定直後は接続できていたんだけれど、そのうち接続できなくなってしまった。
Windows BOX に Gmail のパスワードを入力しっぱなしもちょっと気持ち悪いのでやっぱりアンインストール。
Trowl を入れてみた。
認証は OAuth (PIN 式)。 タイムライン上の tweet の通知について、どのユーザのものを通知するかを選べるのはナイス。ただし設定画面を開くたびに follow 一覧を取ってくるので多いとしんどそう。 リストを指定して tweet 通知させることもできるので、管理的には専用のリストを作るのが便利そうだ。
使い勝手はまずまずかな。
Twitter メインアカウントの認証を設定しっぱなしにしておくのは嫌なので、専用に別 Twitter アカウントを作って設定。Growl 側では New Tweet を Sticky = Always にして見落さないようにしてみた。
Twitter API v1.1 に対応していないスクリプトがあって、たしか OAuth 対応はしてあるけど RSS 形式を使っていたので JSON で取得して処理するようにしなければなーと思ってたんだけれど、そもそも OAuth 対応すらしてなかった。
なので Net::Twitter::Lite を使うように書き換え。
あと、いままで1つのスクリプトで「Twitter API を呼び出してタイムライン取得」「シリアライズしてファイルに保存」「Wiki 形式に整形して書き出し」をしていたんだけれど、UNIX 哲学に従って小スクリプトに分割してパイプで受け渡すように変更するなど。
スクリプト間のやりとりは構造化テキストデータなので JSON にしたんだけれど、若干これでいいのかなぁ感はある。テキスト形式だし最近の主流フォーマットではあるんだけれど、それでもシェルから見ると複雑な形式な気がするんだよね。でもあと軽量な構造化テキストフォーマットだと YAML ぐらいかなぁ。
Plack::App::Directory::Markdown をベースにちょっと手を入れた Markdown ビューアを使っている(記事)んだけれど、閲覧要認証なシチュエーションが出てきた。
自分のみ閲覧のものは builder で Plack::Middleware::Auth::Digest を enable にして Digest 認証をかけ、htdigest コマンドでパスワード管理とかで済ませているのだけれど、複数人に閲覧してもらうのにこれは嫌だ。人のパスワード管理はしたくない。
OAuth で Google アカウントとかの認証を使うというのもあるけれどキーとか面倒くさいので、せっかくだし mixi OpenID を使うことにした。Perl モジュールは Net::OpenID::Consumer::Lite を使用。
とりあえずやっつけで以下のような感じ。いきなり mixi OpenID 認証させるしエラー・キャンセル処理もほとんどないし、call の中にネジこんだりしてあるので、まだまだダメダメだけれどとりあえず認証はできた。後で整理する。
$app = builder { enable 'Session', store => 'File'; $app; };
my $session = $env->{'psgix.session'}; my $request = Plack::Request->new($env); unless ($session->{openid}) { unless ($request->parameters->{'openid.mode'}) { my $check_url = Net::OpenID::Consumer::Lite->check_url( 'https://mixi.jp/openid_server.pl', $request->uri); return [302, ['Location' => $check_url], []]; } return Net::OpenID::Consumer::Lite->handle_server_response( $request->parameters => ( not_openid => sub { return [503, [], []]; }, setup_required => sub { my $setup_url = shift; return [302, ['Location' => $setup_url], []]; }, cancelled => sub { return [403, [], []]; }, verified => sub { my $vident = shift; my $identity = $vident->{identity}; # %member に閲覧 OK の OpenID を入れてある。 if (exists $member{$identity}) { $session->{openid} = $identity; return [302, ['Location' => $vident->{return_to}], []]; } else { return [403, [], []]; } }, error => sub { my $err = shift; return [503, [], []]; }, ) ); } # 以下は認証済みの場合の処理を書く。
[ Naney と mixi ]
社内で動かしている Markdown ビューアについては去年 mixi Open ID 認証にしました(記事)。ですが mixi OpenID については 2016年1月25日提供終了となっていますので今回認証を変更しました。
今回は Google アカウントで認証できるように OpenID Connect を使ってみることに。基本的には OAuth 2.0 とほぼ同じです。
認証ページ(https://accounts.google.com/o/oauth2/auth)にリダイレクトさせる時に scope パラメータに 'openid email' を指定しておきます。
そしてコールバックを受けて https://accounts.google.com/o/oauth2/token でアクセストークンを取得した際に、レスポンスに一緒に含まれる id_token をパースして email 取り出します。今回はそのメールアドレスが指定ドメインだったらアクセスを許可するという処理にしました。
JSON Web Token (JWT) である id_token のパースには OIDC::Lite::Model::IDToken モジュールを使用。
$email = OIDC::Lite::Model::IDToken->load($id_token) ->payload->{email};
で email が取得できます。
一昨日からSlack 分報をやりはじめました。Android スマートフォンからさくっとつぶやくには Slack アプリはちょっと不便(立ち上がってからチャネル選択する必要がある)なので Slack Web API でさくっと投稿できるようにしておきます。
投稿は Slack の incoming webhook でもできるのですが、これで送ると BOT とついてしまうので Slack Web API を使うことにします。認証・承認は OAuth 2 が推奨ですが、まずはシンプルに API トークンを使う方法にしておきます。
の [Create token] でトークンを発行します。
発行できたらあとは
https://slack.com/api/chat.postMessage?token=<トークン>&channel=%23times_naney&as_user=true&parse=full&text=Hello.
のように chat.postMessage を呼び出せば投稿できます。
あとはサポテキ (SupportText Pro) のユーザー定義ボタンで
[TITLE] #times_naney [TEXT] https://slack.com/api/chat.postMessage?token=<トークン>&channel=%23times_naney&as_user=true&parse=full&text=%s [TYPE] URI [CCODE] UTF-8 [END]
としておけばボタン一発投稿できるようになります。
実行すると Web ブラウザが開いて API レスポンスが表示されるだけのシンプルな設定なので、あとはよしなに工夫していけば良い感じです。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。