Rails Ambassador

Herokuでメール送信を行う

Herokuでメール送信を行う時にはSendmailというアドオンを使うと非常に簡単にメール機能を実装することができます。
このTipsでは最小限の実装でメール送信を行ってみたいと思います。
投稿があったらメール通知を行う、特定のユーザーに向けてお知らせメールを送信したいなど色々応用ができると思います。

参考サイト

環境

以下環境で動作確認しています。
Rails: 6.1.4.4
Ruby: 3.0.3

Herokuに接続はできていて、ログイン済みとします。また、デプロイにgitも必要なのでない方はインストールしておきましょう。

  • 2021/03/07 SendGridの変更に対応しました。
  • 2022/02/05 SendGridの記述を一部変更しました。

動作確認日:2022/02/05

作成するアプリ

送信ボタンを押すと指定のメールアドレスにメールが届くという簡易アプリ。
DBは使いません。

メールテスト用のアプリを作成

$ rails new sendmailtest
$ cd sendmailtest
新規プロジェクトを作成し、ディレクトリの移動を行います。
便宜上プロジェクト名はsendmailtestにしましたが任意の名前で大丈夫です。

ローカルリポジトリも作成しておきましょう。

$ git init

$ git add .
$ git commit -m "App init"
$ git status
On branch master
nothing to commit, working tree clean

メーラーを作成する

メーラー作成の書式は以下になります。

rails g mailer メーラー名

では早速作成しましょう。メーラー名はTestとします。この名前はメーラーのクラス名になりますので、アッパーキャメルケースにすると良いです。(※小文字でも自動的に変換されます。)

$ rails g mailer Test
      create  app/mailers/test_mailer.rb
      invoke  erb
      create    app/views/test_mailer
      invoke  test_unit
      create    test/mailers/test_mailer_test.rb
      create    test/mailers/previews/test_mailer_preview.rb

app/mailers/test_mailer.rbがメーラー本体になります。メーラー本体ではメソッドを用意し、メールのタイトルなどを定義します。
app/views/test_mailerフォルダにはメールの本文をviewファイルとして作成します。

Tips!メーラーの削除

メーラー名を間違えてしまったなど一度削除したい場合はrails dコマンドを使うと、自動生成されたファイル群も一括削除されます。

$ rails d mailer メーラー名

Tips!メーラーをview付きで作成

今回は手動で作成しますが、メーラ―にメソッドとメソッドのview付きで生成することもできます。

$ rails g mailer メーラー名 メソッド1 メソッド2 ...
※メソッドやviewについては以降のチャプターを確認してみてください。

メーラーを編集しメソッドを作成する

ではapp/mailers/test_mailer.rbを開いてメーラー本体を編集していきましょう。以下のように編集してください。

class TestMailer < ApplicationMailer

  default from: '送信元のメールアドレス'

  def testmail(str)
    @str = str
    mail(to: "送信先のメールアドレス", subject: "メールの件名")
  end
end

default from: では送信者のメールアドレスを指定します。実在しなくても大丈夫ですが、他人のメールアドレスやドメインを使う事(成りすまし)は絶対にやめましょう。

mail の行でメールの送信先とメールの件名を設定します。今回はテストアプリですから送信先のメールアドレスは自分のメールアドレスにすると良いと思います。

メーラーのメソッドで定義したインスタンス変数はメール本文であるviewに渡すことができます。controllerのアクションとviewの関係と同じですね。今回はフォームから送信されてきた任意の文字列をメソッドの引数に渡し、本文に使おうと思いますので@strを設定しています。

メール本文(view)のHTML版を作成する

ではメール本文を作成していきましょう。本文はviewの扱いになります。
メーラーに対応するviewファイルには法則があります。

app/views/メーラー名/メーラーのメソッド名.html.erb

ということでapp/views/test_mailer/testmail.html.erbファイルを作成し、以下のように記述しましょう。

<!DOCTYPE html>
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
  </head>
  <body>
    <h1>こちらはメール本文です</h1>
    <p>
      <%= @str %>
    </p>
  </body>
</html>

HTMLファイルと同様にHTMLタグが使えますのでお好みで装飾してみてください。
また、erbファイルですからerbの書式でrubyのコードを使う事ができます。

メール本文(view)のテキスト版を作成する

クライアントがHTMLで受け取れるとは限りませんのでテキスト版も作成します。
こちらも対応するviewファイル名は同様の法則になります。test.erb拡張子で作成しましょう。

app/views/メーラー名・メーラーのメソッド名.text.erb

ではapp/views/test_mailer/testmail.text.erbファイルを作成し、以下のように記述しましょう。

こちらはメール本文です

<%= @str %>

erbファイルなのでrubyのコードを記載することができますが、HTMLタグは使えません。そのまま本文にタグが出力されてしまいますのでご注意ください。

TOPページを作成する

メーラの設定が終わりましたのでTOPページを作成していきましょう。
TOPページで表示させるものは入力フォームと送信ボタンだけです。
入力された文字列がメールの本文になるようにします。

ではまずコントローラをview付きで作成しましょう。TOPページはtop#indecx で表示させます。

$ rails g controller top index

次にルートを設定します。
config/routes.rbファイルを開きルーティングの記載をしましょう。

Rails.application.routes.draw do
  root 'top#index'
  post '/mail', to: 'top#mail', as: :mail;
end

トップページとメール送信用の二つのアクションを設定しました。

次にviewを編集します。app/views/top/index.html.erbファイルを開き以下のように編集しましょう。

<%= h(flash[:notice]) %>

<h1>メール送信フォーム</h1>

<%= form_with url: mail_path, local: true do |f| %>
  <%= f.text_field :str %>
  <%= f.submit "送信" %>
<% end %>

コントローラにメール送信のアクションを追加

ではTOPコントローラにメール送信するアクションを追加しましょう。
ルーティングで設定したように、メール送信はmailアクションになります。
app/controllers/top_controller.rbを以下のようにmailアクションを追加します。

class TopController < ApplicationController
  def index
  end

  def mail
    TestMailer.testmail(params[:str]).deliver_later  #メーラに作成したメソッドを呼び出す。
    flash[:notice] = "メール送信完了" 
    redirect_to root_url
  end
end

ここでは作成したメーラーのクラスのメソッドを呼び出すだけです。非常に簡単ですね。
引数には本文に使う入力フォームの値を渡しています。

    TestMailer.testmail(params[:str])

送信した後はTOPページへリダイレクトさせflashメッセージを表示させます。

Herokuアプリの作成

ではHerokuアプリを作成していきます。

$ heroku create アプリ名
Creating app... done,

doneと出ましたらアプリ作成は成功しています。

※アプリ名は既に同じ名前が使われていた場合は作成できません。
アプリ名は全て半角英数で小文字である必要があり、数字から始めることができません。
記号はハイフンのみ使えます。
アプリ名が思いつかない方はアプリ名を省略しますと任意の名称のアプリが作成されます。
無料版はアプリは5つまでしか作成できません。

コマンド実行時にエラーになっていないかよく確認し、リモートリポジトリにherokuが追加されているか確認しましょう。

$ git remote -v 
heroku  https://git.heroku.com/作成したアプリ名.git (fetch)
heroku  https://git.heroku.com/作成したアプリ名.git (push)

Tips!Herokuアプリが作成されていない例

コマンド実行時にCreating app... doneとは出ずに以下のような表記が出ていましたらエラーで作成できていません。もう一度アプリ作成を行ってください。

Creating ⬢ アプリ名... !
     Name testmail is already taken
=> testmailという名前が既に使われている
     Name must start with a letter and can only contain lowercase letters, numbers, and dashes.
=> 名前は文字で始まり全て小文字か数字、ハイフンである必要がある。

HerokuのSendGridアドオンを有効にする

以下コマンドでアドオンを追加しましょう。

$ heroku addons:create sendgrid:starter
Creating sendgrid:starter on ⬢ アプリ名... free
Created sendgrid-xxxxx-xxxxx as SENDGRID_PASSWORD, 
SENDGRID_USERNAME
Use heroku addons:docs sendgrid to view documentation

SendGridのAPIキーを作成する

SendGridを使うにあたってAPIキーが必要になります。
まず以下のリンクからHerokuにログインしてください。
Heroku Loginページ

ログインしましたらHerokuのアプリ一覧から作成したアプリをクリックして選択しましょう。
アプリのページへ遷移しましたら resourcesタブをクリックしてください。

Add-ons 一覧にSendGridが追加されていると思いますのでこちらをクリックしてください。

HerokuSendGridAddOn

別タブでSendGridの設定画面が開くと思います。sendgridに登録していない方は登録し、ログインを行ってください。

Send Confirmation Emailをクリックすると入力されたメールアドレスにメールが届きます。メールを確認しましょう。以下のようなメールアドレスが届いていると思いますので「Confirm Email Address」をクリックして認証を完了させてください。

認証が完了しましたらAPIキーを作成します。左メニューバーから 「Settingsタブ」内にある「API Keys」を選択してください。

右上にある「Create API Key」をクリックします。

右側に現れたメニューの一番上の「API Key Names」にアプリの名称を入力し、「Full Access」 を選択し、「Create & View」をクリックしてください。

API Key Created画面にあるランダムな文字列がAPIキーになります。こちらを控えておきましょう。

Herokuの環境変数にSendGridのAPIKeyを追加

取得したAPIキーをHerokuの環境変数にセットします。Railsアプリの設定にAPIキーを直書きするのは危険なので必ず環境変数を使うようにしましょう。

$ heroku config:set SENDGRID_API_KEY=作成したAPIキー
Setting SENDGRID_API_KEY and restarting ⬢ アプリ名... done, vxx
SENDGRID_API_KEY: APIキー

doneと出ていればセットされています。APIキーは間違いなく入力しませんと動作しませんので慎重にセットされたか確認してください。

Tips!Heroku環境変数の確認方法

環境変数が正しく設定できているか確認するには以下コマンドをアプリのディレクトリでターミナルに入力しましょう。

$ heroku config
SENDGRID_API_KEY:  登録したAPIキー
SENDGRID_PASSWORD: 自動生成
SENDGRID_USERNAME: 自動生成

Herokuの環境変数一覧が表示されます。今回のアプリでは「SENDGRID_API_KEY」という名称で登録しますのでこの名前が正しくなっているかも確認しておいてください。
自動的にSENDGRID_PASSWORDSENDGRID_USERNAMEが生成されているはずです。こちらの環境変数を次のチャプターで設定する本番設定用ファイル「config/environment/production.rb」で使用します。

ActionMailerの本番用の設定をする

config/environments/production.rbファイルに本番環境用の設定を追記します。

Rails.application.configure do

  # 省略

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_deliveries = true
  config.action_mailer.smtp_settings = {
  :user_name      => 'apikey',
  :password       => ENV['SENDGRID_API_KEY'],
  :domain => 'herokuapp.com',
  :address => 'smtp.sendgrid.net',
  :port => 587,
  :authentication => :plain,
  :enable_starttls_auto => true
  }
end

actionメーラーに関する記述は中段にもあるのですが、よくわからなければ最後尾のend直前に追加して大丈夫です。

Herokuにデプロイする

今回はDBを使っていません。sqlite3gemを使いますとデプロイ時にエラーとなりますので Gemfileのsqlite3の行をコメントアウトし、代わりにpgというgemを追加します。

source 'https://rubygems.org'

#略

#gem sqlite3の行をコメントアウト
#gem 'sqlite3'
gem 'pg', group: :production #この行を追加
#略

コメントアウトしましたらbundle installを行いましょう。

$ bundle install

PostgreSQLというデータベースがインストールされていない場合はエラーとなるかもしれません。その際はデータベースをインストールするか、以下コマンドでこのgemを開発環境ではインストールしないコマンドを実行します。

$ bundle install --without production

次にconfig/database.ymlファイルを開き、Heroku用の設定を記述します。
productionの部分だけ書き換えましょう。YAMLファイルのインデントは半角スペース2つと決まっていますのでこちらも注意してください。

production:
  adapter: postgresql
  encoding: unicode
  pool: 5
  database: sendmailtest_production
  username: sendmailtest
  password: <%= ENV['SENDMAILTEST_DATABASE_PASSWORD'] %>

コミットしてデプロイします。

$ git add .
$ git commit -m "SendGrid Test"
$ git status
On branch master
nothing to commit, working tree clean
$ git push heroku master

Herokuで動作確認

以下コマンドをアプリのディレクトリで実行しますと、一番下にURLが出ると思います。
$ heroku info

一番下にあるURLにアクセスし、フォームに送信したいメッセージを入力してみましょう
設定したメールアドレスにメールが届けば成功です。

または以下コマンドが有効な環境でしたら自動的にアプリが開きます。
$ heroku open