Xây dựng Hệ Thống Email Toàn Diện với Mailgun: Hướng Dẫn Chi Tiết

Mailgun là một nền tảng API mạnh mẽ, hỗ trợ bạn gửi, nhận và quản lý email hiệu quả. Bài viết này sẽ hướng dẫn bạn xây dựng một hệ thống email nội bộ, tận dụng tối đa các tính năng mà Mailgun cung cấp, giúp bạn kiểm soát và quản lý email một cách chủ động.

I. Thiết Lập Tài Khoản và Cấu Hình Mailgun

Để bắt đầu, bạn cần tạo một tài khoản Mailgun. Truy cập trang đăng ký của Mailgun và điền đầy đủ thông tin. Sau khi hoàn tất, Mailgun sẽ gửi email xác nhận đến địa chỉ bạn đã cung cấp. Hãy kiểm tra hộp thư và làm theo hướng dẫn để kích hoạt tài khoản.

Giao diện trang đăng ký MailgunGiao diện trang đăng ký Mailgun

Sau khi kích hoạt và đăng nhập, bạn sẽ được chuyển đến trang quản trị Mailgun. Mặc định, Mailgun cung cấp một domain miễn phí để bạn thử nghiệm trong quá trình phát triển. Nếu bạn đã có server SMTP riêng, bạn có thể tạo mới hoặc thay thế domain mặc định này. Việc sử dụng domain riêng giúp tăng độ tin cậy và khả năng gửi email thành công.

Hệ thống email mà chúng ta xây dựng sẽ lưu trữ toàn bộ email gửi đi và nhận về từ các hệ thống khác. Việc lưu trữ email gửi đi khá đơn giản, chỉ cần tạo một bản ghi mới trong bảng email. Tuy nhiên, việc lưu trữ email nhận về từ bên ngoài phức tạp hơn. Mailgun Routes sẽ giúp bạn giải quyết vấn đề này. Mỗi Route hoạt động như một bộ lọc, có chức năng chuyển tiếp email nhận được đến một địa chỉ email hoặc URL cụ thể, hoặc bỏ qua nếu bạn xác định đó là email không mong muốn.

Giao diện Mailgun RoutesGiao diện Mailgun Routes

Để tạo một Route mới, truy cập trang quản lý Routes của Mailgun. Tại đây, bạn cần chú ý đến 3 trường quan trọng:

  • Expression Type: Xác định điều kiện để lọc email. Ví dụ: lọc theo địa chỉ người gửi, tiêu đề, hoặc nội dung email.
  • Actions: Xác định hành động cần thực hiện khi email thỏa mãn điều kiện lọc. Thông thường, email sẽ được chuyển tiếp (Forward) đến URL bạn chỉ định.
  • Priority: Xác định thứ tự ưu tiên khi có nhiều Route và một email thỏa mãn nhiều điều kiện lọc khác nhau.

Với cấu hình này, bạn đã hoàn thành việc thiết lập Mailgun. Bước tiếp theo là xây dựng hệ thống email của riêng bạn.

II. Xây Dựng Hệ Thống Email

Trong phần này, chúng ta sẽ sử dụng framework Ruby on Rails để minh họa cách xây dựng hệ thống email. Bạn có thể áp dụng tương tự với các ngôn ngữ và framework khác.

1. Lưu Trữ Email

Đầu tiên, bạn cần tạo một bảng (table) trong cơ sở dữ liệu để lưu trữ email. Bảng này nên có các trường như:

  • to: Địa chỉ người nhận
  • cc: Địa chỉ người nhận CC
  • bcc: Địa chỉ người nhận BCC
  • subject: Tiêu đề email
  • body: Nội dung email
  • from: Địa chỉ người gửi
  • sent_at: Thời gian gửi

Các trường này có thể thay đổi tùy theo yêu cầu cụ thể của hệ thống, nhưng cần đảm bảo tính bảo mật và khả năng xác định người gửi, người nhận và loại email.

Mỗi người dùng trong hệ thống nên có một địa chỉ email riêng, ví dụ: [email protected]. Hãy chắc chắn rằng bạn đã đăng ký domain của mình trong phần Domain của Mailgun.

2. Gửi Email Qua Mailgun

Mặc định, ActionMailer của Rails sử dụng deliver_method:smtp. Để sử dụng Mailgun, bạn cần chỉnh sửa cấu hình như sau:

config.action_mailer.delivery_method = :mailgun
config.action_mailer.mailgun_settings = {
  api_key: ENV["MAILGUN_API_KEY"],
  domain: ENV["MAILGUN_DOMAIN"]
}

Trong đó:

  • MAILGUN_API_KEY: API Key của bạn trên Mailgun.
  • MAILGUN_DOMAIN: Domain bạn đã đăng ký trên Mailgun.

Để thuận tiện cho việc gửi và lưu trữ email, bạn có thể tạo một class UserMailer để thực hiện công việc này:

class UserMailer < ActionMailer::Base
  def send_mail(email)
    mail to: email.to, subject: email.subject, body: email.body
    email.save # Lưu email vào database
  end
end

Khi người dùng muốn gửi email, bạn tạo một object email tương ứng với các thông tin cần thiết, sau đó sử dụng UserMailer.send_mail(email) để gửi email và lưu lại thông tin vào database.

3. Nhận Email Vào Hệ Thống

Khi có một email gửi đến địa chỉ có dạng [email protected], Mailgun sẽ bắt được nó thông qua bộ lọc (Route) bạn đã thiết lập. Sau đó, Mailgun sẽ thực hiện các hành động tương ứng, trong trường hợp này là chuyển tiếp email đến một URL trỏ đến một controller bạn đã xác định trước. Tại đây, email sẽ được xử lý và lưu vào database.

Để kiểm thử trong quá trình phát triển, bạn có thể sử dụng ngrok để public địa chỉ local ra bên ngoài. Địa chỉ này thường có dạng https://your-ngrok-subdomain.ngrok.io. Kết hợp với domain mặc định của Mailgun (ví dụ: sandbox123.mailgun.org), bạn có thể dùng email cá nhân để gửi email đến địa chỉ bất kỳ, ví dụ [email protected].

Sau khi nhận được email, Mailgun sẽ tạo một request với method POST đến URL bạn đã định nghĩa.

Thông tin POST request từ MailgunThông tin POST request từ Mailgun

Ví dụ, nếu bạn muốn Mailgun gửi request đến EmailsController, bạn cần cấu hình URL trong phần Forwards của Route là https://your-ngrok-subdomain.ngrok.io/emails.

Trong EmailsController, bạn có thể xử lý request như sau:

class EmailsController < ApplicationController
  def create
    ReceiveEmailFromMailgun.new(params).perform
  end
end

Service ReceiveEmailFromMailgun sẽ có nhiệm vụ xử lý các params được gửi từ Mailgun và lưu email vào hệ thống.

class ReceiveEmailFromMailgun
  def initialize(params)
    @params = params
  end

  def perform
    ActiveRecord::Base.transaction do
      users.each { |user| clone_email user }
    end
    true
  rescue false
  end

  private

  attr_reader :params

  def clone_email(user)
    email = Email.new(email_params(user))
    if email.valid?
      email.save!
      save_attachments(email) if attachments?
    else
      raise ActiveRecord::Invalid
    end
  end

  def users
    @users ||= User.where(email: email_to)
  end

  def email_to
    params[:recipient].split(",").map(&:strip)
  end

  def email_cc
    return unless params[:Cc].present?
    params[:Cc].split(",").map { |email| email.match(/<(.+)>/)&.captures&.first }.compact
  end

  def attachments?
    !params.keys.select { |key| key =~ /attachment-[0-9]*/ }.empty?
  end

  def save_attachments(email)
    params.keys.select { |key| key =~ /attachment-[0-9]*/ }.each do |key|
      attachment = params[key]
      email.attachments.attach(io: StringIO.new(attachment.read), filename: attachment.original_filename)
    end
  end

  def email_params(user)
    {
      to: [user.email],
      cc: email_cc,
      from: params[:sender],
      subject: params[:subject],
      body: params["body-plain"],
      sent_at: params[:Date]
    }
  end
end

Các trường trong params mà Mailgun gửi về được mô tả chi tiết trong tài liệu của Mailgun. Dựa vào đó, bạn có thể lấy ra những thông tin cần thiết. Service ReceiveEmailFromMailgun sẽ lấy ra mảng địa chỉ to, cc và attachments. Từ địa chỉ tocc, bạn có thể xác định email này gửi cho user nào. Sau đó, bạn lưu email tương ứng với từng user. Việc lưu trữ attachments cũng rất quan trọng, bạn cần đảm bảo các file được lưu trữ an toàn và có thể truy xuất sau này.

III. Kết luận

Bài viết đã hướng dẫn bạn cách sử dụng Mailgun để xây dựng hệ thống gửi và nhận email cho riêng mình. Tùy thuộc vào chức năng và yêu cầu của từng hệ thống, cấu trúc và phương pháp sử dụng có thể khác nhau. Mailgun cung cấp rất nhiều chức năng mạnh mẽ, bài viết này chỉ giới thiệu một số trong số đó. Hy vọng bài viết hữu ích khi bạn cần xây dựng một hệ thống email mà bạn có thể chủ động quản lý.