Rails使用Mailgun發郵件的幾個方式

1.使用Rails內建的Action Mailer

因為Rails有內建Action Mailer,所以這個方法比較直接,只要更改Action Mailer的smtp設定

# enviroments/production.rb 或是 enviroments/development.rb 加上

ActionMailer::Base.smtp_settings = 
  { :port => 587, 
    :address => 'smtp.mailgun.org',  
    :user_name => '[email protected]', 
    :password => 'mailgun-smtp-password', 
    :domain => 'your.mailgun.domain', 
    :authentication => :plain }

ActionMailer::Base.delivery_method = :smtp 

再來新增 mailers/user_mailer.rb

# mailers/user_mailer.rb

class UserMailer < ActionMailer::Base 
  default from: " [email protected]"
  def confirm(email, params)
    @customer_name = params[:customer_name]
    @customer_phone = params[:customer_phone]
    @customer_email = params[:customer_email]
    @content = params[:content]
    @website_name = params[:website_name]

    mail to: email, subject: "ELIVING 客戶留言通知信"
  end
end 

再來在views/user_mailer/confirm.text.erb編輯郵件的template

假設為:

HI <%= @website_name %> 您好,有客戶在您的網站留言

相關資訊如下:

* * *

客戶名稱 / <%= @customer_name %>

聯絡電話 / <%= @customer_phone %>

電子郵件 / <%= @customer_email %>

服務內容 / <%= @content %>

* * *

如此要發送郵件時只要在controller裡面呼叫:

UserMailer.confirm(@website.email, inquiry_params).deliver

2.使用mail gem

這個也是使用smtp的方法,只是不使用Rails內建的Action Mailer

首先Gemgile加上 gem ‘mail’,然後bundle安裝

在 enviroments/production.rb 或是 enviroments/development.rb 加上

# enviroments/production.rb 或 enviroments/development.rb
Mail.defaults do
  delivery_method :smtp, {
    :port      => 587,
    :address   => "smtp.mailgun.com",
    :user_name => "",
    :password  => "",
  }
end

在controller呼叫以下指令,就可以發送mail了

mail = Mail.deliver do to '[email protected]' from '[email protected]' subject 'Hello'
  text_part do
    body 'Testing some Mailgun awesomness'
  end
end

3.使用mailgun gem

這個是使用mailgun的gem去直接呼叫mailgun的api

首先Gemgile加上 gem ‘mailgun’,然後bundle安裝

在 enviroments/production.rb 或是 enviroments/development.rb 加上

# enviroments/production.rb 或 enviroments/development.rb
# Initialize your Mailgun object:
Mailgun.configure do |config|
  config.api_key = 'your-api-key'
  config.domain  = 'your-mailgun-domain'
end

在controller呼叫以下指令,就可以發送mail了

@mailgun = Mailgun()

parameters = 
{ :to => "[email protected]", 
  :subject => "missing tps reports", 
  :text => "yeah, we're gonna need you to come in on friday...yeah.", 
  :from => "[email protected]" }

@mailgun.messages.send_email(parameters)

4.使用rest-client gem

這個是使用rest-client去呼叫mailgun api

首先Gemgile加上 gem ‘rest-client’,然後bundle安裝

然後在要發送的controller執行以下指令

RestClient.post 
"https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"
"@api.mailgun.net/v2/samples.mailgun.org/messages",
:from => "Excited User <[email protected]>",
:to => "[email protected], [email protected]",
:subject => "Hello",
:text => "Testing some Mailgun awesomness!"

只是要記得將 api:後面的key換成自己的 還有將samples.mailgun.org換成自己的domain

參考資料:

https://github.com/HashNuke/mailgun http://documentation.mailgun.com/quickstart-sending.html

Rails 使用 Sidekiq 背景處理工作

先安裝redis

Mac的話執行以下指令

brew install redis

再來啟動 redis, commamd line 執行

redis-server

啟動後如圖:

螢幕快照 2014-07-07 下午7.12.20.png

安裝 sidekiq

先在Gemfile加上

#Gemfile
gem 'sidekiq'

執行

bundle install

執行sidekiq

bundle exec sidekiq

啟動後如圖:

螢幕快照 2014-07-07 下午7.11.09.png

理論上 這個都正常運作的話,大致上就沒什麼問題了

執行sidekiqe工作

新增 app/workers/ 資料夾, 可以將要執行背景工作的class都放在這裡

假設要做一個Email發信的工作

#/app/workers/mail_sender.rb

class MailSender include Sidekiq::Worker
  def perform(mail_id)
      mail = @mail.find(mail_id)
      # ..
        這裡執行發送的工作
      # ..
  end
end 

在 Controller或是model,可以呼叫以下方法發送程式

MailSender.perform_aysnc(mail_id) # 呼叫perform這個class method但是記得多加上 _async 

4.安裝sidekiq監控界面

sidekiq 提供一個界面可以讓管理者觀看,目前的背景工作的情況,和統計圖表

安裝方法:

在Gemfile加上

gem 'sinatra', require: false
gem 'slim'` 然後 bundle 安裝

然後 記得在route.rb加上

require 'sidekiq/web'
# ...
mount Sidekiq::Web, at: '/sidekiq'

如此只要在您的網站打上

http://[yourdomain_address]/sidekiq

就可進入此界面,圖如下

Sidekiq.png

但是由於安全性的問題, 如果要限定管理員才能查看此頁面呢? 如果有使用devise,且user model 是存放使用者資料的地方 另外如果user model的admin回傳是true的是管理員的話

可以改為如下,如此就只有有認證過的使用者,且是管理員才能觀看/sidekiq

#routes.rb

authenticate :user, lambda { |u| u.admin? } do  
  mount Sidekiq::Web => '/sidekiq'
end

http://sidekiq.org/
http://railscasts.com/episodes/366-sidekiq
http://redis.io/topics/quickstart
http://blog.remarkablelabs.com/2013/01/using-sidekiq-to-send-emails-asynchronously
http://rubyist.marsz.tw/blog/2013-06-08/sidekiq/
https://github.com/mperham/sidekiq/wiki