はてなブログAtomPub – Hatena Developer Center
Mục Lục
はてなブログAtomPub
■
はてなブログ AtomPub を利用したプログラムの例
Perlを用いた例 (WSSE認証)
CPANモジュールのXML::Atom::ClientはAtomPubクライアントを実装するための、WSSE認証やリクエスト、レスポンスに必要なXML文書の組み立てなどを抽象化したモジュールです。
XML::Atom::Clientを用いて、はてなブログにエントリを投稿するサンプルコードは以下です。
#!/usr/bin/env perl
use strict
;use warnings
;use utf8
;use
XML::Atom::Entry;use
XML::Atom::Client;my
$username
=shift
or
die
'need username'
;my
$blog_domain
=shift
or
die
'need blog_domain'
;my
$api_key
=shift
;my
$PostURI
="https://blog.hatena.ne.jp/
$username
/
$blog_domain
/atom/entry"
;my
$client
= XML::Atom::Client->new
;$client
->username($username
);$client
->password($api_key
);my
$entry
= XML::Atom::Entry->new
;$entry
->title('テストエントリだよー'
);my
$content
="
# マークダウンも書けますよ
- こんな
- ふうに
- ね"
;$entry
->content($content
);my
$EditURI
=$client
->createEntry($PostURI
,$entry
)or
die
$client
->errstr;$EditURI
;
XML::Atom::Client はWSSE認証を抽象化しているため、username/blog_domain/passwordメソッドでそれぞれをセットするだけで認証を通過できます。また、XML文書の組み立てはXML::Atom::Entryインスタンスを生成して行い、それを最後にXML::Atom::Clientインスタンスに渡せば完了です。
このスクリプトはコマンドラインから、
$ perl atompost.pl はてなID ブログドメイン APIキー
として実行できます。
Perl を用いた例 (OAuth認証)
上記の XML::Atom::Client はOAuth認証には対応していません。ここでは、フレームワークとして Mojolicious::Lite、OAuthライブラリとして OAuth::Lite を利用したサンプルコードを紹介します。
以下のスクリプトを oauth-sample.plとして保存して、以下のように実行します。
$CONSUMER_KEY
='
<YOUR CONSUMER KEY>
'
\\
CONSUMER_SECRET
='
<YOUR CONSUMER SECRET>
'
\\
API_URL
='
<YOUR BLOG API ROOT ENDPOINT>
'
\\
perl oauth-sample.pldaemon
<YOUR CONSUMER KEY>, <YOUR CONSUMER SECRET> には、自分のOAuthアプリケーションの consumer key, consumer secretを設定してください。<YOUR BLOG API ROOT ENDPOINT> には、サービス文章のURIを設定してください。特に、はてなブログ AtomPub APIは、はてなのOAuth認証における、read_private, write_privateの両方を要求することに注意してください。詳しくは、認証についての章を参照してください。
スクリプトが起動したのち、http://localhost:3000へアクセスしてください。
#!/usr/bin/env perl
use strict
;use warnings
;use utf8
;use
Mojolicious::Lite;use
OAuth::Lite::Consumer;use
OAuth::Lite::Token;use
XML::Atom::Feed;use
Encode;my
$consumer_key
=$ENV
{CONSUMER_KEY};my
$consumer_secret
=$ENV
{CONSUMER_SECRET};my
$api_url
=$ENV
{BLOG_API_ROOT_ENDPOINT};if
(!($consumer_key
&&$consumer_secret
&&$api_url
)) {STDERR
<<"ENDUSAGE";
Usage:
CONSUMER_KEY=<YOUR CONSUMER KEY>
\\
CONSUMER_SECRET=<YOUR CONSUMER SECRET>
\\
API_URL=<BLOG API ROOT ENDPOINT>
\\
plackup
$0
ENDUSAGE
exit
1
; }my
$consumer
= OAuth::Lite::Consumer->new
(consumer_key
=>$consumer_key
,consumer_secret
=>$consumer_secret
,site
=>q{https://www.hatena.com}
,request_token_path
=>q{/oauth/initiate}
,access_token_path
=>q{/oauth/token}
,authorize_path
=>q{https://www.hatena.ne.jp/oauth/authorize}
, ); get'/'
=>
sub
{
my
$self
=shift
;$self
->stash(access_token
=>$self
->session('access_token'
) ||''
); } =>'root'
; get'/oauth'
=>
sub
{
my
$self
=shift
;$self
->stash(consumer
=>$consumer
);my
$request_token
=$consumer
->get_request_token(callback_url
=>q{http://localhost:3000/callback}
,scope
=>'read_private,write_private'
, )or
die
$consumer
->errstr;$self
->session(request_token
=>$request_token
->as_encoded);$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
= OAuth::Lite::Token->from_encoded($self
->session('request_token'
));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
->as_encoded);$self
->redirect_to('/'
); } =>'callback'
; get'/list'
=>
sub
{
my
$self
=shift
;$self
->stash(consumer
=>$consumer
);my
$access_token
= OAuth::Lite::Token->from_encoded($self
->session('access_token'
))or
return
;my
$res
=$consumer
->request(method
=>'GET'
,url
=>$api_url
.'/entry'
,token
=>$access_token
,params
=> {}, )or
die
$consumer
->errstr;my
$xml
=$res
->content;my
$entries
= [map
{my
($link
) =map
{$_
->href }grep
{$_
->releq
'alternate'
}$_
->link
; +{title
=> ( decode_utf8($_
->title) ||''
),link
=> ($link
||''
) } } XML::Atom::Feed->new
(\$xml
)->entries ];$self
->stash(entries
=>$entries
); } =>'list'
; app->start;
Ruby を用いた例
Ruby gemsで公開されているatomutilというモジュールもXML::Atom::Clientと同様に、AtomPubクライアントを実装するための、WSSE認証やリクエスト、レスポンスに必要なXML文書の組み立てなどを抽象化したモジュールです。
atomutilを用いて、はてなブログにエントリを投稿するサンプルコードは以下です。
#!/usr/bin/env ruby
require
'
atomutil
'
USERNAME
=ARGV
[0
]BLOG_DOMAIN
=ARGV
[1
]API_KEY
=ARGV
[2
]POST_URI
="
https://blog.hatena.ne.jp/
#{USERNAME}
/
#{BLOG_DOMAIN}
/atom/entry
"
auth =Atompub
::Auth
::Wsse
.new( username:USERNAME
, password:API_KEY
) client =Atompub
::Client
.new(auth: auth) entry =Atom
::Entry
.new( title:"
テストエントリ
"
.encode('
BINARY
'
,'
BINARY
'
), content: <<'ENDOFCONENT'
.encode('
BINARY
'
,'
BINARY
'
))*もちろん
- はてな記法も
- 書けます
ENDOFCONENT
p client.create_entry(POST_URI
, entry);
このスクリプトはコマンドラインから、
$ ruby atompost.rb はてなID ブログドメイン APIキー
として実行できます。
Scala を用いた例
ここではJavaのモジュールであるApache Abderaを用いた記事の投稿を、Scalaで実装した例を紹介します。
はてなブログにエントリを投稿するサンプルコードは以下の通りです。
import
java.util.Dateimport
org.apache.abdera.Abderaimport
org.apache.abdera.protocol.client.AbderaClientimport
org.apache.abdera.ext.wsse.WSSEAuthScheme;import
org.apache.commons.httpclient.UsernamePasswordCredentials;object
AtomPubEntryPost {def
main(args:Array
[String
]): Unit = {val
username =""
;val
blogDomain =""
;val
apiKey =""
;val
abdera =new
Abderaval
abderaClient =new
AbderaClient(abdera) WSSEAuthScheme.register(abderaClient,true
); abderaClient.addCredentials("https://blog.hatena.ne.jp"
,null
,"WSSE"
,new
UsernamePasswordCredentials(username, apiKey));val
factory = abdera.getFactoryval
entry = factory.newEntry entry.setTitle("タイトル"
) entry.setUpdated(new
Date()) entry.addAuthor(username) entry.setContent("本文"
)val
response = abderaClient.post(s"https://blog.hatena.ne.jp/$username/$blogDomain/atom/entry"
, entry) println("STATUS CODE : "
+ response.getStatus) } }
依存モジュールは、sbtを用いた場合には、以下のような記述を加えてください。
libraryDependencies ++= Seq ("org.apache.abdera"
%"abdera-bundle"
%"1.1.3"
, )



















![Toni Kroos là ai? [ sự thật về tiểu sử đầy đủ Toni Kroos ]](https://evbn.org/wp-content/uploads/New-Project-6635-1671934592.jpg)


