2011/02/28

Rails3 で POP 受信したメールを DB に登録する

現在作成しているアプリケーションで、メールを取り込む必要が出てきたので、学習した。
まずは、何も考えず登録するだけのコード。
サンプルでよくある $STDIN.read で取得するデータを POP3 で取得するにはどうすればいいかだけがカギかな。
class MailClient
  Net::POP3.start('mail_server', 110, 'account', 'password') do |pop|
    pop.mails.each |m|
      UserMailer.receive(m.pop)
      m.delete
    end
  end
end

ところが今回の環境では、サーバからメールを削除できないという条件があった。
(正確には別の手段で10日以上たったメールを削除している)
このため、差分受信を自前で実装しなければならない。
すでに受信したメールを判別するには、一意なキーが必要だけど候補は二つ。
Net::POPMail#unique_id か Mail#message_id でも、Mail オブジェクトを作るためには、m.pop でメールを受信しなければならない。(pop を呼び出す前までは、LIST コマンドで取得した数値だけ持っている)
というわけで、Net::POPMail#unique_id で判別したい。すなわち、unique_id を DB に登録した、
しかし、ActionMailer#receive メソッドで自動的に Mail オブジェクトにパースされると、この unique_id の値がどっかに行くようだ。
なので、引数が一つしか渡せない ActionMailer#receive では unique_id を DB に登録するのは無理だ。
というわけで、ActionMailer#receive を使うのは諦めるしかない。
結局、下記のようなコードになった。

class MailClient
  Net::POP3.start('mail_server', 110, 'account', 'password') do |pop|
    registered_unique_id_list = UserMail.select(:unique_id).all.collect { |um| um.unique_id }
    pop.mails.each |m|
      unless registered_unique_id_list.include?(m.unique_id)
        mail = Mail.new(m.pop)
        save_mail(mail, m.unique_id)
      end
    end
  end
end
とりあえずは、これで動いている。
でも、そもそも差分受信のロジックを要勉強な気がする。
どっかのメーラのソースでも読むべきかな

0 件のコメント :

コメントを投稿