Railsでメール送信プログラムを作るとき、Gmailを利用して手軽にSMTP送信することができます。
- Googleでアプリパスワードを取得
- 環境設定ファイルに通信設定を記述
- メーラー(Mailer)を作成
- コントローラー(Controller)で送信するよう記述
- メールのテンプレートを作成
で簡単に実装することが可能です。
【実行環境】
Rails 6.1.4
Ruby 2.5.3
Googleでアプリパスワードを取得
Gmailを利用してSMTPでメールを送るためには、まずGoogleアカウントにてアプリパスワードを発行する必要があります。
Googleのアカウントページから「セキュリティ」を選択。
2段階認証が設定されていない場合は、まず2段階認証をオンにしてください。
その上で「アプリパスワード」欄をクリック。
ログインが求められるので、画面の案内に沿ってIDやパスワードを入力して進んでください。
「アプリを選択」欄で「その他(名前を入力)」を選びます。
アプリ名を入力します。
これはなんでも構わないので、自分がわかりやすい名前でOKです。
入力後「生成」ボタンを押すと、画面にアルファベット16桁のパスワードが表示されます。
あとでこのパスワードは使いますが、一度画面を閉じてしまうと再確認が難しいので必ず控えておくといいです。
ただし、パスワードが流出すると第三者からGoogleのアカウントを自由に使われてしまうので、取り扱いには十分に注意してください。
環境設定ファイルに通信設定を記述
Rails側で通信ができるように設定を記述していきます。
config/environments/
以下に環境ごとの設定を記述するファイルがあるので、環境に応じたものを選びます。
例えば、開発環境からメール送信が行えるようにしたい場合、config/environments/development.rb
が適切です。
開発環境:development.rb
テスト環境:test.rb
本番環境:production.rb
アプリパスワード等はセキュリティ面を考慮してcredentials.yml.enc
に記述するとよいでしょう。
環境設定ファイルに必要なコードまとめ
最初に、環境設定ファイルに記述する内容をまとめておきます。
require "active_support/core_ext/integer/time"
Rails.application.configure do
# 省略
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
domain: 'gmail.com',
port: 587,
user_name: Rails.application.credentials.gmail[:user_name], #Gmailアドレス(credentials.yml.encに記載)
password: Rails.application.credentials.gmail[:password], #アプリパスワード(credentials.yml.encに記載)
authentication: :login
}
# 省略
end
基本的にこのままコピペで動きますが、詳しく知りたい人向けに解説していきますね。
必要ない人は飛ばしてもOKです。
以下、詳しい解説です。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
アプリケーションのホスト情報をメーラー内で使いたい場合のため、hostとportを設定しました。
config.action_mailer.delivery_method = :smtp
メール送信方式をSMTPに設定しています。
他に:sendmail
、:file
、:test
などが設定可能です。
詳しくは公式ドキュメントを参照してください。
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
domain: 'gmail.com',
port: 587,
user_name: Rails.application.credentials.gmail[:user_name], #Gmailアドレス(credentials.yml.encに記載)
password: Rails.application.credentials.gmail[:password], #アプリパスワード(credentials.yml.encに記載)
authentication: :login
}
SMTPに関わる設定を記述しています。
Gmailを利用する場合、address
、domain
、port
は上記の状態で固定です。
user_name
、password
は念のためcredentials.yml.enc
に記載したものを呼び出しています。
(※設定方法は次の見出しへ)
最後に、メールサーバー側で認証をするときはパスワードをBase64でエンコードする必要があるので、authentication: :login
と記載しました。
credentials.yml.encにGmailアドレスとアプリパスワードを追記
まずはvim
でcredentials.yml.enc
を編集します。
$ EDITOR="vi" bin/rails credentials:edit
初期状態では以下のようになっているはずです。
# aws:
# access_key_id: XXXX
# secret_access_key: XXXXX
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: XXXXXXXXXXXXXXXXX
そこで、下記のように追記して保存します。
# aws:
# access_key_id: XXXX
# secret_access_key: XXXXX
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: XXXXXXXXXXXXXXXXX
gmail:
user_name: 'XXXXX@gmail.com' #Gメールアドレス
password: 'XXXXXXX' #アプリパスワード
これで通信設定は完了です。
メーラー(Mailer)を作成・設定
次にメール送信処理を作っていきます。
Railsにおいてメール送信処理はメーラー(Mailer)が担当するので、コマンドを叩いてさっとベースを作ってしまいましょう。
$ rails g mailer User
Running via Spring preloader in process XXXX
create app/mailers/user_mailer.rb
invoke erb
create app/views/u_mailer
create app/views/layouts/mailer.text.erb
create app/views/layouts/mailer.html.erb
今回はユーザー向けメールを処理するものとして「UserMailer」を作成してみました。
生成されたファイルは以下の3つ。
- app/mailers/user_maier.rb
- app/views/layouts/mailer.text.erb
- app/views/layouts/mailer.html.erb
上記と合わせて、もともとある下記ファイルを使って構築していきます。
- app/mailers/application_mailer.rb
application_mailer.に記述する内容
まずメーラー全体の設定をしていきます。
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout 'mailer'
end
デフォルトでは↑のようになっているはずなので、2行目を書き換えます。
class ApplicationMailer < ActionMailer::Base
default from: Rails.application.credentials.gmail[:user_name]
layout 'mailer'
end
送信元としてGmailを設定しました。
mailer.text.erb, mailer.html.erbに記述する内容
app/views/layouts/mailer.text.erb
とapp/views/layouts/mailer.html.erb
は、全メールの共通テンプレとなっています。
例えば共通のフッターがある場合などは、以下のように記述しておきます。
<%= yield %>
=======
サイト名
https://xxxxxx.com
xxxxx@gmail.com
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<%= yield %>
<p>
サイト名<br>
<a href="https://xxxxxx.com">https://xxxxxx.com</a><br>
<a href="mailto:xxxxx@gmail.com">xxxxx@gmail.com</a><br>
</p>
</body>
</html>
<%= yield %>
部分が、個別のメールテンプレート内容を出力する場所になります。
app/mailers/user_mailer.rbに記述する内容
メール送信処理のコア部分を作ります。
今回は、ユーザーが新規会員登録をしたときに送るお礼メールを作っているとします。
メール本文内には登録したユーザーの名前などを入れ込みたいですよね。
ユーザーデータを管理しているモデル(Userとします)からのデータはメール送信時に受け渡しが可能です。
参考として、Userテーブルは以下の状態であると仮定して処理を作っていきます。
mysql> describe users;
+-------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+-------------------+-----------------------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(100) | YES | | NULL | |
| email | varchar(255) | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| modified_at | timestamp | YES | | NULL | on update CURRENT_TIMESTAMP |
+-------------+--------------+------+-----+-------------------+-----------------------------+
メール送信をする関数名は何でもいいのですが、今回はthanks_mail
としてuser_mailer.rb
内に記述しました。
class UserMailer < ApplicationMailer
def thanks_mail
@user = User.find(params[:user])
mail(to: @user.email, subject: '新規会員登録ありがとうございました')
end
end
mail
という関数で、宛先を@user.email
、件名を「新規会員登録ありがとうございました」として送信を実行しています。
thanks_mail
を実行する際にユーザー情報が必要になるので、params
でユーザーIDを受取り、ユーザー情報を取得した上で実行をかけています。
このparams
は、コントローラーからメール送信処理を実行するときに渡すものです。
コントローラー(Controller)で送信するよう記述
メール送信の設定ができたので、いよいよ送信する部分を記述していきます。
前提として、新規会員の登録(=userの新規追加)はController側で以下のように用意していることが多いと思います。
class UsersController < ApplicationController
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to root_path
else
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email)
end
end
新規会員登録が完了したときにメールを送りたいので、create
内の@user.save
が成功したときに処理をします。
def create
@user = User.new(user_params)
if @user.save
UserMailer.with(user: @user.id).thanks_mail.deliver_later
redirect_to root_path
else
render :new
end
end
.with(user: @user)
にて、メール送信時にユーザー情報をメーラーに渡しています。
だからusers_mailer.rb
で↓が実行されているんですね。
@user = User.find(params[:user])
.thanks_mail
部分で、UserMailerの中でどの関数を実行するかを指定しています。
最後の.deliver_later
は非同期でメール処理を行うように設定している部分です。
ちなみに.deliver_later(wait: 3.minutes)
とすると「3分後に」メール送信してくれます。
もし非同期ではなく即時メール送信したい場合は.deliver_now
とすればOK。
メールのテンプレートを作成
最後に、メールのテンプレートを完成させていきます。
今回はメーラーの関数thanks_email
で送られるメールテンプレートを作成するので、
- app/views/user_mailer/thanks_email.text.erb
- app/views/user_mailer/thanks_email.html.erb
を作ります。
もしHTMLメールは不要でテキストメール送信のみにしたい場合、thanks_email.html.erb
は不要です。
thanks_email.text.erbに記述する内容
サンプルとしてテキストメールを作成します。
メーラーにて@user
が用意された上で、mail
関数にて送信処理を行なっていました。
class UserMailer < ApplicationMailer
def thanks_mail
@user = User.find(params[:user])
mail(to: @user.email, subject: '新規会員登録ありがとうございました')
end
end
そのため、テンプレート内で@user
を使うことができます。
実際にテキストメールのテンプレートを作った例がこちらです。
<%= @user.name %>様
この度は新規会員登録をいただき、ありがとうございました。
登録のメールアドレス:
<%= @user.email %>
なにかご不明点があれば、お気軽にお問い合わせください。
フッター部分はapp/views/layouts/mailer.text.erb
に記述されているので、ここでは不要です。
RailsでGmail経由のSMTPメール送信する方法まとめ
以上のプロセスでRailsからメール送信することが可能です。
手順が多いので迷子になりがちですが、きちんと順を追っていけば簡単にメール送信プログラムができます。
- Googleでアプリパスワードを取得
- 環境設定ファイルに通信設定を記述
- メーラー(Mailer)を作成
- コントローラー(Controller)で送信するよう記述
- メールのテンプレートを作成
ただし、Google側で発行したアプリパスワードは第三者に悪用されるとアカウントを自由に操作されてしまう可能性があるので、扱いには十分注意していきましょう。
コメント