Rails でメール受信なんぞしてみた
今回は、また Rails の話です。「10分で作るRailsアプリ for Windows」も無事クリアし(^_^)、次へステージ進むべく「Ruby on Rails入門 優しいRailsの育て方」を買ってきたが、やっぱ興味あるネタがないと、舞波の技は身につきませんね。せっかくの3連休ってことで、ちょうど、前からやってみたかったネタがあったので、Rails を使って挑戦してみました。やりたいのは、Webのメール共有管理ツールを作ること!イメージとしては、サイボウズのメールワイズ(*1)です。◆まずは、<実験その1>として・メールを受信し、DBへ格納するってとこまでやってみることにしました。Rails のことだから、それぐらいすぐに出来るだろうと思ったが、甘かった・・・(Google で探せば、そこいらにサンプルがころがっているだろうと・・・)とりあえず、本家で HowToReceiveEmailsWithActionMailer(*2) を見たが・・・意味が分からん。いや、英語が読めないってことではないですよ(^^; ソースの意味が分からんのです。なんで、STDIN からメールを食わせにゃならんかと・・・POP したけりゃ、 getmail を使ってみろと・・・なんで?とりあえず、そのままソースを入れて実行しても当然エラーばっかだし・・・「あぁ、JavaMail 使ってりゃよかったかなぁ」と弱気になるっす。(それじゃ、そもそもの意味が違うし!)気を取り直して、ビールでも飲みながらいろいろと調べると、ありました。同じような悩みに答えてくださった人を見つけました。(*3)「なんだ、事前にデータベースとモデルクラスの設定が必要なのね」そりゃそうだよね♪(意外と立ち直りが早い)ってことで、DB を作って、モデルも対応させ、メール1通分をテキストファイルにして、ruby script/runner Mailmgr.receive(STDIN.read) < sampleMail.txtと実行すると、ちゃーんとDBへ格納されました!(マイグレーションが良く分からないので、MySQL Administrator ツールで DB を作りました)よし、次は Pop だ。これまた、いろいろと調べると、ありました。Popする方法が。(*4)ありがたく頂戴し、ruby script/runner Mailmgr.r_mと実行すると、Pop して来てくれました!ここまで来れば、こっちのものです(^0^)ヘッダの中の、ほしいフィールドをテーブルに追加したり、Pop 直後に、サーバからメールを削除する処理を追加したりとちょちょいのちょいです。構想:3分製作:3日 実働12時間(うち、調べ物がほとんど)実行結果は、こんな感じでテーブルにメールデータが入っています。(中身は文字化けで良く分かりません。PostgreSQL 使いなので MySQL のツールも分からんす)◆次の課題は・文字化けの克服・スレッド表示のための準備◆ソースいただいたお礼に、ささやかながら地域に還元させていただきます。require 'nkf'require 'net/pop'class Mailmgr < ActionMailer::Base @address = 'mailServer' @port = 110 @id = 'mailId' @pass = 'mailPassword' def receive(email) page = Page.find_by_address(email.to.first) || Page.create(:address => email.to.first) page.emails.create( :subject => email.subject, :body => email.body, :header => email.header, :messageid => email.message_id, :receivedate => email.date ) if email.has_attachments? for attachment in email.attachments name = attachment.original_filename # 日本語ファイル名の場合はデコード if(name =~ /=\?ISO-2022-JP\?B\?/) name.gsub!(/=\?ISO-2022-JP\?B\?/,'') name = NKF.nkf('-mB', name) end page.attachments.create({ :file => attachment, :description => email.subject, :filename => name }) end end end def Mailmgr.r_m pop = Net::POP3.new(@address, @port) pop.start(@id, @pass) if !pop.mails.empty? then pop.each_mail do |m| receive(m.pop) # 受信したメールを、「処理」する(DBへ登録) m.delete # 受信したメールをサーバから削除 end end pop.finish endend◆注釈*1:実際に評価版で使ってみたが、OutlookExpress のアホな仕様についてこれず、スレッド表示が役に立たなくて、購入を見合わせました。<参考にさせていただいたサイト>*2:HowToReceiveEmailsWithActionMailerhttp://wiki.rubyonrails.com/rails/pages/HowToReceiveEmailsWithActionMailer*3:事前にデータベースとモデルクラスの設定が必要http://www.fdiary.net/ml/rails/msg/884*4:popする方法http://pascal.orz.cn/muse/pascal/70708190014.htmlNet::POP3http://www.ruby-lang.org/ja/man/?cmd=view;name=net%2FpopTMailhttp://i.loveruby.net/ja/projects/tmail/