LoginSignup
8
5

More than 3 years have passed since last update.

sendgridを使ってメールを送信 Rails

Posted at

SendGridとは

sendgirdはメールのインフラサービスです。SaaSっぽいです。
従来はメールを送るにはsmtpサーバーを立ててとか結構面倒なことがいっぱいあるらしいです。(わたしは自分で用意したことないのでありがたみが分からず)
にも関わらず、メールが相手に届かないことも20%ほどはあるらしいです。(^_^;)
ビジネスだと大きな機会損失につながりますね。
なので、面倒なことと、機会損失を取っ払ってくれるのが、sendgridだと認識しています。👏

sendgrid.png

導入背景

パスワードを忘れた人向けに、「パスワード忘れました」ボタンを押せば自動でメールが配信されるようにしたい。
でも事情があってソースコードは共有できないので、ここでは「公式ページ RubyonRailsでメールを送信」を参考に導入方法を記載しています。参考というかほぼそれ、、、、笑

環境

Ruby 2.4.2
Rails 5.2.1
MacOS Mojave

導入方法

railsだとactionmailerを使って導入します。まずはmailerクラスを生成します。

$ rails generate mailer User
Running via Spring preloader in process 7688
      create  app/mailers/user_mailer.rb
      invoke  erb
      create    app/views/user_mailer
      invoke  test_unit
      create    test/mailers/user_mailer_test.rb
      create    test/mailers/previews/user_mailer_preview.rb

mailerのuser_mailer.rbにメソッドを追記する

app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
  default :from => 'any_from_address@example.com'

 # ここから下を追記 このメソッドが呼び出されると @user.emailにメールが送信される
  def send_signup_email(user)
    @user = user
    mail( :to => @user.email,
    :subject => 'Thanks for signing up for our amazing app' )
  end
end

アクションとHTML出力に対応したViewを生成する。これがメールとして届く文書になる。

app/views/user_mailer/send_signup_email.erb

    <h1> <%= @user.name %> 様、ご連絡いただきありがとうございます。</h1>
    <p>パスワードを配信するまで少々お時間がかかります。もうしばらくお待ちください。</p>

user_mailer.rbに記載した send_signup_emailコールする必要があるため、アクションにdelverメソッドを記載する。

app/controllers/users_controller.rb
class UsersController < ApplicationController
  def create
    # Create the user from params
    @user = User.new(params[:user])
    if @user.save
      # ↓の一文でuser_mailer.rbのsend_signup_emailがコールされメールが送信される
      UserMailer.send_signup_email(@user).deliver
    end
  end
end

最後に、sendgridを使用するためのactionmailerを設定する。
config/enviroment.rbに以下を記載

config/environment.rb
ActionMailer::Base.smtp_settings = {
  :user_name => 'your_sendgrid_username',
  :password => 'your_sendgrid_password',
  :domain => 'yourdomain.com',
  :address => 'smtp.sendgrid.net',
  :port => 587,
  :authentication => :plain,
  :enable_starttls_auto => true
}

user_nameはsendgridに登録した時に与えられる。
passwordはsendgridに登録する時に自分で設定するやつ。
domainは自分は指定しなくてよかったので、test.comとかにしといた。練習用とかだったら、yourdomain.comのままで良さそう。
あとは触らなくて大丈夫。

これで、userをcreateアクションが実行されれば、sendgridを通じてメールは送信できるようになる。

環境変数を設定する

もちろんこのままgithubにあげたりすると、enviroment.rbに記載しているパスワードやuser_nameがダダ漏れなので、環境変数に入れてあげます。

ハマったポイント

createアクションが実行されても、なぜかメールが届かなくて、コンソールで確認したら以下のようなエラーが発生していた。

$ @user = User.create(name:〇〇,email:〇〇)
$ UserMailer.send_signup_email(@user).deliver
Rendering user_mailer/send_signup_email.html.erb within layouts/mailer
  Rendered user_mailer/send_signup_email.html.erb within layouts/mailer (0.6ms)
UserMailer#send_signup_email: processed outbound mail in 387.6ms
objc[5386]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[5386]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

わけわかめと思いながら、色々調べているとこちらにたどり着き、最終的に
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES rails sを実行すればいけました。
その前に、bash_profileの中に export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES も記載しました。この辺良く分かってないです。:thinking:
原因はMacOS上のruby特有の汎用的なエラーであること、また解決方法としてはOBJC_DISABLE_INITIALIZE_FORK_SAFETYという環境変数をyesで設定すれば良いと書いてありました。

最後に

本当はsendgridのwebAPIが公開されているので、こちらで実装したかったのですが(推奨されている)、エラーに悩まされて、自分の力では解決できず、公式ページを参考に直接コードを書いて実装しました。
今までactionmailerも環境変数も勉強してこなかったので、非常に勉強になりました。sendegrid便利!!なはず笑

参考

sendgrid公式ページ、Ruby on Railsで送信する。
Not work on macOS Mojave: may have been in progress in another thread when fork() was called.
Ruby on Railsで環境変数を設定する
NSPlaceholderDictionary initialize~というエラーが出て、railsがクラッシュする。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5