Created
December 21, 2010 09:52
-
-
Save nanto/749732 to your computer and use it in GitHub Desktop.
はてなブックマークの OAuth 対応 API 利用サンプル。 Run | $ perl consumer.pl daemon | and access http://localhost:3000/.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use utf8; | |
use Mojolicious::Lite; | |
use OAuth::Lite::Consumer; | |
use XML::Atom::Feed; | |
use XML::Atom::Entry; | |
use URI::Escape qw/uri_escape_utf8/; | |
use Encode qw/decode_utf8/; | |
my $origin = 'http://localhost:3000'; | |
my $consumer_key = '__consumer_key__'; | |
my $consumer_secret = '__consumer_secret__'; | |
my $consumer = OAuth::Lite::Consumer->new( | |
consumer_key => $consumer_key, | |
consumer_secret => $consumer_secret, | |
site => 'https://www.hatena.com', | |
request_token_path => '/oauth/initiate', | |
access_token_path => '/oauth/token', | |
authorize_path => 'https://www.hatena.ne.jp/oauth/authorize', | |
); | |
get '/' => sub { | |
my $self = shift; | |
my $access_token = $self->session('access_token') || ''; | |
$self->stash( access_token => $access_token ); | |
} => 'root'; | |
# リクエストトークン取得から認証用URLにリダイレクトするためのアクション | |
get '/oauth' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
# リクエストトークンの取得 | |
my $request_token = $consumer->get_request_token( | |
callback_url => $origin . '/callback', | |
scope => 'read_public,write_public', | |
) or die $consumer->errstr; | |
# セッションへリクエストトークンを保存しておく | |
$self->session( request_token => $request_token ); | |
# 認証用URLにリダイレクトする | |
$self->redirect_to( $consumer->url_to_authorize( | |
token => $request_token, | |
) ); | |
}; | |
# 認証からコールバックされ、アクセストークンを取得するためのアクション | |
get '/callback' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $verifier = $self->param('oauth_verifier'); | |
my $request_token = $self->session('request_token'); | |
# リクエストトークンとverifierなどを用いてアクセストークンを取得 | |
my $access_token = $consumer->get_access_token( | |
token => $request_token, | |
verifier => $verifier, | |
) or die $consumer->errstr; | |
$self->session( request_token => undef ); | |
# アクセストークンをセッションに記録しておく | |
$self->session( access_token => $access_token ); | |
$self->redirect_to('/'); | |
} => 'callback'; | |
get '/add' => sub { | |
my $self = shift; | |
} => 'add'; | |
post '/add' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $access_token = $self->session('access_token') or return; | |
$consumer->access_token( $access_token ); | |
my $url = $self->param('url') or return; | |
my $comment = $self->param('comment'); | |
# PostURI 用の Atom エントリを作成 | |
my $link = XML::Atom::Link->new; | |
$link->rel('related'); | |
$link->type('text/html'); | |
$link->href( $url ); | |
my $entry = XML::Atom::Entry->new; | |
$entry->add_link( $link ); | |
$entry->summary( $comment ); | |
# PostURI でブックマークを追加 | |
my $res = $consumer->request( | |
method => 'POST', | |
url => 'http://b.hatena.ne.jp/atom/post', | |
headers => [ 'Content-Type' => 'application/atom+xml' ], | |
content => $entry->as_xml_utf8, | |
); | |
return unless $res->is_success; | |
$self->redirect_to( '/edit?url=' . uri_escape_utf8( $url ) ); | |
}; | |
get '/edit' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $access_token = $self->session('access_token') or return; | |
$consumer->access_token( $access_token ); | |
my $url = $self->param('url') or return; | |
# EditURI でブックマークを取得 | |
my $res = $consumer->request( | |
method => 'GET', | |
url => 'http://b.hatena.ne.jp/atom/edit', | |
params => { url => $url }, | |
); | |
return unless $res->is_success; | |
my $entry = XML::Atom::Entry->new( \$res->decoded_content ); | |
$self->stash( url => $url ); | |
$self->stash( entry => $entry ); | |
$self->stash( comment => decode_utf8( $entry->summary ) ); | |
} => 'edit'; | |
post '/edit' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $access_token = $self->session('access_token') or return; | |
$consumer->access_token( $access_token ); | |
my $url = $self->param('url') or return; | |
my $comment = $self->param('comment'); | |
# EditURI 用の Atom エントリを作成 | |
my $entry = XML::Atom::Entry->new; | |
$entry->summary( $comment ); | |
# EditURI でブックマークを編集 | |
my $res = $consumer->request( | |
method => 'PUT', | |
url => 'http://b.hatena.ne.jp/atom/edit', | |
params => { url => $url }, | |
headers => [ 'Content-Type' => 'application/atom+xml' ], | |
content => $entry->as_xml_utf8, | |
); | |
return unless $res->is_success; | |
$self->redirect_to( '/edit?url=' . uri_escape_utf8( $url ) ); | |
}; | |
post '/delete' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $access_token = $self->session('access_token') or return; | |
$consumer->access_token( $access_token ); | |
my $url = $self->param('url') or return; | |
# EditURI でブックマークを削除 | |
my $res = $consumer->request( | |
method => 'DELETE', | |
url => 'http://b.hatena.ne.jp/atom/edit', | |
params => { url => $url }, | |
); | |
return unless $res->is_success; | |
$self->redirect_to('/'); | |
}; | |
get '/list' => sub { | |
my $self = shift; | |
$self->stash( consumer => $consumer ); | |
my $access_token = $self->session('access_token') or return; | |
$consumer->access_token( $access_token ); | |
# FeedURI でブックマークの一覧を取得 | |
my $res = $consumer->request( | |
method => 'GET', | |
url => 'http://b.hatena.ne.jp/atom/feed', | |
); | |
return unless $res->is_success; | |
my $feed = XML::Atom::Feed->new( \$res->decoded_content ); | |
$self->stash( feed => $feed ); | |
} => 'list'; | |
app->start; | |
__DATA__ | |
@@ root.html.ep | |
<!DOCTYPE html><html lang="ja"><meta charset="utf-8"> | |
<title>OAuth対応APIではてなブックマークを利用する</title> | |
<p><a href="/oauth">はてなOAuth認証をする</a> | |
% if ( $access_token ) { | |
<ul> | |
<li><a href="/add">ブックマークを追加</a> | |
<li><a href="/list">ブックマーク一覧を表示</a> | |
</ul> | |
% } | |
@@ callback.html.ep | |
% my $token = $self->stash('token'); | |
<%= $token->token %><br> | |
<%= $token->secret %> | |
@@ add.html.ep | |
<!DOCTYPE html><html lang="ja"><meta charset="utf-8"> | |
<title>ブックマークを追加</title> | |
<form action="/add" method="post"><p> | |
<label>URL: <input type="text" name="url" size="50"></label><br> | |
<label>コメント: <input type="text" name="comment" size="50"></label> | |
<input type="submit" value="追加"> | |
</form> | |
@@ edit.html.ep | |
% my $url = $self->stash('url'); | |
% my $entry = $self->stash('entry'); | |
% my $comment = $self->stash('comment'); | |
<!DOCTYPE html><html lang="ja"><meta charset="utf-8"> | |
<title>ブックマークを編集</title> | |
<form action="/edit" method="post"><p> | |
<input type="hidden" name="url" value="<%= $url %>"> | |
URL: <%= $url %><br> | |
<label>コメント: <input type="text" name="comment" value="<%= $comment %>" size="50"></label> | |
<input type="submit" value="保存"> | |
</form> | |
<form action="/delete" method="post"><p> | |
<input type="hidden" name="url" value="<%= $url %>"> | |
<input type="submit" value="削除"> | |
</form> | |
@@ list.html.ep | |
<!DOCTYPE html><html lang="ja"><meta charset="utf-8"> | |
<title>ブックマーク一覧</title> | |
<ul> | |
% for ( $feed->entries ) { | |
% my $url = $_->link->href; | |
<li><a href="<%= $url %>"><%= $url %></a> <a href="/edit?url=<%= URI::Escape::uri_escape_utf8( $url ) %>">編集</a> | |
% } | |
</ul> | |
@@ exception.html.ep | |
REQUEST ERROR: <%= $consumer->errstr %> </br> | |
WWW-Authenticate: <%= $consumer->oauth_res && $consumer->oauth_res->header('www-authenticate') %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment