🍣

Heroku にデプロイした Rails アプリから SENDGRID を使ってメール送信する

2021/06/20に公開

はじめに

Ruby on Rails で作成した ウェブアプリのデプロイ先として、heroku は良く使われています。(デプロイとは「配備する」という意味の英単語で、作成したウェブアプリを使えるようにするという意味合いです。)
そして、アプリケーションからメールを送信したい場面も多々あります。
初心者の方向けに記してみましたので、ご参考になれば幸いです。

環境

% rails -v
Rails 6.1.1

% ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin20]

アプリケーションの作成

アプリケーションの概要

日々の雑件を管理するタスク管理アプリケーションを作成します。
そして、タスクを作成すると、利用者にメールが送信されます。

MVC フレームワークとは

Ruby on Rails では 「MVCフレームワーク」という設計思想に基づいて、アプリケーションを作っていきます。

  • M とは モデルのことで、データベースからデータを読み出したり、書き込んだりする処理(CRUD作成・読出・更新・削除)を担当します。

  • V とは ビューのことで、アプリケーションを使う人が実際に見ている画面表示を担当する部分です。HTML に Ruby のコードを埋め込んだ、ERB や、より簡潔に記述できる slim が良く使われます。

  • C とは コントローラのことで、利用者からの操作をうけて、モデルとビューの間を取り持ってくれる存在です。例えばタスク登録画面が表示されているときに、「登録」ボタンが押されたので、ビューから送られてきたデータをモデルに渡してデータベースに登録するよう依頼したり、「データを登録しました」と画面表示できるよう、ビューに必要なデータを送ったりする役割を果たしてくれます。

アプリケーションの作成

まず、アプリケーションを生成します。名前は、taskleaf にします。

% rails new taskleaf --database=postgresql

Gemfile を開いて、以下の gem を追記します。

gem 'pg'                             # データベースに Postgresql を使う
gem 'slim-rails'                     # Slimを使って効率的にhtmlを記述する

group :development do
  gem 'letter_opener_web'            # 開発環境で、メール開封が簡単にできる
end

モデルの作成

以下のコマンドで、モデルを生成します。

% rails generate model task string:name
class CreateTasks < ActiveRecord::Migration[6.1]
  def change
    create_table :tasks do |t|
      t.string :name

      t.timestamps
    end
  end
end

上のような感じの migration ファイル ができ上がっているはずなので、
次のコマンドで、データベースの作成と更新(マイグレーション)を行います。
マイグレーションすることで、tasksテーブルがデータベースに作成されます。

% rails db:create
% rails db:migrate

コントローラとビューの作成

モデルができたので、以下のコマンドでコントローラとビューを作成します。

% rails generate controller tasks index show new edit

コントローラの雛型ができているので、以下のように編輯します。

class TasksController < ApplicationController
  def new
    @task = Task.new
  end

  def create
    # 登録画面から送られてきたフォームのデータに基づき、タスクを新規作成します。
    @task = Tasks.new(task_params)

    if @task.save
      # 画面に、登録できた旨、通知を表示する
      redirect_to @task, notice: "タスク「#{@task.name}」を登録しました。"
    else
      render :new
    end
  end

  private

  def task_params
    # 画面からの入力は、name の項目のみを受け付けるようにします。
    params.require(:task).permit(:name)
  end
end

ビューも雛型をもとにして、new.html.slim を次のように 編輯します。

h1 タスクの新規登録

= form_with model: task, local: true do |f|
  = f.label :name
  = f.text_field :name, required: true
  = f.submit '登録する'

これで、タスクの新規登録ができるようになりました。
タスクの一覧表示を司る index アクション や 個別表示を司る show アクションなどをまだ作っていませんので、画面上で結果を確認することはできませんので、Rails コンソール上から、確認してみましょう。

以下のコマンドを実行します。

% rails console
% rails c
Running via Spring preloader in process 68828
Loading development environment (Rails 6.1.1)
[1] pry(main)> Task.all
  Task Load (0.4ms)  SELECT "tasks".* FROM "tasks"
[2] pry(main)>

コンソール上で、 Task.all とタイプすると、今、登録したタスクが表示されます。

メール送信機能の作成

タスクの登録機能が実装できましたので、利用者へタスクを登録した旨お知らせするメール送信機能を実装していきましょう。
どのようなメールを送るか制御するメーラー(Mailer)と、実際に送るメールの雛型を作成します。

Rails では、メール送信機能を簡単に実装できるようになっており、その関係は、コントローラとビューとの関係に良く似ています。
ちょうど、Controller の new アクション(メソッド) で、View の new.html.slim が表示されるように、
Mailerの creation_email アクション(メソッド) で、View の creation_email の メールが送信されますようにします。

Controller の場合には、RESTfulの原則に従って、基本七アクション(index, show, new create, edit, update, destroy)を使うことがお薦めでしたが、Mailerにはそのような原則はないので、ここでは、分かりやすい名前として、creation_email アクション(メソッド) という名前にします。

以下のコマンドをターミナルより入力しましょう。

% rails generate mailer task creation_email

メーラーとメールの雛型が作られます。
メーラーは、app/mailers/task_mailer.rb というファイル名で、
雛型は、app/views/task_mailer/creation_html.slim と、app/views/task_mailer/creation_text.slim ができています。雛型が二つあるのは、HTMLメールと、テキストメール の両方に対応するためです。

それでは、メーラーを次のように編輯しましょう。

class TaskMailer < ApplicationMailer
  def creation_email(task)
    # 引数(ひきすう)として受け取ったtaskを、
    # 雛型に渡せるよう、@taskに代入しています。
    # こうすることで、雛型の中で、@taskを参照できるようになります。
    @task = task

    # メールの送信先を指定します。
    # 件名は、「タスク作成完了メール」
    # 宛先は、taro@example.com に送ることにします。
    mail(
      subject: "タスク作成完了メール",
      to: "taro@example.com"
    )
  end
end

HTMLメール用と、テキストメール用、それぞれの雛型を編輯します。

| 以下のタスクを作成しました。

ul
  li
    | 名称:
    p
      = @task.name
| 以下のタスクを作成しました。
= "\n"
| 名称:
= "\n"
= @task.name

HTMLメールでは、ul タグや li タグなどを使って装飾することができます。
テキストメールで改行するには、= "\n" と書きます。
両者ともに、= @task.name と書くことで、作成されたタスク名称を参照しています。

それでは、タスクを登録した際に、メールが送られるようにしてみましょう。
TasksController に、今、作成したメール送信機能が呼び出されるよう、追加します。

class TasksController < ApplicationController
  def create
    # 登録画面から送られてきたフォームのデータに基づき、タスクを新規作成します。
    @task = Tasks.new(task_params)

    if @task.save
      # タスク作成した旨、メール送信する
      TaskMailer.creation_email(@task).deliver_now

      # 画面に、登録できた旨、通知を表示する
      redirect_to @task, notice: "タスク「#{@task.name}」を登録しました。"
    else
      render :new
    end
  end
end
      # タスク作成した旨、メール送信する
      TaskMailer.creation_email(@task).deliver_now

この二行が追加されています。

以上で、メール送信機能の実装は完了です。

開発環境でのメール送信できているか、確認する

Ruby on Rails の 開発環境で 簡単にメール送信機能の確認ができる letter_opener_web の使い方

Heroku(へろく) にデプロイ(公開・配備)する

ここでは、Rails アプリのデプロイ(公開・配備)先として、よく用いられている heroku (へろく) を使います。
heroku の名称は、hero haiku (ヒーロー俳句) に因んだとのことですが、インターネット上に アプリケーション を簡単に公開できるサービス(PaaS パース: Platform as a Service)を提供しています。
これにより、以前は自分でサーバーを用意して、様々な設定をして、という苦労なしに、手軽に公開できるようになりました。

アカウントの作成

https://heroku.com にアクセスし、Sign up から、自分のアカウントを作成します。

CLI(Command Line Interface)のインストール

GUI(Graphical User Interface)を使って、ブラウザからウェブアプリの作成もできます。
そしてせっかくですから、Heroku Command Line Interface (CLI) もインストールしておきます。
ターミナルからコマンド一つで、いろいろできるようになるので、慣れると簡単です。

% brew tap heroku/brew && brew install heroku

Gitを使ってデプロイする。

Git は、バージョン管理システム と呼ばれるソフトウェアで、自分の作ったソースコードの履歴を管理することができます。
Git を使うことで、以前のコードに戻したり、本番用のコードを変更することなく新しい機能を試すためにプログラムを書いたりすることが容易にできるようになります。
コマンドラインでの操作が基本ですが、GUIベースで操作ができるSourceTreeもありますので、ご利用ください。
わかばちゃんと学ぶ Git使い方入門 が、豊富なイラストで読みやすいです。

また、Heroku に公開した際に、メール送信できるよう、config/environments/production.rb に
SENDGRID用の設定を追記します。

# config/environments/production.rb
Rails.application.configure do
  (略)
  # メイラーのテンプレートでフラグメントキャッシュを有効にするべきかどうかを指定します。
  # 指定のない場合のデフォルト値はtrueです。
  config.action_mailer.perform_caching = false
  # deliverメソッドを実行したときに、true なら、メール配信を行なう。
  config.action_mailer.perform_deliveries = true
  # メール配信に失敗した場合にエラーを発生するかどうかを指定します。
  # このオプションは、外部のメールサーバーが即時配信を行っている場合にのみ機能します。
  config.action_mailer.raise_delivery_errors = true
  # SMTP プロトコルによるメール配信を行う。
  config.action_mailer.delivery_method = :smtp
  # アプリケーションのホスト情報をメイラー内で使いたい場合は:hostパラメータを明示的に指定します。
  # これにより、メーラー内で、= link_to 'ようこそ', welcome_url などのように記述可能となる。
  config.action_mailer.default_url_options = { host: 'taskleaf.herokuapp.com' }
  # smtpの配信メソッドの詳細設定を行います。
  # SENDGRID用
  config.action_mailer.smtp_settings = {
      address: 'smtp.sendgrid.net',
      port: 587,
      domain: 'heroku.com',
      user_name: 'apikey![ss_ 2021-02-17 0.58.25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96314/30d49808-0ee1-f09e-8689-38d2e9b5dde4.jpeg)
',
      password: ENV['SENDGRID_APIKEY'],
      authentication: :plain,
      enable_starttls_auto: true
  }
  (略)
end
% cd taskleaf
% git init
Initialized empty Git repository in .git/
% git add .
% git commit -m "My first commit"

Herokuにログインしてウェブアプリを作成します。
名前は、taskleaf にします。(すでに使われていたら別の名前にします。)

% heroku login
% heroku create taskleaf

Heroku では、いろいろなadd-on(追加機能)を使えるようになっています。
データベースには、Postgresql を、
ストレージサービスには、Cloudinary を、
以下のコマンドで、機能追加します。
各アドオンとも、利用する容量等によって、さまざまな料金プランが用意されていますが、
ここでは、無料プランにしています。

% heroku addons:create heroku-postgresql:hobby-dev
% heroku addons:create cloudinary:starter

公開(デプロイ)します。

% git push heroku master

公開できましたので、データベースを更新します。

% heroku run rails db:migrate

ブラウザで開いて確認します。

% heroku open

Heroku で SENDGRID を使って メール送信できるようにする

Heroku で メール送信できるようにします。
SENDGRID という メール送信サービスが有名ですので、これを使ってみることにします。
(他には Mailgun というサービスもあります)
月に10000通までは無料ですので、実験用には充分です。

SendGrid アカウントの登録

SendGridにアクセスし、右上の青い「Start for free」ボタンからアカウントを作成します。
スクリーンショット 0003-02-10 15.01.06.jpg

メールアドレスとパスワードを入力します。
プログラムによる不正なアカウント取得を防止するために、人であるか確認する機能(キャプチャ)が設けられています。
「わたしはロボットではありません」にチェック「✓」を入れ、人であることが認識させます。
「I accept the Terms of Service and have read the Services Privacy Policy」にチェックを入れると、「Create Account」ボタンが押せるようになります。
スクリーンショット 0003-02-10 15.02.08.jpg

開発者情報の登録が求められますので、<font color="red"> * </font>がついた必須項目を入力し、
「Get Started!」ボタンを押します。
スクリーンショット 0003-02-10 15.09.20.jpg

先ほど登録したメールアドレス宛に SendGrid からメールが届いています。
メールアドレスの持ち主であることを確認するメールです。
中央の青い「Confirm Email Address」をクリックし、自分のメールアドレスであることを確認します。

スクリーンショット 0003-02-10 15.49.04.jpg

ブラウザが開き、以下の画面が表示されます。

スクリーンショット 0003-02-10 15.58.36.jpg

「Review Security」という青いボタンをクリックし、セキュリティ関係の設定を進めていきます。

「Verify Account Email Address」の項目は、青く「Done」と表示されており、メールアドレスの確認が済んでいることが示されています。

スクリーンショット 0003-02-10 16.12.43.jpg

ですので、次の「Enable Two-Factor Authentication (2FA)」の確認を進めていきます。
「Enable Two-Factor Authentication (2FA)」をクリックすると、折り畳まれていたものが展開され、中が読めるようになります。

スクリーンショット 0003-02-10 16.11.13.jpg

「Two-Factor Authentication (2FA) protects your account with an extra layer of security. We’ll ask for your password and an authentication code each time you log in to your Twilio SendGrid account.
2FA will soon be required to log in, so we recommend you enable it now – it only takes a few minutes.」
と書かれています。

DeepLというサービスがありますので、これを使って日本語に翻訳します。
「二要素認証(2FA)は、お客様のアカウントをさらに安全なレイヤーで保護します。Twilio SendGridアカウントにログインするたびに、パスワードと認証コードをお尋ねします。
2FAはまもなくログイン時に必要になりますので、今すぐ有効にすることをお勧めします。」となります。

簡単に纏めると、二要素認証(2FA)とは、
「パスワードを知っている」 という「知識要素」に加えて、
自分の所持する端末に送られてきた文字列などの「所持要素」も確認することで、
より、高い認証を行う手法です。

二要素認証を行う

Authy の 登録

二要素認証サービスを提供している Authy (Twilio Authy)にアクセスします。
モバイル版のアプリと、デスクトップ版のアプリそれぞれが提供されています。
どちらでも良いのですが、ここでは、デスクトップ版のアプリをダウンロードすることにします。

デスクトップ版のアプリを起動し、
日本の国番号81と、ご自身の電話番号を入力、「Next」ボタンを押します。

スクリーンショット 0003-02-10 16.59.31.jpg

電話番号の確認方法を三種類選ぶことができます。
ここでは、真ん中のSMSを選びます。
スクリーンショット 0003-02-10 17.02.06.jpg

入力した電話番号にSMSメッセージが届きます。6桁の数字が書かれていますので、入力します。
入力を終えると、Authyの登録は完了し、次の画面が表示されます。

ss_ 2021-02-17 0.13.13.jpg

SendGrid の二要素認証

Authyへの登録が完了しましたので、SendGridの二要素認証を行います。

ブラウザの新しいタブを開き、SendGridにアクセスします。
右上の log in をクリックし、ログイン画面へと遷移、
メールアドレスとパスワードを入力し、Log in ボタンを押します。

ss_ 2021-02-17 0.18.34.jpg

二要素認証を求められます。
ss_ 2021-02-17 0.25.33.jpg

Authy を開きます。
ss_ 2021-02-17 0.13.13.jpg

SendGridの認証を行いたいので、SendGridをクリックします。
ss_ 2021-02-17 0.36.43.jpg

表示されている8桁のコードの有効時間は20秒です。
Authyに表示されているこのコードを、SendGridに入力すると、二要素認証は完了です。

SendGridの API Keys の作成

アプリケーションからSendGridを利用するためには、
従前は、USER_NAMEとPASSWORDによる認証が必要でしたが、
セキュリティ強化のため、APIキーを用いることが推奨されています。

ss_ 2021-02-17 0.52.26.jpg

API Keys の設定を行うために、左下、Settings をクリックします。
API Keys という項目がありますので、クリックします。

ss_ 2021-02-17 0.55.20.jpg

右上の Create API Key をクリックします。

ss_ 2021-02-17 0.58.55.jpg

API キーが生成されています。クリックするとコピーできます。(二度と表示されませんので注意。)
Done ボタンを押し、終了します。
ss_ 2021-02-17 1.04.00.png

Heroku の環境変数の設定

Herokuにアクセスし、ログインします。
ダッシュボードをクリック、作成したアプリ(taskleaf)をクリックします。
このアプリでSendGridを使えるよう、Herokuの環境変数を設定します。

Settings メニューから、Reveal Config Vars をクリックします。

ss_ 2021-02-17 1.17.46.jpg

環境変数の KEY と VALUE の追加ができます。
KEYを、SENDGRID_APIKEY
VALUEを、先ほどコピーしたAPIキーを貼り付け、Add ボタンを押します。

ss_ 2021-02-17 1.15.52.png

終わりに

手数はかかりますが、やっていることは、難しくはないかと思います。

  • SendGridに利用者登録する。
  • Authyに利用者登録する。
  • SendGridの二要素認証する。
  • SendGridのAPIキーを作成する。
  • HerokuにSendGridのための環境変数を登録する。

どなたかのお役に立てば幸いです。

Discussion