Send Gmail using Rails ActionMailer Class (ActionMailer를 이용하여 Gmail 전송하기)

Rails는 기본적으로 Mail 송/수신이 가능한 객체를 가지고 있습니다. 보통 웹에서 많이 사용하는 기능이기 때문에 미리 구현되어 있는 상태인데요, 라이브러리 의존성이나 복잡한 설정 없이 간단한 코드로 메일 처리가 가능합니다.

오늘은 Rails의 기본 객체인 ActionMailer를 이용하여 Gmail의 메일 송신하는 방법에 대해 정리해둡니다.

Pre-setting(Gmail & Google Accounts)

ActionMailer 사용하기 전 지메일에서 미리 세팅이 필요합니다. 우선 메일 전송에 필요한 정보부터 미리 확인해봅시다.

Gmail 설정 https://support.google.com/mail/answer/7126229?hl=ko

수신 메일(IMAP) 서버: imap.gmail.com
SSL 필요: 예
포트: 993
발신 메일(SMTP) 서버: smtp.gmail.com
SSL 필요: 예
TLS 필요: 예(사용 가능한 경우)
인증 필요: 예
SSL용 포트: 465
TLS/STARTTLS용 포트: 587
이름 또는 표시 이름: 이름
계정 이름, 사용자 이름 또는 이메일 주소 : 전체 이메일 주소 
비밀번호: Gmail 비밀번호

공식적으로 제공되는 내용은 이렇고, 우린 TLS/STARTTLS를 사용할거라서 smtp.gmail.com:587로 통신해주시면 됩니다. 우선 알아만둡시다.

두번째는.. 계정 권한인데요. 메일 전송할 구글 계정 로그인 후 아래 링크 들어가셔서 권한 조정을 해주셔야합니다. https://myaccount.google.com/u/2/lesssecureapps?pageId=none (에서 On으로 바꿔야합니다)

왜냐하면.. 2014년에 구글에서 계정보안 강화 정책으로 비신뢰 앱에 대해서는 기능처리를 기본적으로 하지 못하도록 막아뒀습니다.

As of July 15, 2014, Google increased its security measures and now blocks attempts from apps it deems less secure. You can change your Gmail settings here to allow the attempts. If your Gmail account has 2-factor authentication enabled, then you will need to set an app password and use that instead of your regular password. Alternatively, you can use another ESP to send email by replacing 'smtp.gmail.com' above with the address of your provider.

아마 설정해두지 않은 상태에선 정상적으로 전송이 되지 않을거라 미리 해두시면 좋습니다. (제가 삽질한 케이스..)

Write code!

바로 코드로 들어가볼텐데요, 우선 각 phase 별로 설정 파일에 mailer 관련 정보를 넣어주셔야 합니다.

environment/production or developements

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    domain:               'optons..',
    :user_name            => "gmail account",
    :password             => "gmail password",
    authentication:       'plain',
    enable_starttls_auto: true }
config.action_mailer.perform_deliveries = true

developements, production 모두 사용하실꺼면 둘다 해야합니다. 특별한건 없고 아까 이야기한대로 587포트에 smtp.gmail.com으로만 잘 넣어주시면 됩니다. 그리고 보통 계정명, 패스워드는 환경변수로 넣고 쓰거나 KMS 통해서 사용하시는게 더 안전할겁니다. (소스코드에 노출되면 좀 그렇잖아윰)

AppcationMailer

class ApplicationMailer < ActionMailer::Base
  layout 'mailer'
  def sendEmail(email, subject, contents)
    mail(to: email, subject: subject, body: contents, from: 'test@gmail.com', content_type: "text/html"
    )
  end
end

기본적으로 Rails앱을 생성하면 ApplicationMailer라는 객체가 생성됩니다. 이 객체는 ActionMailer에서 상속받은 객체로 메일 관련 메소드들을 사용할 수 있습니다. 단순하게 한두가지 케이스에 대해 메일 전송만 필요한거면 직접 ApplicationMailer에서 선언해주셔도 되지만 보통의 경우 ApplicationMailer를 상속받아서 새로 만드시는 경우가 많습니다. (내부 기능이 다른 여러 객체가 필요할 수 있으니..)

e.g

class ResetUserInfoMailer < ApplicationMailer
  def sendResetPassword
    #BlahBlah
    mail()
  end

  def sendResetId
    #BlahBlah
  end
end

여기서 잘 봐야할껀, mail() 함수입니다. 실제로 메일 전송을 위해 사용하는 메소드이며, ActionMailer에 정의되어 있습니다. :to , :subject , :body등 여러가지 인자값이 존재합니다. 자체한건 아래 주소 참고해주세요.

https://api.rubyonrails.org/v5.2.3/classes/ActionMailer/Base.html Code

def sendPostWithEmail(addr,title,contents)
  message = ApplicationMailer.sendEmail('test@gmail.com','mailtest','contents').deliver_now
  p message
end

mail()를 사용한다고 메일이 바로 전송되는건 아닙니다. 언제 전송할지(?) 결정하는 메소드가 있는데 보통은 바로 전송하는 케이스가 많으니 .deliver_now로 메일이 전송될 수 있도록 해줍시다.

그럼… sendPostWithEmail()를 호추하면 정상적으로 메일이 전송됩니다!