Railsで送信メールの開封を検知する

はじめに

イタンジ株式会社の赤松です。業者間サイトITANDI BBの開発を担当しています。
Railsでメールを送信して、そのメールが開封されたか知りたい時があるのではないでしょうか?
本記事では、送信メールの開封を検知する方法をご紹介します!

背景

現在メール配信機能を開発しているのですが、配信の効果測定を行うために開封率を取得する必要が出てきました。
今回はRailsで開封を検知するということになり、早速着手してみました。

解決方法

方法は簡単で、まずはメールの末尾に画像を設置し、この画像が読み込まれたら開封検知のURlにアクセスが行くようにします。
その後、Controller内で対象の開封情報を更新し透明な画像を返します。
メール上では透明な画像が表示されるのでユーザーには気づかれません。
これで終わりです!

下記で具体的なやり方を見ていきましょう。

1. URLを埋め込んだimgをメールの末尾に配置する

image_tag(url, size: '1x1', alt: nil)
  • image_tagのsrcにurlを入れることで、画像の読み込み時にそのurlにアクセスが行きます。
  • urlは2の開封処理へのリンクを記載してください。
  • 目立たせたくないので、サイズは最小の1ピクセルにしておくといいです。

※ 注意点として、HTMLメールにしかimgを埋め込むことができず、TEXTメールでは開封を検知できないです。

2. メール開封時の処理を記述する

def opened
  〇〇.find(params[:id]).update(opened: true)

  send_file Rails.root.join('app/assets/images/□□.png’), type: 'image/png', disposition: 'inline'
end
  • 開封情報を持つテーブルのカラムを更新し画像を返します。
  • □□.pngは透明な画像を配置してください。
  • 「透明画像 作成」とGoogleで検索すれば簡単に作成できるツールがあります。

余談

HTMLのメールテンプレートに直接記述せず、動的にimgを埋め込みたいときがあるかと思います。
その時は、下記のような処理をApllicationMailerに記載するといいです。

def add_open_tracking_image(mail, url)
  mail.all_parts.each do |part|
    if part.content_type.include?('html')
      part.body.raw_source <<
        ActionController::Base.helpers.image_tag(url, size: '1x1', alt: nil)     
    end
  end
end

こちらの処理では、HTMLメールのみ末尾に画像を埋め込みます。
引数のmailはMail::Messageインスタンスで、メールの送信先や本文などの情報を持ちます。
このメソッドを各mailerの処理に追記することで、動的に対応することができます!

終わりに

以上、Railsで送信メールの開封の有無を調べる方法を簡単にまとめてみました。
この記事をご覧の方の開発の一助になれば幸いです。それでは!