好久好久没有写过Blog了,五一放假其间赶紧补上。
在Ubuntu7.04上,可以用postfix作为邮件发送服务器,如果只想通过本机发送邮件,则可以考虑不使用smtp验证
安装postfix:
ruby 代码
- sudo apt-get install postfix
配置postfix:
ruby 代码
- sudo dpkg-reconfigure postfix
ruby 代码
- internet Site
- NONE
- server1.example.com
- server1.example.com,localhost.example.com,localhost
- No
- 127.0.0.0/8
- Yes
- 0
- +
- all
如果希望局域网内其他电脑能够通过本机发送邮件,则将127.0.0.0/8这一栏改为
127.0.0.0/8, 192.168.1.0/24
这样在192.168.1.x网段的电脑都可以使用本机邮件发送服务了,此时可以开一个postfix日志窗口查看邮件是否能够正常发送
ruby 代码
- tail -f /var/log/mail.log
测试邮件发送服务:
ruby 代码
- telnet localhost 25
- Trying 127.0.0.1...
- Connected to localhost.
- Escape character is '^]'.
- 220 nicole ESMTP Postfix (Ubuntu)
-
- ehlo localhost
- mail from: lgn21st@gmail.com
- rcpt to: lgn21st@163.com
- Subjet: My Test
- HelloWorld,
- .
- quit
Rails通过ActionMail组件来为rails程序提供邮件发送功能,ActionMail是对Ruby的Net::SMTP模块的高级封装
首先需要配置rails的环境设置:
ruby 代码
- vim config/environment.rb
在environment.rb尾部添加如下代码:
ruby 代码
- ActionMailer::Base.smtp_settings = {
- :address => "localhost",
- :port => 25,
- :domain => "example.com"
- }
生成一个邮件发送服务的Model,这里取名为notifier:
ruby 代码
- ruby script/generate mailer notifier
编辑app/model/notifier.rb,添加一个notifier_mail的方法:
ruby 代码
创建邮件内容模板app/views/notifier/notifier_mail.rhtml,内容可以按自己的需要定制
测试rails的邮件发送功能,打开rails的console
ruby 代码
- ruby script/console
- Notifier.deliver_notifier_mail
console如果不返回错误,并能看到正确的TMail::Mail对象,就可到在日志中(railsapp/log/development.log)查看到发送出去邮件体是否符合预期,查看邮件服务器日志中邮件队列是否正常处理(/var/log/mail.log),查看电子邮箱中是否收到测试邮件了。
这里可能会遇到一个问题,通过自己搭的邮件服务器发送出去的邮件总是被网上邮件服务器当做spam过滤掉
希望能通过Gmail提供的SMTP服务发送邮件,但需要ActionMail支持ssl/tls方式访问SMTP服务器,ActionMail并不直接支持ssl/tls,在网上找到一个方法,可以实现此功能,需要编译并安装ruby的openssl模块,然后在rails应用程序中对Net::SMTP作扩展。
首先需要在系统中安装Openssl开发包(编译ruby的openssl模块需要)
ruby 代码
- sudo apt-get install libssl-dev
编译并安装ruby的openssl模块:
ruby 代码
- cd ruby-CurrentVersion/ext/openssl
- ruby extconf.rb
- make
- sudo make install
扩展rails,在rails应用程序的lib目录下新建一个smtp_tls.rb的文件:
ruby 代码
- require "openssl"
- require "net/smtp"
-
- Net::SMTP.class_eval do
- private
- def do_start(helodomain, user, secret, authtype)
- raise IOError, 'SMTP session already started' if @started
- check_auth_args user, secret, authtype if user or secret
-
- sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
- @socket = Net::InternetMessageIO.new(sock)
- @socket.read_timeout = 60
-
- check_response(critical { recv_response() })
- do_helo(helodomain)
-
- if starttls
- raise 'openssl library not installed' unless defined?(OpenSSL)
- ssl = OpenSSL::SSL::SSLSocket.new(sock)
- ssl.sync_close = true
- ssl.connect
- @socket = Net::InternetMessageIO.new(ssl)
- @socket.read_timeout = 60
- do_helo(helodomain)
- end
-
- authenticate user, secret, authtype if user
- @started = true
- ensure
- unless @started
-
- @socket.close if not @started and @socket and not @socket.closed?
- @socket = nil
- end
- end
-
- def do_helo(helodomain)
- begin
- if @esmtp
- ehlo helodomain
- else
- helo helodomain
- end
- rescue Net::ProtocolError
- if @esmtp
- @esmtp = false
- @error_occured = false
- retry
- end
- raise
- end
- end
-
- def starttls
- getok('STARTTLS') rescue return false
- return true
- end
-
- def quit
- begin
- getok('QUIT')
- rescue EOFError
- end
- end
- end
修改rails应用程序的环境配置,在之前提到的environment.rb文件尾部修改:
ruby 代码
- require "smtp_tls"
- ActionMailer::Base.smtp_settings = {
- :address => "smtp.gmail.com",
- :port => 587,
- :authentication => :plain,
- :user_name => "your name",
- :password => "your password"
- }
至此,原rails应用程序不需要修改发送邮件部分的代码,只需要简单置入一个扩展文件,并作相应的配置,即获得用ssl/tls方式访问Gmail的SMTP服务器。简单测试一下,此方法发出的邮件不大会被spam掉,但事无绝对,此方法仅仅是一个参考,好处是不需要为自己的rails应用程序架设邮件服务器,缺点是无法跟踪查看邮件服务器以及邮件队列的日志信息,但Gmail一旦发送邮件失败,会自动给你的账号发送一封发送失败提示邮件。