まずはテストコードとこれを動かした結果。リクエストにエラーがあるといわれるけど、どこがまずいのかはわからない。
$ cat googlereader_test.pl #!/usr/bin/perl use strict; use warnings; use WebService::Google::Reader; my $reader = WebService::Google::Reader->new( username => '*******', password => '*******', ); $reader->unsubscribe('http://search.cpan.org/uploads.rdf'); print $reader->error; exit; $ perl googlereader_test.pl 400 Bad Request - <html><head><title>400 Client Error</title> <style type="text/css"> body {font-family: arial,sans-serif} div.nav {margin-top: 1ex} div.nav A {font-size: 10pt; font-family: arial,sans-serif} span.nav {font-size: 10pt; font-family: arial,sans-serif; font-weight: bold} div.nav A,span.big {font-size: 12pt; color: #0000cc} div.nav A {font-size: 10pt; color: black} A.l:link {color: #6f6f6f} </style></head> <body text="#000000" bgcolor="#ffffff"><table border="0" cellpadding="2" cellspacing="0" width="100%"></table> <table><tr><td rowspan="3" width="1%"><b><font face="times" color="#0039b6" size="10">G</font><font face="times" color="#c41200" size="10">o</font><font face="times" color="#f3c518" size="10">o</font><font face="times" color="#0039b6" size="10">g</font><font face="times" color="#30a72f" size="10">l</font><font face="times" color="#c41200" size="10">e</font> </b></td> <td> </td></tr> <tr><td bgcolor="#3366cc"><font face="arial,sans-serif" color="#ffffff"><b>Error</b></font></td></tr> <tr><td> </td></tr></table> <blockquote><h1>Client Error</h1> There was an error in your request. <p></p></blockquote> <table width="100%" cellpadding="0" cellspacing="0"><tr><td bgcolor="#3366cc"><img alt="" width="1" height="4"></td></tr></table></body></html>
ngrepを仕込んでパケットキャプチャした結果が以下。GoogleReaderAPIの非公式文書を当たると、subscription/edit系のAPIはtokenが必要とのこと。本家WebService::Google::Readerを使うとtokenが送られていない。
# ngrep -d ppp0 -W byline WebService interface: ppp0 (***************/255.255.255.255) match: WebService T ***************:58605 -> 66.249.89.104:80 [AP] POST /reader/api/0/subscription/edit?ck=1277968999000&client=WebService%3A%3AGoogle%3A%3AReader%2F0.1+(gzip) HTTP/1.1. TE: deflate,gzip;q=0.3. Connection: TE, close. Accept-Encoding: gzip,deflate. Authorization: GoogleLogin auth=***********************************************************************************************************************************************************************************************************. Host: www.google.com. User-Agent: WebService::Google::Reader/0.1 (gzip). Content-Length: 272. Content-Type: application/x-www-form-urlencoded. . ac=unsubscribe&s=feed%2Fhttp%3A%2F%2Fsearch.cpan.org%2Fuploads.rdf&T=*********************************************************************************************************************************************************************************************************** 118 received, 0 dropped
tokenとは何かを非公式文書から調べる。tokenとはhttp://www.google.com/reader/api/0/tokenにアクセスして得られる57文字の文字列のことらしい。
To edit anything in the Google Reader database, you need a token (see glossary). To get a token, just go to http://www.google.com/reader/api/0/token . This url will return a string containing 57 chars. It's the token.
まずはtokenを得るためのコード。tokenを得るためには最初にログインをする必要がある。得られた文字列は57文字ではない(22文字)けど、これで問題ない。
$ cat googlereader_test.pl #!/usr/bin/perl use strict; use warnings; use HTTP::Request; use WebService::Google::Reader; my $reader = WebService::Google::Reader->new( username => '*******', password => '*******', ); $reader->_login; my $req_token = HTTP::Request->new(GET => 'http://www.google.com/reader/api/0/token'); my $res_token = $reader->_request($req_token); print $res_token->content, "\n"; exit; $ perl googlereader_test.pl **********************
ngrepでパケットキャプチャしたときの記録。
# ngrep -d ppp0 -W byline WebService interface: ppp0 (***************/255.255.255.255) match: WebService T ***************:49241 -> 66.249.89.99:80 [AP] GET /reader/api/0/token?ck=1277970643000&client=WebService%3A%3AGoogle%3A%3AReader%2F0.1+(gzip) HTTP/1.1. TE: deflate,gzip;q=0.3. Connection: TE, close. Accept-Encoding: gzip,deflate. Authorization: GoogleLogin auth=***********************************************************************************************************************************************************************************************************. Host: www.google.com. User-Agent: WebService::Google::Reader/0.1 (gzip). .
得られたtokenを使ってsubscribeしてみる。エラーなしで終了する。確かにフィードが購読されていることがブラウザからログインして確かめられる。
$ cat googlereader_test.pl #!/usr/bin/perl use strict; use warnings; use HTTP::Request::Common qw(POST); use Data::Dumper; use WebService::Google::Reader; my $reader = WebService::Google::Reader->new( username => '*******', password => '*******', ); $reader->_login; my $req_token = HTTP::Request->new(GET => 'http://www.google.com/reader/api/0/token'); my $res_token = $reader->_request($req_token); my $uri = 'http://www.google.com/reader/api/0/subscription/edit'; my $req = HTTP::Request->new(); $req = POST($uri,[ ac => 'subscribe', s => 'feed/http://search.cpan.org/uploads.rdf', T => $res_token->content, ]); $reader->_request($req); $reader->error; exit; $ perl googlereader_test.pl
ngrepの記録。tokenを持ってきて、これを使ってsubscribeしていることがわかる。
# ngrep -d ppp0 -W byline WebService interface: ppp0 (***************/255.255.255.255) match: WebService T ***************:45131 -> 66.249.89.99:80 [AP] GET /reader/api/0/token?ck=1277970978000&client=WebService%3A%3AGoogle%3A%3AReader%2F0.1+(gzip) HTTP/1.1. TE: deflate,gzip;q=0.3. Connection: TE, close. Accept-Encoding: gzip,deflate. Authorization: GoogleLogin auth=***********************************************************************************************************************************************************************************************************. Host: www.google.com. User-Agent: WebService::Google::Reader/0.1 (gzip). . ############### T ***************:45132 -> 66.249.89.99:80 [AP] POST /reader/api/0/subscription/edit?ck=1277970978000&client=WebService%3A%3AGoogle%3A%3AReader%2F0.1+(gzip) HTTP/1.1. TE: deflate,gzip;q=0.3. Connection: TE, close. Accept-Encoding: gzip,deflate. Authorization: GoogleLogin auth=***********************************************************************************************************************************************************************************************************. Host: www.google.com. User-Agent: WebService::Google::Reader/0.1 (gzip). Content-Length: 89. Content-Type: application/x-www-form-urlencoded. . ac=subscribe&s=feed%2Fhttp%3A%2F%2Fsearch.cpan.org%2Fuploads.rdf&T=********************** 54 received, 0 dropped
つまり、subscription/editする場合はtokenを持ってきて、これを含めてPOSTすればいいということになる。subscription/edit系ののメソッドで全てこれをやるのは煩雑なのでモジュール化して欲しい。