GMail の未読メールを自作スクリプトから読むための方法まとめ
諸般の事情で GMail の未読メールの本文を取得して、ごにょごにょ するスクリプトを作ってみたので、やり方をまとめます。
1. 未読メール一覧の取得
これはご存知の方も多いとは思います。GMail のヘルプにもある通り、未読メール一覧は https://mail.google.com/mail/feed/atom/ から ATOM 形式で取得できます。atom/ のあとにラベル名をつけたら、特定ラベルの未読メール一覧だけを取ってくることもできます。
認証はどうなってるかというと、Google のアカウント情報が Cookie に保存されていれば普通に表示できます。Cookie がないと HTTPS で BASIC 認証して、OK なら表示できるようになります。シンプルな仕様ですね。
取得できる ATOM はこんな感じ。ちゃんと個別のメールへアクセスするための URL も埋め込まれています。
<?xml version="1.0" encoding="UTF-8" ?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#">
<title>Gmail - Inbox for xxxx@gmail.com</title>
<tagline>New messages in your Gmail Inbox</tagline>
<fullcount>3</fullcount>
<link rel="alternate" href="http://mail.google.com/mail" type="text/html" />
<modified>2007-03-17T16:16:04Z</modified>
<entry>
<title>Subject</title>
<summary>本文少し</summary>
<link rel="alternate" href="http://mail.google.com/mail?account_id=xxxx%40gmail.com&message_id=123456789abcdefg&view=conv&extsrc=atom" type="text/html" />
<modified>2007-03-15T00:00:00Z</modified>
<issued>2007-03-15T00:00:00Z</issued>
<id>tag:gmail.google.com,2004:XXXXXXXXXXXXX</id>
<author>
<name>差出人</name>
<email>xxxx@xxxx.co.jp</email>
</author>
</entry>
<entry>
<title>....
2. メール本文の取得
(追記) 2008/05/08 現在、この方法は使えなくなっています…。
上の ATOM から個別のメールを表示するための URL は入手できました。
この URL にアクセスすれば、メール本文を取得できそうです。実際にブラウザで開けば本文を表示できるのですが、スクリプトから取得するとなると話は別になります。ためしに Firebug で覗いてみると、HTML の中身はこんな具合になってます。

ごちゃごちゃしてますね。フレームあり、Ajax あり…。スクリプトから解析するとなると気が重くなります。
じゃあ、どうすればいいかというと、簡易 HTML 表示の URL を叩けばいいのです。簡易 HTML 形式というのは、JavaScript が使えない環境のために用意されたインターフェースです。まさに打ってつけですね。
簡易 HTML 表示のための URL の作り方はこうなります。
- ATOM から取得した URL のうち、message_id を抜き出す。
http://mail.google.com/mail?account_id=xxxx%40gmail.com&message_id=123456789abcdefg&view=conv&extsrc=atom
- message_id の前に「http://mail.google.com/mail/h/mail?view=cv&search=all&th=」をつける。
http://mail.google.com/mail/h/mail?view=cv&search=all&th=message_id=123456789abcdefg
これだけです。なんとも簡単。
あとはこの URL に対して HTTP GET をはたけばいいだけです。レスポンスにはメール本文が含まれているので、必要な部分を正規表現で取り出すなり、XPath 使うなり、好きにスクレイピングしましょう。
注意点
- ATOM で取得できるのは未読メールだけ
- メール本文を取得すると既読になる(次に ATOM 取得したときにはそのメールは ATOM から消えている)
サンプル
HTA+JavaScript で作ってみました。ATOM で未読メールを取得して表示して、クリックしたら本文を取得しにいきます。
HTA にしたのは、Ajax のドメイン制限を取り除くためです。ただし、HTA からはプロセス起動もできてしまうので、セキュリティチェックは入念にしてください。このサンプルは悪意のある Subject からの攻撃は防いでいますが万全ではないかもしれません。
<body>
<script>
var label = "";
window.onload = function(){
var ajax = new ActiveXObject('Microsoft.XMLHTTP');
if(!ajax) return;
ajax.open('GET', 'https://mail.google.com/mail/feed/atom/'+label+"?"+(new Date()).getTime(), true);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200) {
parseXML(ajax.responseXML);
}
}
ajax.send(null);
}
function $(id){return document.getElementById(id);}
function parseXML(xml){
if(!xml) return;
var entries = xml.getElementsByTagName("entry");
for(var i = 0; i < entries.length; i++){
var entry = entries[i];
var title = entry.getElementsByTagName("title")[0].firstChild.nodeValue;
var link = entry.getElementsByTagName("link")[0].attributes;
var url = link.getNamedItem("href").nodeValue;
if(!title || !url) continue;
title = title.replace(/</g, "<").replace(/>/g, ">");
if(url.match(/message_id=([0-9a-zA-Z]+)/)){
url = "http://mail.google.com/mail/h/mail?view=cv&search=all&th=" + RegExp.$1;
$("mail_list").innerHTML += '<a href="' + url + '" onclick="return _link_click(this)">' + title + '</a><br>';
}
}
}
function _link_click(elm){
var ajax = new ActiveXObject('Microsoft.XMLHTTP');
if(!ajax) return;
var url = elm.href;
ajax.open('GET', url, true);
ajax.onreadystatechange = function(){
if(ajax.readyState == 4 && ajax.status == 200) {
// ajax.responseText に本文が入ってる
//alert(ajax.responseText);
}
}
ajax.send(null);
return false;
}
</script>
<div id="mail_list"></div>
</body>
おわり。