RubyRuby on Rails程序员

rails如何用action_mailer发送邮件

2017-09-26  本文已影响91人  程序员小哥哥

一:

1.在命令上敲命令

rails g mailer NoticeMailer

这里主要会生成app/mailer/application_mailer.rb和app/mailer/notice_mailer.rb文件

#这里的关键点是继承了ActionMailer::Base
class ApplicationMailer < ActionMailer::Base

备注:这里以163邮箱为例,只针对于163邮箱之间的互相发送邮件。

2.在163邮箱上开通smtp服务

SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转发出的电子邮件
它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。跟大多数应用层协议一样,SMTP也存在两个 端:在发信人的邮件服务器上执行的客户端和在收信人的邮件服务器上执行的服务器端。SMTP的客户端和服务器端同时运行在每个邮件服务器上。当一个邮件服 务器在向其他邮件服务器发送邮件消息时,它是作为SMTP客户在运行。
SMTP协议与人们用于面对面交互的礼仪之间有许多相似之处。首先,运行在发送端邮件服务器主机上的SMTP客户,发起建立一个到运行在接收端邮件服务 器主机上的SMTP服务器端口号25之间的TCP连接。如果接收邮件服务器当前不在工作,SMTP客户就等待一段时间后再尝试建立该连接。SMTP客户和服务器先执行一些应用层握手操作。就像人们在转手东西之前往往先自我介绍那样,SMTP客户和服务器也在传送信息之前先自我介绍一下。 在这个SMTP握手阶段,SMTP客户向服务器分别指出发信人和收信人的电子邮件地址。彼此自我介绍完毕之后,客户发出邮件消息。

备注:以上来自百度百科

2.1

点击设置->选择POP3/SMTP/IMAP

2.2

勾选POP3/SMTP服务

备注:这里会让你设置个密码,记住它,在配置文件中会用到

3.修改在config/environments//$RAILS_ENV.rb

  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.perform_caching = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.163.com',
    port:                 "25",
    domain:               '163.com',
    user_name:           '你的邮箱地址', #比如我的是:'sai@163.com'
    password:             '邮箱密码', #比如我的邮箱密码:'bugaosuni'
    authentication:       :plain,
    enable_starttls_auto: true
  }

4.修改app/mailer/notice_mailer.rb文件

class NoticeMailer < ApplicationMailer
  default to: 'sai1@163.com', from: "sai2@163.com"

  #如果想发送给多个人,这样定义
  #default to: ['sai1@163.com', 'i__am__sai@163.com'], from: "sai2@163.com"

  def send_mail(body, subject)
    mail(body: body, subject: subject)
  end
end

5.在app/views/notice_mailer增加send_mail.erb文件写入你想说的话

<h1>我是无聊才给你发的</h1>
<h2>我是Sai</h2>
<h3>随时欢迎你给我发呀</h3>

要不就会出现下面的报错信息

action_mailer..png

6.然后在你想要发送的controller方法中调用即可

#deliver:立即发送
NoticeMailer.send_mail.deliver

参考文档

英文版:http://guides.rubyonrails.org/action_mailer_basics.html

(还是看中文版吧)
中文版:https://rails.guide/book/action_mailer_basics.html#action-mailer-basics

-------------------------人工分割线-------------------------

后续优化todo (2017-09-27)

最后把邮件放在队列中,sidekiq会从redis中来取,这样就不会影响正常的逻辑处理。
我这里创建了一个worker

class SendMailWorker
  include Sidekiq::Worker
  sidekiq_options :queue => :send_mail, retry: 3

  sidekiq_retries_exhausted do |msg|
    Sidekiq.logger.warn "Failed #{msg['class']} with #{msg['args']}: #{msg['error_message']}"
  end

  def perform(body_info, notice_type)
    NoticeMailer.send_mail(body_info, notice_type).deliver_now
  end
end

后来发现在action_mailer里本身就有这个方法 -> deliver_later
把sidekiq删除,把deliver_now/deliver更改成deliver_later就行了

NoticeMailer.send_mail.deliver_later

Active Job 的默认行为是通过 :async 适配器执行作业。因此,这里可以使用 deliver_later,异步发送电子邮件。 Active Job 的默认适配器在一个进程内线程池里运行作业。这一行为特别适合开发和测试环境,因为无需额外的基础设施,但是不适合在生产环境中使用,因为重启服务器后,待执行的作业会被丢弃。如果需要持久性后端,要使用支持持久后端的 Active Job 适配器(Sidekiq、Resque,等等)。
如果想立即发送电子邮件(例如,使用 cronjob),调用 deliver_now 即可.

2.放在我项目之后139、qq邮箱也要支持发送,这里我换成了阿里的企业邮箱可以了,配置如下,这里不在纠结了。

 #action_mailer配置
  config.action_mailer.raise_delivery_errors = true
  #config.action_mailer.perform_caching = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address:              'smtp.mxhichina.com',
    port:                 "25",
    domain:               'qiye.aliyun.com',
    user_name:           'xxx@nideqiyemingzi.com',
    password:             'zenmekenenggaosuni',
    authentication:       :login
  }
上一篇下一篇

猜你喜欢

热点阅读