devdev blog

なにかウェブサービスを作りたい

node.jsでGmailの新着メールの監視・取得する方法

サーバサイドで、「Gmailの新着メールをチェックして、メールがあったら取得する」という処理をする方法について調べてみました。

  • サーバサイドは、node.jsで実装
  • Gmailとの通信は IMAPを使用

node.jsの IMAPクライアントライブラリ探し

「node.js imap」でググると、、

  1. mscdex/node-imap

    2014/01/23 - An IMAP client module for node.js. Contribute to node-imap development by creating an account on GitHub

  2. andris9/inbox

    Simple IMAP client for node.js. Contribute to inbox development by creating an account on GitHub.

  3. node.js - Get new email with node-imap nodejs - Stack Overflow

要約すると

  • 質問者 「gmailの新着メールを node-imap で取得してるんだけど、cron jobじゃなくって新着がきたらすぐ処理したいんだけど、どうしたらいいの?数分おきに見に行くとか嫌。」
  • 回答 「IMAP IDLEコマンドつかうといいよ。僕はIDLE使うのやめたけどね。」

IMAP IDLEコマンドという、新着メールをプッシュ通知する仕組みがあるんですね。但し、以下の様な注意点があるようです。

  1. IDLEコマンドは、メッセージを受信したことを教えてくれるけど、どのメッセージが新着かは教えてくれない。
  2. IDLEコマンド中は、他のコマンド(検索とか)は送信出来ないので、メッセージを取得するには、他のプロセスで行う必要がある。

node-imapとinbox

みつかった、有名そうなライブラリは node-imapとinboxというライブラリですが、node-imapは低レベルなAPIを提供し、inboxはより高レベルなAPIを提供しているようです。

今回やりたいことは inboxを使うと簡単にできそうです。サンプルに既に書いてありました。

Wait for new messages

You can listen for new incoming e-mails with event "new"

client.on("new", function(message){
    console.log("New incoming message " + message.title);
});

新着通知の際に、そのメッセージまで教えてくるようです。これを使えばOKそう!

脇道

inboxの new イベントはどういう実装をしてるのでしょうか。 https://github.com/andris9/inbox/blob/master/lib/client.js を読んでみると、 SELECTコマンド等でメールボックスを選択すると、自動的にIDLEコマンドを発行し、idleモードになり、コマンド送信時は、一旦IDLE状態を終了し、コマンド実行後に再度IDLEモードに入るようです。 新着メールの識別は、現在取得済みのメッセージのUIDの最大値+1から始まるUIDを対象にFETCHしているようです。

※UIDはメールボックスの中でユニークで、かつ、必ず昇順に割り当てられる、という仕様です。