2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Net::SMTPAuthenticationError: 530-5.7.0 Authentication Requiredのエラー対処法

Posted at

この記事はプログラミング学習者がアプリ開発中に躓いた内容を備忘録として記事におこしたものです。内容に不備などあればご指摘頂けると助かります。

記事投稿の背景

Xのクローンサイトを制作している時に通知機能の実装で色々と躓いたので、知識整理も兼ねて記事として残すことにしました。

遭遇したエラーメッセージ

エラーメッセージ
== Preparing database ==
rails aborted!
Net::SMTPAuthenticationError: 530-5.7.0 Authentication Required. For more information, go to
/myapp/db/seeds.rb:159:in `find_or_create_user'
/myapp/db/seeds.rb:167:in `<main>'

このエラーメッセージは、SMTPサーバーが認証を要求しているにも関わらず、適切な認証情報が提供されていないためにメールの送信ができないことを示しています。
私の場合、このエラーはGithub Actions中に発生しました。
seeds.rbにメール送信機構を持った通知機能を実装しているのですが、そのコードを検証中に発生したエラーです。

seeds.rb
ActionMailer::Base.deliveries.clear if defined?(ActionMailer::Base)

def find_or_create_user(email, phone_number, birthday)
  User.find_by(email:) || User.create!(email:, phone_number:, birthday:,
                                       password: 'password')  # 159行目
end

def find_or_create_tweet(content, user)
  Tweet.find_by(content:, user:) || Tweet.create!(content:, user:)
end

user1 = find_or_create_user('sample@gmail.com', '050-1234-5678', '2000-01-01')  # 167行目
tweet1 = find_or_create_tweet('You are fired.', user1)

favorite1 = Favorite.create!(
  tweet_id: tweet1.id,
  user_id: user1.id
)
if (Rails.env.production? || Rails.env.development?) && !ENV['CI']
  favorite1.tweet.create_notification_favorite!(favorite1.user)
end

user2 = find_or_create_user('apprentice@gmail.com', '070-1234-5678', '2000-12-01')
tweet2 = find_or_create_tweet('Enough!!', user2)

favorite2 = Favorite.create!(
  tweet_id: tweet2.id,
  user_id: user2.id
)
if (Rails.env.production? || Rails.env.development?) && !ENV['CI']
  favorite2.tweet.create_notification_favorite!(favorite2.user)
end

user3 = find_or_create_user('rookie@gmail.com', '080-1234-5678', '2002-12-01')
tweet3 = find_or_create_tweet("I'm done.", user3)

retweet1 = Retweet.create!(
  tweet_id: tweet3.id,
  user_id: user3.id
)
if (Rails.env.production? || Rails.env.development?) && !ENV['CI']
  retweet1.tweet.create_notification_retweet!(retweet1.user)
end

user4 = find_or_create_user('newface@gmail.com', '090-1234-5678', '2012-12-01')
tweet4 = find_or_create_tweet('You are welcome.', user4)

retweet2 = Retweet.create!(
  tweet_id: tweet4.id,
  user_id: user4.id
)
if (Rails.env.production? || Rails.env.development?) && !ENV['CI']
  retweet2.tweet.create_notification_retweet!(retweet2.user)
end

メール送信機能を含む通知機能を実装した部分

tweet.rb
  def create_notification_favorite!(current_user)
    temp = Notification.where(['visitor_id = ? and visited_id = ? and tweet_id = ? and action = ? ', current_user.id, user_id, id, 'favorite'])
    return if temp.present?

    notification = current_user.active_notifications.new(
      tweet_id: id,
      visited_id: user_id,,
      action: 'favorite'
    )
    # 自分の投稿に対するいいねの場合は、通知済みとする
    notification.checked = true if notification.visitor_id == notification.visited_id
    notification.save if notification.valid?
    # メール送信するメソッドにつながる部分
    NotificationMailer.send_notification(notification, User.find(user_id), current_user).deliver_now
  end

  def create_notification_retweet!(current_user)
    # 既に「リツイート」されているか検索
    temp = Notification.where(['visitor_id = ? and visited_id = ? and tweet_id = ? and action = ?', current_user.id, user_id, id, 'retweet'])
    # リツイートされていない場合のみ通知レコードを生成
    return if temp.present?

    notification = current_user.active_notifications.new(
      tweet_id: id,
      visited_id: user_id,
      action: 'retweet'
    )
    # 自分の投稿に対するリツイートの場合は通知済みとする
    notification.checked = true if notification.visitor_id == notification.visited_id
    notification.save if notification.valid?
    # メール送信するメソッドにつながる部分
    NotificationMailer.send_notification(notification, User.find(user_id), current_user).deliver_now
  end

実際にメール送信機能を処理しているActionMailerの設定

notification_mailer.rb
class NotificationMailer < ApplicationMailer
  def send_notification(notification, user, current_user)
    @visitor = current_user
    @notification = notification
    @user = user
    mail to: user.email, subject: '弊社サービスからのお知らせ'
  end
end

解決方法

エラー当初はGithub Actions内の処理が原因だと踏んでenvironments/test.rbの設定だけを修正して再度トライという流れを繰り返していました。
が、手を尽くしてもtest.rbの修正ではエラー解決に至りませんでした。
視点を変えて、他の環境でメール送信できていないのが原因ではないかと推測しました。
思いついた時点でのdevelopment.rbは以下の通りです。

developmen.rb - 変更前
  config.action_mailer.delivery_method = :smtp

  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    domain: 'gmail.com',
    port: 587,
    user_name: ENV['GMAIL_USERNAME'],
    password: ENV['GMAIL_PASSWORD'],
    authentication: :login
  }

試しに認証情報を外して、メールの送信はsmtpからletter opener webで確認するように変更してみました。

development.rb - 変更後
  config.action_mailer.delivery_method = :letter_opener_web

この変更をすることでエラーを解決することができました。

letter opener webとは
開発環境で使用するためのgemです。
デフォルトのブラウザでRuby on Railsの開発環境から送信処理したメールを閲覧することができます。このgemを導入することで開発環境でのメール送信設定が不要となります。実際にはメールを送信してはいないので、誤ってメールを相手に送信してしまうこともありません。
Railsサーバーが起動した状態でhttp://localhost:3000/letter_opener/にアクセスすれば開発環境で送信処理されたメールの内容を閲覧することができます。
また、letter opener webを利用する為の設定として上のコードで説明したdevelopment.rb以外に下記のコードを追記する必要があります。

routes.rb
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?

蛇足ですが、認証情報のuser_nameやpasswordをハードコード(直接入力)すればエラーが解消されることもあるそうです(特に環境変数がらみのエラー)。但し、環境変数を使用せずに直接秘匿情報を入力することはお勧めできないので、一時的な確認をする程度にとどめておくのが吉かと思います。

参考にしたサイト

gem letter_opener を試してみる
Net::SMTPAuthenticationError: 530-5.7.0 Authentication Required Rails Mailer using environmental variable on config
letter_opener_web

2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?