Actionmailer

[9]Actionmailer

1.Actionmailer
メールの送信やメール本文の解析を行うActionMailerパッケージが標準装備されています。これを使ってSMTPPOP3と簡単に遣り取りすることができます。ここでは簡単なメーラを作ってみましょう。

1-1.プロジェクトの生成
(1) プロジェクトAppli010を生成する
(2) 日本語環境の設定
(3) データベースの作成

1-2.テーブルpageの作成
(1) モデルの作成
NetBeansで[生成..]を選択します
    ジェネレータ(G):model
    引数(A):Page


実行結果
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/page.rb
create test/unit/page_test.rb
create test/fixtures/pages.yml
create db/migrate
create db/migrate/20100210000356_create_pages.rb

(2) マイグレーションファイルの修正


/db/migrate/20100210000356_create_pages.rb
class CreatePages < ActiveRecord::Migration
def self.up
create_table :pages do |t|
t.column :address, :string
t.timestamps
end
end

def self.down
drop_table :pages
end
end

(3) マイグレーションファイルの実行
NetBeansで[データベースマイグレーション]→[現在のバージョンへ]を選択します。


実行結果
(in D:/Rails_Projects/Appli010)
== CreatePages: migrating ====================================================
-- create_table(:pages)
-> 0.1090s
== CreatePages: migrated (0.1090s) ===========================================

1-3.テーブルemailの作成
(1) モデルの作成
NetBeansで[生成]を選択します。
    ジェネレータ(G):model
    引数(A):Email


実行結果
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/email.rb
create test/unit/email_test.rb
create test/fixtures/emails.yml
exists db/migrate
create db/migrate/20100210000929_create_emails.rb

(2) マイグレーションファイルの修正


/db/migrate/20100210000929_create_emails.rb
class CreateEmails < ActiveRecord::Migration
def self.up
create_table :emails do |t|

t.column :page_id, :integer
t.column :subject, :string
t.column :receivedate, :timestamp
t.column :messageid, :string
t.column :header, :text
t.column :body, :text

t.timestamps
end
end

def self.down
drop_table :emails
end
end

(3) マイグレーションファイルの実行
NetBeansで[データベースマイグレーション]→[現在のバージョンへ]を選択します。


実行結果
(in D:/Rails_Projects/Appli010)
== CreateEmails: migrating ===================================================
-- create_table(:emails)
-> 0.1560s
== CreateEmails: migrated (0.1560s) ==========================================

1-4.テーブルattachmentの作成
(1) モデルの作成
NetBeansで[生成]を選択
    ジェネレータ(G):model
    引数(A):Attachment


実行結果
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/attachment.rb
create test/unit/attachment_test.rb
create test/fixtures/attachments.yml
exists db/migrate
create db/migrate/20100210001457_create_attachments.rb

(2) マイグレーションファイルの修正


/db/migrate/20100210001457_create_attachments.rb
class CreateAttachments < ActiveRecord::Migration
def self.up
create_table :attachments do |t|

t.column :page_id, :integer
t.column :file, :binary
t.column :filename, :string
t.column :description, :string

t.timestamps
end
end

def self.down
drop_table :attachments
end
end

(3) マイグレーションファイルの実行
NetBeansで[データベースマイグレーション]→[現在のバージョンへ]を選択します。


実行結果
(in D:/Rails_Projects/Appli010)
== CreateAttachments: migrating ==============================================
-- create_table(:attachments)
-> 0.1100s
== CreateAttachments: migrated (0.1100s) =====================================

1-5.リレーションの宣言


/app/models/page.rb
class Page < ActiveRecord::Base
has_many :emails
has_many :attachments
end

1-6.メール受信専用モデルの作成
(1) モデルの生成
NetBeansで[生成..]を選択します。
    ジェネレータ(G):mailer
    引数(A):Mailreceiver


実行結果
exists app/models/
create app/views/mailreceiver
exists test/unit/
create test/fixtures/mailreceiver
create app/models/mailreceiver.rb
create test/unit/mailreceiver_test.rb

(2) モデルの編集


/app/models/mailreceiver.rb

require 'net/pop'

class Mailreceiver < ActionMailer::Base

@address = 'POP3saver' # <= 自分のPOP3サーバー
@port = 110 # <= ポート番号 110など
@id = 'userid' # <= ユーザーID
@pass = 'password' # <= パスワード

def receive(email)
page = Page.find_by_address(email.from.first) ||
Page.create(:address => email.from.first)
str = email.subject.kconv(Kconv::UTF8, Kconv::JIS) # JIS から UTF8 に変換
page.emails.create(
:subject => str,
:body => email.body,
:header => email.header,
:messageid => email.message_id,
:receivedate => email.date
)

if email.has_attachments?
for attachment in email.attachments
str = attachment.original_filename.kconv(Kconv::UTF8, Kconv::JIS)
page.attachments.create({
:file => attachment,
:description => email.subject,
:filename => str
})
end
end
end

def Mailreceiver.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
end
end

1-7.動作確認


/app/models/mailreceiver.rb
D:\Rails_Projects\Appli010>ruby script/runner Mailreceiver.r_m
D:\Rails_Projects\Appli010>

1-8.メール送信サーバの設定


/config/environments/development.rb

# Settings specified here will take precedence over those in config/environment.rb

# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false

# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true

# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = false

# Don't care if the mailer can't send

config.action_mailer.raise_delivery_errors = true

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:address => 'SMTPsever', # <= 自分のSMTPサーバー
:port => 25, # <= ポート番号 25,587など
:authentication => :login, # <= 認証方法 :plain, :login, :cram_md5など
:user_name => "username", # <= ユーザーID
:password => "password", # <= パスワード
:domain => "domain" # <= ドメイン
}

1-9.メール送信専用モデルの作成
(1) モデルの生成
NetBeansで[生成]を選択します。
    ジェネレータ(G):mailer
    引数(A):Mailsender


実行結果
exists app/models/
create app/views/mailsender
exists test/unit/
create test/fixtures/mailsender
create app/models/mailsender.rb
create test/unit/mailsender_test.rb

(2) モデルの修正


/app/models/mailsender.rb
class Mailsender < ActionMailer::Base
@@default_charset = 'iso-2022-jp'

def okuru(okuru)
str = okuru[:subject].kconv(Kconv::JIS, Kconv::UTF8) # UTF8 から JIS に変換
@subject = str
@recipients = okuru[:to]
@from = okuru[:from]
@sent_on = Time.now
str = okuru[:body].kconv(Kconv::JIS, Kconv::UTF8) # UTF8 から JIS に変換
@body = str
@headers["reply-to"] = okuru[:from]
end

end

1-10.コントローラrmailerの作成
(1) コントローラの生成
NetBeansで生成を選択
    ジェネレート(G):controller
    名前(N):rmailer
    ビュー(V):list show new okuru ukeru


実行結果
exists app/controllers/
exists app/helpers/
create app/views/rmailer
exists test/functional/
create app/controllers/rmailer_controller.rb
create test/functional/rmailer_controller_test.rb
create app/helpers/rmailer_helper.rb
create app/views/rmailer/list.html.erb
create app/views/rmailer/show.html.erb
create app/views/rmailer/new.html.erb
create app/views/rmailer/okuru.html.erb
create app/views/rmailer/ukeru.html.erb

(2) コントローラの編集


/app/controllers/rmailler_controller.rb
class RmailerController < ApplicationController
layout "rmailer"

def list
@emails = Email.find(:all)
end

def show
@email = Email.find(params[:id])
end

def new
end

def okuru
@okuru = params[:okuru]
logger.info "EMAIL:" + params[:okuru][:to]
Mailsender.deliver_okuru(@okuru)
end

def ukeru
job = open('|ruby script/runner Mailreceiver.r_m')
end

end

1-11.ビューの作成
(1) 送信用メールフォームの作成


/app/views/rmailer/new.html.erb
<br>
<div class="box"><%= link_to "受信箱", :action => "list" %>
</div>
<br>
<h1>新規送信メール</h1><% form_for(:okuru, :url =>{:action => "okuru"}) do |f| %><%= error_messages_for('okuru') %>
<table width="60%">
<tr><th>subject</th><td><%= f.text_field(:subject, :size => 60 ) %></td></tr>
<tr><th>to</th><td><%= f.text_field(:to, :size => 60 ) %></td></tr>
<tr><th>from</th><td><%= f.text_field(:from, :size => 60 ) %></td></tr>
<tr><th>body</th><td><%= f.text_area(:body, :cols => 50, :rows => 10 ) %></td></tr>
<tr><th></th><td><%= submit_tag("送信") %>
</table><% end %>

(2) 送信完了通知の作成


/app/views/rmailer/okuru.html.erb
<br>
<div class="box"><%= link_to "受信箱", :action => "list" %>
</div>
<br>
<P>送信終了しました</p>

(3) 受信完了通知の作成


/app/views/rmailer/ukeru.html.erb
<br>
<div class="box"><%= link_to "受信箱", :action => "list" %>
</div>
<br>
<P>受信終了しました</p>

(4) 受信箱の作成


/app/views/rmailer/list.html.erb
<br>
<div class="box"><%= link_to "新規送信", :action => "new" %><%= link_to "受信", :action => "ukeru" %>
</div>
<br>
<h1>受信箱</h1>
<table>
<thead>
<tr>
<th>subject</th>
<th>address</th>
<th>receivedate</th>
<th></th>
</tr>
</thead>

<tbody><%-
fg = "ON"
@emails.each do |e|
@page = Page.find(e.page_id)
if fg=="ON" then
fg = "off"
-%>
<tr><%-
else
fg = "ON"
-%>
<tr class="odd"><%- end -%>
<td><%=h e.subject %></td>
<td><%=h @page.address %></d>
<td><%=h e.receivedate %></td>
<td><%= link_to "show", :action => "show", :id => e.id %></td>
</tr><% end %>
</tbody>
</table>

(5) 受信メール表示の作成


/app/views/rmailer/show.html.erb
<br>
<div class="box"><%= link_to "受信箱", :action => "list" %>
</div>
<br>
<h1>受信メール</h1><% @page = Page.find(@email.page_id) %>
<table width="60%">
<tr><th>subject</th><td><%=h @email.subject %></td></tr>
<tr><th>address</th><td><%=h @page.address %></td></tr>
<tr><th>receivedate</th><td><%=h @email.receivedate %></td></tr>
<tr><th>body</th><td><%=h @email.body %></td></tr>
</table>

1-12.スタイルシートの作成
(1) CSSで使用する画像の準備
/public/images/に透過のtable-back.gifを用意します。
これは見出し部分を立体的に見せる工夫で背景色より薄めの色で枠線を作ります。

(2) IE対応
IE6.0ではtr:hoverが動作しません。
http://www.xs4all.nl/~peterned/csshover.htmlからcsshover.htcをダウンロードし、
ダウンロードしたファイルをcsshover3.htcとリネームして/public/stylesheets/に保存します。

(3) CSSファイルの作成


/public/stylesheets/rmailer.css
/* 見出しを作る */
h1 {
padding: 10px;
border: medium solid #5C443A;
color: #5C443A;
font-family: sans-serif;
}


/* 文字に背景色を付ける */
.box a {
text-decoration: none; /* 下線を消す */
background-color: #cdcdcd; /* 背景色を薄い灰色 */
color: #000000; /* 文字を黒色 */
padding: 4px 10px 2px 10px;
}
.box a:link { /* 未訪問のリンク */
background-color: #cdcdcd; /* 背景色を薄い灰色 */
color: #000000; /* 文字を黒色 */
}
.box a:visited { /* 訪問済みのリンク */
background-color: #cdcdcd; /* 背景色を薄い灰色 */
color: #000000; /* 文字を黒色 */
}
.box a:hover { /* マウスがのっているとき */
background-color: #808080; /* 背景色を濃い灰色 */
color: #ffffff; /* 文字を白色 */
}
.box a:active { /* クリック時のリンク */
background-color: #808080; /* 背景色を濃い灰色 */
color: #ffff00; /* 文字を黄色 */
}

/* テーブル行に背景色を付ける */
body {
behavior: url(/stylesheets/csshover3.htc);
}

table {
border-top:1px solid #5C443A;
border-left:1px solid #5C443A;
border-collapse:collapse;
background:#ffffff;
font-size:90%;
}
caption {
color:#5C443A;
font-weight:bold;
text-align:center;
text-transform: uppercase;
}
thead th, tfoot th, tfoot td {
border-right:1px solid #5C443A;
border-bottom:1px solid #5C443A;
background:#5C443A;
color:#ffffff;
background-image:url(/images/table-back.gif);
background-position:left top;
padding:3px 10px 3px 10px;
text-align:center;
}
td, th {
padding:4px;
}
tbody tr th, tbody tr td {
border-right:1px solid #5C443A;
border-bottom:1px solid #5C443A;
}
tbody tr:hover td, tbody tr:hover th {
background: #996633;
color: #ffffff;
}
tbody tr:hover td a, tbody tr:hover th a {
background: #996633;
color: #ffffff;
}
tbody td a, tbody th a {
border: none;
background: transparent;
color: #000000;
text-decoration: none;
}
tbody td a:hover, tbody th a:hover {
background: #996633;
color: #ffffff;
text-decoration: underline;
}
.odd {
background: #ffeebb;
}

1-13.レイアウトファイルの作成


/app/views/layouts/rmailer.html.erb
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8"/>
<title>Rmailer</title>
<%= stylesheet_link_tag 'rmailer' %>
</head>
<body><%= yield %>

</body>
</html>

1-14.動作確認
(1) ブラウザよりhttp://127.0.0.1:3000/rmailer/listによる起動

(2) 受信メール表示

(3) 新規送信



Ajaxのテスト | index | ActiveResource