Action Mailer trong Rails

Gửi email là một tính năng gần như không thể thiếu ở bất kỳ trang web hiện đại nào hiện nay. Rails là một framework giúp tạo ra những ứng dụng web hiện đại, đầy đủ tính năng, vì vậy, việc gửi email cũng được Rails hỗ trợ rất tốt, thông qua Action Mailer. Ở bài này, mình sẽ nói qua về cách tạo một Action Mailer, cấu hình Action Mailer để nó hoạt động như cách chúng ta muốn. Let's go!

1. Gửi Email

1. Tạo Mailer

Để bắt đầu gửi email với Action Mailer, bạn chạy generator sau để tạo Mailer:

bin/rails generate mailer UserMailer

Sau khi chạy xong generator, bạn sẽ thấy các files do Mailer generator sinh ra có khá nhiều điểm tuơng đồng với Controller generator: chúng ta cũng lần lượt có mailer, thư mục views, và các test files.

2. Edit Mailer

Như đã đề cập ở trên, Mailer có nhiều điểm tuơng đồng với Controller, Mailer cũng có những actions, cũng có các views để render ra nội dung. Điểm khác nhau ở đây là Controller sẽ tạo ra các file HTML để gửi cho client, còn Mailer sẽ tạo ra các tin nhắn để có thể gửi qua email.

Giờ hãy mở file app/mailers/user_mailer và điền thử những thông tin như dưới đây, mình sẽ giải thích sau:

class UserMailer < ApplicationMailer
  default from: '[email protected]'
 
  def welcome_email user
    @user = user
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end
end

Trong đó:

default

Chứa một hash các giá trị mặc định mà tất cả các email nhận được từ bạn. Trong trừong hợp này, chúng ta đã cài đặt để :from header luôn luôn có giá trị là [email protected] cho mọi messages sẽ được gửi đi trong file này.

Còn

  def welcome_email user
    @user = user
    @url  = 'http://example.com/login'
    mail(to: @user.email, subject: 'Welcome to My Awesome Site')
  end

là 1 method, tương tự actions trong Controller, trong đó mail(...) sẽ chính là nội dung được gửi đi. Method này nhận 2 giá trị là to-để chỉ định địa chỉ sẽ được gửi đến và subject-nội dung của subject thư. Có một điểm lưu ý nhỏ ở đây, là tuơng tự với Controller (nhiều tuơng tự quá đi 😄), đó là các instance variables được định nghĩa trong mailer sẽ có thể truy cập trên view.

3. Tạo Mailer View

Các bạn tạo file welcome_email.html.erb trong thư mục app/views/user_mailer. File này chính là template sẽ được sử dụng cho email. Nội dung file này tùy thích:


<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hi,  <%= @user.name %></h1>
    <p>
     You're now a member, with username is your choice: <%= @user.login %>.<br>
    </p>
    <p>
      To login to the site, just follow this link: <%= @url %>
  </body>
</html>

Với những user thích đọc email dưới dạng text, ta tạo file welcome_email.text.erb ở chung thư mục với file welcome_email.html.erb ở trên:


Hi, <%= @user.name %>
===============================================
 
You're now a member, with username is your choice: <%= @user.login %>.
 
To login to the site, just follow this link: <%= @url %>.

4. Gọi Mailer:

Với Controller, views được generate và gửi cho clients thông qua giao thức HTTP, với Mailer, views cũng được generate, nhưng được gửi qua các giao thức email. Vì vậy, logic đơn giản để có thể sử dụng mailer là gọi mailer trong controller khi người dùng đã đăng kí thành công. Chúng ta sử dụng scaffold để nhanh chóng tạo model, view, controller cho User:

$ bin/rails generate scaffold user name email login
$ bin/rails db:migrate

Sau khi tạo xong, ta vào app/controllers/uses_controller.rb để bắt đầu "nghịch" với Mailer: như đã bàn ở trên, khi người dùng đăng kí thành công, đồng nghĩa với việc UserController tạo mới người dùng thành công, ta sẽ gọi ActionMailer để gửi email cho người dùng đó:


class UsersController < ApplicationController
  def create
    @user = User.new params[:user]
    if @user.save
        UserMailer.welcome_email(@user).deliver_later
    end
  end
end

Rất dễ hiểu, tuy nhiên, có 1 điểm cần lưu ý ở đây, đó là deliver_later. deliver_later được chạy một cách bất đồng bộ. Khi sử dụng hàm này, email không đựoc gửi ngay khi hàm được gọi, thay vào đó, nó sẽ được đẩy vào job's queue. Trong trường hợp bạn muốn gửi email ngay lập tức, có thể dùng deliver_now, nó sẽ không sử dụng ActiveJob. Để đọc thêm về Active Job, bạn có thể vào đây: ActiveJob

5. Gmail Configuration

Về cơ bản thì chúng ta đã chuẩn bị xong, còn một bước cuối cùng để có thể làm cho ứng dụng thực sử gửi được email tới hòm thư gmail, đó là config trong /config/environments/development.rb, các bạn mở file ra và config như sau:

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  address: 'smtp.gmail.com',
  port: 587,
  domain:  'example.com',
  user_name: '<username>',
  password:  '<password>',
  authentication: 'plain',
  enable_starttls_auto: true  
}

vậy là xong 😄

Qua bài bài, mình đã đưa ra các bước làm giúp bạn có thể tạo ra 1 ActionMailer thực sự hoạt động một cách cơ bản nhất. Tất nhiên, còn rất nhiều những tính năng cao cấp khác của ActionMailer mà mình chưa thể đưa ra hết ở đây, như tự động sinh ra URL cho ActionMailer Views, đính kèm file,.. Nhưng với những kiến thức ở trong bài viết này, mình nghĩ các bạn hoàn toàn có thể sử dụng và tìm hiểu, khai thác được tối đa những tính năng đó một cách không quá khó khăn.

Chúc các bạn thành công!