action mailbox
Action Mailer Basics和Action Mailbox Basics:邮件系统。
https://edgeguides.rubyonrails.org/action_mailbox_basics.html#exim
https://edgeguides.rubyonrails.org/action_mailer_basics.html
案例:
//在rails6 app分支 10238 rails action_mailbox:install //会生成一个app/mailboxes/application_mailbox.rb
//同时生成3个数据库table
10240 rails g scaffold User email name 10241 rails g scaffold Discussion title 10242 rails g scaffold Comment user:references discussion:references body:text 10243 rails db:migrate 10245 rails g mailbox Replies
上面代码使用rails6的新特性:action mailbox。它用于导航接收的email给控制器mailboxes。
它可以使用Postmark等常见API库。也可以直接通过它内建的Exim等APi来处理接收的email。
接收的email,通过使用action job来异步导航到一个或多个指定的mailboxes。
使用方法
安装-》配置api-》生成一个mailbox-》使用。具体见
继续:
class ApplicationMailbox < ActionMailbox::Base # routing /something/i => :somewhere routing /reply\+.+@reply.github.com/i => :replies routing :all => :replies end
routing方法,指定不同的邮件到特定的mailbox中。本例所有的邮件都被RepliesMailbox类进行处理。
⚠️一个方便的转化ruby 正则表达式语法网站:https://rubular.com/
继续:
在replies_mailbox.rb内编写方法。
mailbox集成了mail这个model。一个Ruby Mail Library.
https://github.com/mikel/mail/
提供了生成,转化,发送的一系列方法。
在gemfile.lock中可见:
actionmailbox (6.0.0.rc1)
...
mail (>= 2.7.1)
class RepliesMailbox < ApplicationMailbox MATCHER = /reply-(.+)@reply.example.com/i # mail => Mail object # inbound_email => ActionMailbox::InboundEmail record #before_processing :ensure_user def process return if user.nil? discussion.comments.create( user: user, # decoded方法返回对象的值(格式是string),即返回的是body,不是subject body: mail.decoded ) end def user @user ||= User.find_by(email: mail.from) end def discussion @discussion ||= Discussion.find(discussion_id) end # recipients是mail的方法,find{}进行匹配找到第一个符合的data。
# recipients可以用to方法代替。
# recipient是一个string, 使用[Regexp, 1]得到捕捉到的字符。具体见正则表达式的捕捉() def discussion_id recipient = mail.recipients.find{|r| MATCHER.match?(r) } recipient[MATCHER, 1] end private def ensure_user if user.nil? bounce_with UserMailer.missing(inbound_email) end end
class ApplicationMailbox < ActionMailbox::Base # routing /something/i => :somewhere # routing /reply\+.+@reply.github.com/i => :replies # routing :all => :replies routing RepliesMailbox::MATCHER => :replies end
然后添加user和discussion2条记录。
在discussions/show.html.erb增加下面的代码:
... <h4>Comments</h4> <div>
<% @discussions.comments.each do |comment| %> <strong><%= comment.user.name%></strong> commented:<br/> <%= simple_format comment.body%>
<% end %> </div>
完成!
测试
进入http://localhost:3000/rails/conductor/action_mailbox/inbound_emails
点击Deliver new inbound email链接,选择发送一封
这是source:
Date: Fri, 24 May 2019 11:30:37 +0800 From: 1@1.com To: reply-1@reply.example.com Message-ID: <5ce7655da43ed_c653feae01b5b9c714c@chentianweideiMac.local.mail> In-Reply-To: Subject: congratulations Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit hello boy!