#実装機能
問い合わせフォームからメールを送信、それを指定したメールアドレスで受信する。
(アプリの利用者から管理者に向けてのメール機能として実装)
ActionMailerでは他にもメルマガ配信のように運営側からユーザーに対してメール送信を行ったり、問い合わせに対するメールの返信機能なども実装が可能とのことだが、今回は一番シンプルなこちらの機能を実装。
またGmailアカウントでのメールの受信方法の為、前提としてGmailのアカウントを持っている体で話を進めていく。
##完成イメージ
#実装内容
##1.コントローラの作成
使用するビューファイルはnewのみな上にルーティングの修正が面倒な為、アクションの指定はせずにコントローラファイル単体で作成。
$ rails g controller inquiries
##2.ルーティングの作成
今回使用するアクションは以下の2つ
・問い合わせ作成画面に使用するnewアクション
・問い合わせのデータを作成する為のcreateアクション
resources :inquiries, only[:new, :create]
##3.モデルの作成
最低限必要な情報としてユーザーの名前とメッセージ内容を保存するカラムを用意するが、今回は送信したユーザーが問い合わせに関して返答を要求する場面を想定し、emailのカラムも作成しておく。
$ rails g model Inquiry name:string email:string message:text
マイグレーションファイルに特に変更がなければ bundle install
を実行してテーブルを作成。
その後必要なカラムにバリデーションをかけておく。
class Inquiry < ApplicationRecord
validates :name, presence: true
validates :email, presence: true
validates :message, presence: true
end
##4.Mailerの作成
ActionMailerという機能がRailsに標準搭載されており、下記のコマンドで作成が出来る
$ rails g mailer inquiry
以下のファイルが作成されるのを確認
create app/mailers/inquiry_mailer.rb
invoke erb
create app/views/inquiry_mailer
invoke test_unit
create test/mailers/inquiry_mailer_test.rb
create test/mailers/previews/inquiry_mailer_preview.rb
このうちのinquiry_mailer.rb
は、メール送信機能を実装するための空のクラス
##5.Mailerにメソッドを定義
InquiryMailer
内でメソッドを定義する。
ここで定義したメソッドを実際にデータの作成、送信を実行するInquiriesコントローラ
内で使用する
class InquiryMailer < ApplicationMailer
def send_mail(inquiry)
@inquiry = inquiry
mail to: 'メールアドレス', subject: '【サイト名】お問い合わせ通知'
end
end
上記のmailメソッドで指定されているプロパティの内容は以下の通り
・to = 送信先(メールアドレス)の指定
・subject = メールの件名
要はここで指定したアドレスから指定した件名でメールが届くということなる。
##6.コントローラにメソッドを定義
class InquiriesController < ApplicationController
def new
@inquiry = Inquiry.new
end
def create
@inquiry = Inquiry.new(inquiry_params)
if @inquiry.save
InquiryMailer.send_mail(@inquiry).deliver
redirect_to new_inquiry_path
flash[:email] = "Your message was successfully sent."
else
render 'new'
end
end
private
def inquiry_params
params.require(:inquiry).permit(:name, :email, :message)
end
end
アクション内の処理の流れは通常の投稿作成とほぼ同じだが、createアクション内の処理で先程作成したInquiryMailer
のメソッドを使用する。
InquiryMailer.send_mail(@inquiry).deliver
コードの文末にあるdeliverメソッドはメールの送信に関わるメソッドになる。
因みに、当然の事ながらこの行の処理が完了するまで以降のredirect等の処理が行われない為、フラッシュメッセージが現れるまで数秒間掛かることもある。
それを回避する為にActiveJob
と連携して非同期にメール送信を行う為のdeliver_laterというメソッドも存在するらしいが、今回はこちらを採用。
##7.development.rbにメール送信設定を記述する
ドメインの指定等の設定をconfigディレクトリ配下のdevelopment.rbファイルに記述する。
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: 'smtp.gmail.com',
port: 587,
domain: 'gmail.com',
user_name: 'メールアドレス',
password: 'パスワード',
authentication: 'plain',
enable_starttls_auto: true
}
このあたりはこちらの参考記事の説明がわかりやすかったのでそのまま引用させて頂くことにする。
ここでは、config.action_mailerというパラメーターに色んなオプションを指定してます。
1行目 raise_delivery_errors
メールの送信に失敗した時にエラーを出すかどうか (出したいので true)
2行目 delivery_method
メールの送信方法。 デフォルトで :smtd なので気にする必要もないのですが、
わたしみたいに「なにそれ!?」ってなった方は以下の引用を読んでみてください。
「SMTP」とは「Simple Mail Transfer Protocol(シンプル・メール・トランスファー・プロトコル)」の略で、あえて>訳せば「簡単なメールの送信の手順」というところだろうか。お約束ごとと考えてもいい。
あなたがメールを書き、宛先のアドレスを入力して「送信」アイコンをクリックする。このとき、あなたのスマホやパソコン>は、この「SMTP」のお約束ごとに従って、あなたが契約しているメールサーバーと、こんなやり取りをするのである。
「メールを送るよ〜」「ええで!」「宛先は〇◯だよ」「りょ」「本文はかくかくしかじかだよ」「受け取ったで!」――とまぁそんな具合。
出典: メール設定で最初につまずく「SMTP」「POP」「IMAP」。その意味&設定方法は?
3行目 smtp_settings
smtpの詳細設定って感じです。
port => SMTPサーバーのポート番号
address => SMTPサーバーのホスト名
domain => HELOドメイン
user_name => メール送信に使用するgmailのアカウント
password => メール送信に使用するgmailのパスワード
authentication => 認証方法
enable_starttls_auto => メールの送信にTLS認証を使用するか
#####※前項のMailerやここで使用するメールアドレスやパスワードはGithub
にpushする際には環境変数化しておく必要があるので注意
#####また、本番環境でアプリケーションを運用する場合は、produciton.rb
にも同じ内容を記述する必要がある。
##8.ビューを作成する
問い合わせフォーム用のビュー画面を作成する。
コードは冒頭で添付した画面で使用したものなので、ご自身のアプリに合わせて作成。
通常のフォーム画面の作成と変わらないはず。
:
<div class="contact_form text-center">
<%= form_with model: @inquiry, local:true do |f| %>
<%= render 'layouts/error_messages', model: f.object %>
<h3>NAME</h3>
<%= f.text_field :name %>
<h3>EMAIL</h3>
<%= f.email_field :email %>
<h3>MESSAGE</h3>
<%= f.text_area :message %>
<div>
<p><%= f.submit "送信" %></p>
</div>
<% end %>
</div>
:
##9.メール画面を構成するファイルを作成
上記とは別に実際に送られてくるメールのレイアウトを構成するファイルも作成する必要がある。
ActionMailerのコマンドを実行した際にviewsディレクトリ
の中にinquiry_mailerディレクトリ
が作成されているため、そこにファイルを作成する。
今回はアプリの管理者が受け取る想定の為、構成には必要最低限しか気を配っていない。
因みに場合によってはHTML形式のメールを受け取ることができない場合もあるらしく、そのためテキスト形式のファイルも用意しておくのがベスト。
HTML形式
<h5>お問い合わせ内容</h5>
<P>-----------------------------------------</P>
<p>名前:<%= @inquiry.name %></p>
<p>メールアドレス:<%= @inquiry.email %></p>
<p>お問い合わせ内容:<%= @inquiry.message %></P>
<p>-----------------------------------------</p>
テキスト形式
お問い合わせ内容
-----------------------------------------
名前:<%= @inquiry.name %>
メールアドレス:<%= @inquiry.email %>
お問い合わせ内容:<%= @inquiry.message %>
-----------------------------------------
実際に届くメール画面がこちら(HTML形式)
##10.環境変数を使用
Githubにpushしたり、本番環境でアプリを使用する際はこれまでに使用したメールアドレスやパスワードはセキュリティを考慮し環境変数化しておく必要がある。
gemのdotenv-rails
をinstallしている前提での説明な為、gemをインストールしていない場合は導入する。
.envファイル
に実際のメールアドレスやパスワードを記述
SEND_MAIL="使用するメールアドレス"
GMAIL_PASSWORD="使用するGmailアカウントのパスワード"
定義した環境変数をコード内で使用
:
mail to: ENV['SEND_MAIL'], subject: '【サイト名】お問い合わせ通知'
:
:
user_name: ENV['SEND_MAIL'],
password: ENV['GMAIL_PASSWORD'],
:
.envファイル
を.gitignoreファイル
に記述して完了
##補足
gmailのアカウントの設定の関係でアクション実行の際に以下のようなサーバーエラーが発生する可能性がある。
・Net::SMTPAuthenticationError (535-5.7.1 Username and Password not accepted. Learn more at
・Net::SMTPAuthenticationError 534-5.7.9 Application-specific password required.
上記エラーが現れた際は、別途Gmailアカウントの設定変更が必要となる可能性が高い(パスワードやメールアドレスのスペルミス等の可能性もあるため、まずはそこを疑う)。
個人的には実装よりもむしろこれらのエラーの解消に手こずったので、参考になれば。
##参考記事
ActionMailer参考記事
・Action Mailer でメール送信機能をつくる
・[【Rails入門説明書】Action Mailerについて解説]
(https://web-camp.io/magazine/archives/19143)
サーバーエラーの解決のために使用
・Googleで2段階認証を使っているときにRailsのActionMailerでGmailを使う方法
・[Rails5]deviseでgmailを送ろうとしたがsmtp認証のエラーが出た時にした事。