GMailのatomフィードを読み込んでみる

GMailでは,新着メールをatomフィードで出力してくれますよね.それを,Rubyで読み込んでみようじゃないかと言うのがこの企画.

# test_atom.rb
require 'net/https'
require 'rexml/document'

account = 'your_account'
pass = 'password'

# 一応,SSL接続
https = Net::HTTP.new('mail.google.com', 443)
https.use_ssl = true
# VERIFY MODEをVERIFY_NONEにしないとだめ.
# この辺はGMailでSMTP接続するときと同じですね.
https.verify_mode = OpenSSL::SSL::VERIFY_NONE

# 接続
https.start

req = Net::HTTP::Get.new('/mail/feed/atom')
# ベーシック認証.こーやってするのかーと勉強になった.
req.basic_auth account, pass

# レスポンスの取得
res = https.request(req)

# レスポンスのbodyをパースしてREXMLオブジェクトを作成
doc = REXML::Document.new(res.body)

# 新着メールだけを取り出す
# 新着メールが無いと,勿論何も起こらない
entries = []
doc.root.each_child do |child|
  entries << child if child.name == "entry"
end

entries.each do |entry|
  puts entry.elements["title"].text
  puts entry.elements["summary"].text
  puts entry.elements["author/email"].text
end

# 終了
https.finish

実行結果です.

$ ruby test_atom.rb 
Test
ちょっとしたテスト
omochist_at_gmail.com # _at_は勿論@

ちなみにこのメール自体は,SMTPのテストをしたときに作ったものなので簡素です.APIを眺めているとこうなったと言う感じ.

メールのグローバルアドレス(?)の取り出し方は,

entry.elements["link"].attribute("href")

でよくて,

http://mail.google.com/mail?account_id=omochist%40gmail.com&amp;
message_id=(略)&amp;view=conv&amp;extsrc=atom

なんていう長ったらしいものが返ってくる*1.&がエスケープされてるんだな.
じゃぁこれの内容を取ってこれば全文いけるんじゃネーノとか思うんですが,そうもいかないんですよね.精いっぱい努力してみた*2ものの,なんだかやっぱり無理っぽい.



もともとは,「GMailPOP3SSLで,Rubyじゃ使えないんだよー」とか学校で話しているときに,id:hakobe932が「んじゃatomフィードで取得すりゃ良いんじゃね?」とか言い出した事から始まったのですが,全文は取り出せないので結局ふりだしに戻った感じです.


でもまーこの知識を元に,RSSリーダとか作ると面白いかもーとか思ったり.

努力の結果

# test_link.rb
require 'net/https'
require 'uri'

account = 'account'
pass = 'pass'

https = Net::HTTP.new('mail.google.com', 443)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
https.start

# このuriは,atomフィードのlinkのhref
url = URI.parse("http://mail.google.com/mail?account_id=account%
40gmail.com&message_id=aaaaaaaaaaaa&view=conv&extsrc=atom")
query = url.query

# もうちょっと綺麗な取り出し方無いかな?
query[/account_id=([^&]*)/]
account_id = $1
query[/message_id=([^&]*)/]
message_id = $1

req = Net::HTTP::Post.new(url.path)
req.form_data = {"account_id" => account_id,
                 "message_id" => message_id,
                 "view" => "conv",
                 "extsrc" => "atom"}
req.basic_auth account, pass

res = https.request(req)
# => #<Net::HTTPFound 302 Moved Temporarily readbody=true>

puts res.body

実行結果は,

$ ruby test_link.rb 

何も無し.結局,java scriptでリダイレクトされたりするから,お目当てのURLに飛べず,さらにわざわざそのリダイレクト先のURLを読み込んでみても何も取得できないので,降参.

*1:もちろん改行は入りません

*2:続きを読む,努力の結果