Railsでドットが連続3つ(トリプルドット)以上あるメールアドレスでもActionMailer::Base.deliverを利用してメールを送信する
●何がやりたいのか
RailsでActionMailer::Base.deliverを利用してメールを送信する場合、以下のようなアドレスは通常送信できないが、送信したい。
TMail 携帯メールアドレス問題 - 基本へ帰ろう←の対応策の一つ。
●実験
・ドットが連続3つ
C:\rails_app>ruby script/console Loading development environment. >> mail = TMail::Mail.new => #<TMail::Mail port=#<TMail::StringPort:id=0x246883e> bodyport=nil> >> mail.to = "hoge...hoge@docomo.ne.jp" => "hoge...hoge@docomo.ne.jp" >> ActionMailer::Base.deliver(mail) => #<TMail::Mail port=#<TMail::StringPort:id=0x246883e> bodyport=#<TMail::StringPort:id=0x246501c>>
Railsのログには以下のように残される。
Sent mail: To: <>
・ドットが連続2つ
C:\rails_app>ruby script/console Loading development environment. >> mail = TMail::Mail.new => #<TMail::Mail port=#<TMail::StringPort:id=0x246883e> bodyport=nil> >> mail.to = "hoge...hoge@docomo.ne.jp" => "hoge...hoge@docomo.ne.jp" >> ActionMailer::Base.deliver(mail) => #<TMail::Mail port=#<TMail::StringPort:id=0x246883e> bodyport=#<TMail::StringPort:id=0x246501c>>
Railsのログには以下のように残される。
Sent mail: To: hoge..hoge@docomo.ne.jp
上記の結果から分かるように、ドットが3つ以上のメールアドレスはToが消えてしまう。
●ドットが連続3つでもActionMailer::Base.deliverを使ってメールを送信する
結論から言うとこうやりました。
・tmail_triple_dot_measures.rb
module ActionMailer
class Base
def deliver!(mail = @mail)
if "#{mail.to}" =~ /\.\.\./
sendmail_lr = SendmailWithoutUsingActionmailer::Send.new(@from,@subject,@body)
sendmail_lr.sendto(@recipients)
return mail
end
raise "no mail object available for delivery!" unless mail
logger.info "Sent mail:\n #{mail.encoded}" unless logger.nil?
begin
send("perform_delivery_#{delivery_method}", mail) if perform_deliveries
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
raise e if raise_delivery_errors
end
return mail
end
end
end・sendmail_without_using_actionmailer.rb
module SendmailWithoutUsingActionmailer
=begin
Example:
class Mobile::Users::AccountController < ApplicationController
require 'sendmail_without_using_actionmailer'
def sendmail_for_triple_dot
subject = "テストタイトル"
body = "テスト本文"
from = "customer@#{SEND_DOMAIN}"
to = "hoge@docomo.ne.jp"
sendmail = SendmailWithoutUsingActionmailer::Send.new(from,subject,body)
sendmail.sendto( to )
end
end
=end
class Send
require "nkf"
SENDMAIL = "/usr/sbin/sendmail"
def initialize( from, subject, body )
@from = from
@subject = subject
@body = body
end
def encode( str )
require "base64"
"=?iso-2022-jp?B?" + Base64.encode64( NKF.nkf( "-j", str ) ).chomp + "?="
end
def sendto( to, cc = nil, bcc = nil )
text = "From: #{@from}\n"
text += "To: #{to}\n"
text += "Cc: #{cc}\n" if cc
text += "Bcc: #{bcc}\n" if bcc
text += "Subject: #{encode( @subject ).gsub(/\n/,'\\n') if @subject}\n"
text += "MIME-Version: 1.0\n"
text += "Content-Type: text/plain; charset=\"ISO-2022-JP\"\n"
text += "Content-Transfer-Encoding: 7bit\n"
text += "\n"
text += NKF.nkf( "-j", @body ) + "\n"
to = to.split( /,\s*/ )
to += cc.split( /,\s*/ ) if cc
to += bcc.split( /,\s*/ ) if bcc
[@from,*to].each do |t|
raise "Mail address error -> #{t}" if t !~ /^[0-9A-Za-z_\-\._]+@[0-9A-Za-z_\-\._]+$/
end
require "net/smtp"
logger = Logger.new("#{RAILS_LOG_FILE}")
begin
Net::SMTP.start( 'localhost' ) do |smtp|
smtp.send_mail text, @from, to
end
rescue
#送信失敗ログを出す
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND FALSE:To:\n #{to}\n" unless logger.nil?
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND FALSE:Subject:\n #{@subject}\n" unless logger.nil?
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND FALSE:Body:\n #{@body}\n" unless logger.nil?
return false
else
#送信成功ログを出す
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND TRUE:To:\n #{to}\n" unless logger.nil?
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND TRUE:Subject:\n #{@subject}\n" unless logger.nil?
#logger.info "SENDMAIL_WITHOUT_USING_ACTIONMAILER SEND TRUE:Body:\n #{@body}\n" unless logger.nil?
return true
end
end
end
endActionMailer::Base.deliverは使いますが、ドットを連続3つ以上含んでいたら、SendmailWithoutUsingActionmailerモジュールを使って送信すると言うやり方をやってみました。Viewのメールテンプレートもそのまま使えますので良いです。
Railsへの設置の仕方は、上記2つのファイルをRailsアプリのlibフォルダ内に入れます。