YOU'VE MADE A BRAVE DECISION, WELCOME.

每一个不曾起舞的日子都是对生命的辜负。

总结:Rails发送邮件

Rails中实现发送邮件的三种方式

1. Transactional Email

从应用中发出的邮件,用户的行为触发的邮件,比如邀请注册、验证邮箱、修改密码、回复提醒等。这时候需要有一个邮件服务商”email service provider”,来提供SMTP转发服务。

需要专业的邮件服务商来避免你发送的邮件被作为垃圾邮件过滤掉、提升邮件送达稳定性、追踪邮件送达状况。

大多数邮件服务商都支持每天免费发200封邮件:Mandrill by MailChimpSendGridMailgunAmazon Simple Email ServiceElastic EmailCritSendMailjetMessageGearsturboSMTPPostageAppPostmark

ActionMailer

Rails在config/environments目录下针对不同执行环境会有不同的邮件服务器设定。在development.rb开发模式中,以下设定会忽略任何寄信的错误:

# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false

建议可以改成true,这样可以提早发现错误。

寄信方式的选项包括有:test:sendmailsmtp三种可以选择。sendmail是使用服务器的/usr/bin/sendmail程式,不过因为因为不是每台服务器都有适当安装sendmail。而:test代表并不会实际寄信出去,而是存在ActionMailer::Base.deliveries阵列中方便做自动化测试。

最推荐的方式是采用:smtp协定来实际寄信出去,例如以下是一个使用Gmail寄信的范例,需要同时配置应用和邮件服务商才能生效。

  • 配置Devise
    假如你有使用Devise的confirmable模块来发验证邮件,修改下面的文件,填写你的发件人邮件地址:config/initializers/devise.rb

    config.mailer_sender = "sender@yourwebsite.com"
    
  • 配置ActionMailer
    修改production环境里面的文件,填入如下代码,注意把default_url改成你自己的网站:config/environments/production.rb

    config.action_mailer.default_url_options = { :host => 'yourwebsite.com' }
    # ActionMailer Config
    # Setup for production - deliveries, no errors raised
    config.action_mailer.delivery_method = :smtp
    config.action_mailer.perform_deliveries = true
    config.action_mailer.raise_delivery_errors = false
    config.action_mailer.default :charset => "utf-8"
    

修改下面的文件,填写你的发件人邮件地址:app/mailers/application_mailer.rb

class ApplicationMailer < ActionMailer::Base
default from: "sender@yourwebsite.com"
layout "mailer"
end
  • 配置邮件服务商
    实现SMTP转发功能。修改production环境里面的文件,先创建Gmail帐号和密码:config/environments/production.rb

    config.action_mailer.smtp_settings = {
      address: "smtp.gmail.com",
      port: 587,
      domain: "example.com",
      authentication: "plain",
      enable_starttls_auto: true,
      user_name: ENV["GMAIL_USERNAME"],
      password: ENV["GMAIL_PASSWORD"]
    }
    
    config.action_mailer.smtp_settings = {
      address: "smtp.sendgrid.net",
      port: 25,
      domain: "heroku.com",
      authentication: "plain",
      enable_starttls_auto: true,
      user_name: ENV["SENDGRID_USERNAME"],
      password: ENV["SENDGRID_PASSWORD"]
    }
    
    config.action_mailer.smtp_settings = {
      :address   => "smtp.mandrillapp.com",
      :port      => 25,
      :user_name => ENV["MANDRILL_USERNAME"],
      :password  => ENV["MANDRILL_API_KEY"]
    }
    

另外实际上,我们其实并不会将帐号密码写死进代码里面,而是希望拆出来另存一个设定档。例如我们可以放到config/email.yml如下,YAML第一层是适用的Rails环境:

development:
  address: "smtp.gmail.com"
  port: 587
  domain: "gmail.com"
  authentication: "plain"
  user_name: "example@gmail.com"
  password: "123456"
  enable_starttls_auto: true
production:
  address: "smtp.mailgun.org"
  port: 587
  domain: "ihower.com"
  authentication: "plain"
  user_name: "postmaster@ihower.tw"
  password: "1234567890"
  enable_starttls_auto: true

这样的话,smtp_settings就可以改成:

config.action_mailer.smtp_settings = config_for(:email).symbolize_keys

其中config_for这个方法根据当时Rails启动环境会读取config目录下的YAML。而symbolize_keys这个方法会将Hash中的String key换成Symbol key,这是因为smtp_settings使用的值是Symbol key,如果没有转的话,会读不到设定。

通常config/email.yml会加到.gitignore列表中,因为有帐号密码在里面。

2. Mailing list

对所有列表用户发送的新闻或通知等。上面提到的SMTP转发服务比如SendGrid通常只提供基本的转发服务,这时候需要更加专业的邮件服务来实现群发功能、管理未订阅者、管理不同的邮件模版等。

群发邮件需要注意一下几点:

  • 处理退信

如果你寄出去的email由于某些理由(地址不对,对方邮箱满了等)而被对方的 mail server 退回,这些 email 需要进行处理。如果忽略它一直寄信,可能会被当成发送垃圾邮件的邮箱,被列入到黑名单中。

  • 建立自己的 email 清单

  • 不要使用100%以图片为主的内容
    减少图片的使用,Gmail 预设是不会读取图片的,重要的信息使用图片发送可能会让收件者收不到,全部都是图片的 email 也容易被当成垃圾邮件。

  • 使用垃圾邮件检测工作
    收邮件的 mail server 通常会使用 Spam Assassin 等工具来判断是否是垃圾邮件,自己也应该使用这类工具检查自己发送的邮件是否有可能被判定为垃圾邮件。如果分数太低,可以参考这篇文章

  • 验证HTML
    如果寄出的 email 是HTML格式的,应该检查格式是否正确。错误的格式也容易被当成垃圾邮件。

  • 模拟使用者环境
    使用不同的email client实际测试。不同的client会有不同的结果。验证是否能收到邮件。

  • 专属IP
    是否和别人共用email server,如果别人被拉入黑名单,那么你也被列入黑名单。

  • 验证寄信人地址
    email服务商会先检查寄件人的地址是否正确,才会收信,所以要保证email地址是正确的。

  • 设定 Reverse DNS 反查
    设定反向查询的DNS记录,如果你寄信的IP无法反查,可能根本寄不到。

  • 设定SPF Validation
    SPF (Sender Policy Framework) 是一个 email协议来确认 return-path address的正确性,用来防止垃圾信件。设定 SPF可以改进信件发送的成功率,特别是MSN。

  • 设定 Domain Keys Verification
    Domain Keys 验证是另一种防止垃圾信件的协议。

综上,我们还是使用专业的邮件服务商来发送群发邮件,可以选择以下邮件服务商:MailChimpMadMimiCampaignMonitorConstant ContactYMLPJangoMailiContactVerticalResponse

3. Company Email

用你的公司邮箱给供应商、客户、同事等发邮件,可以用Gmail解决掉这个问题,设置Gmail代收公司邮箱,然后用Gmail回复时,再选择从不同地址发送邮件。当然你也可以选择更专业版的Google Apps for Business