class SendGridActionMailerAdapter::DeliveryMethod

Attributes

settings[R]

Public Class Methods

new(settings) click to toggle source

Initialize this instance.

This method is expected to be called from Mail::Message class.

@params [Hash] settings settings parameters which you want to override. @options settings [String] :api_key Your SendGrid Web API key. @options settings [String] :host Base host FQDN of API endpoint. @options settings [Hash] :request_headers Request headers which you want to override. @options settings [String] :version API version string, eg: 'v3'. @options settings [Integer] :retry_max_count Count for retry, Default is 0(Do not retry). @options settings [Integer, Float] :retry_wait_sec Wait seconds for next retry, Default is 1.

# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 24
def initialize(settings)
  @settings = ::SendGridActionMailerAdapter::Configuration.settings.merge(settings)
  @logger = @settings[:logger] || ::Logger.new(nil)
end

Public Instance Methods

deliver!(mail) click to toggle source

Deliver a mail via SendGrid Web API.

This method is called from Mail::Message#deliver!.

@param [Mail::Message] mail Mail::Message object which you want to send. @raise [SendGridActionMailerAdapter::ValidationError] when validation error occurred. @raise [SendGridActionMailerAdapter::ApiError] when SendGrid Web API returns error response.

# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 36
def deliver!(mail)
  sendgrid_mail = ::SendGridActionMailerAdapter::Converter.to_sendgrid_mail(mail)

  if mail[:remove_from_bounces]
    remove_to_addrs_from_bounces(sendgrid_mail)
  end

  with_retry(**@settings[:retry]) do
    @logger.info("Calling sendMail API, #{extract_log_info(sendgrid_mail)}")
    response = sendgrid_client.mail._('send').post(request_body: sendgrid_mail.to_json)
    @logger.info("End calling sendMail API, status_code: #{response.status_code}")
    handle_response!(response)
  end
end

Private Instance Methods

extract_log_info(sendgrid_mail) click to toggle source
# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 90
def extract_log_info(sendgrid_mail)
  {
    subject: sendgrid_mail.subject,
    personalizations: sendgrid_mail.personalizations,
  }
end
handle_response!(response) click to toggle source

@see sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html

# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 98
def handle_response!(response)
  case response.status_code.to_i
  when (200..299)
    response
  when (400..499)
    raise ::SendGridActionMailerAdapter::ApiClientError, response
  else
    raise ::SendGridActionMailerAdapter::ApiUnexpectedError, response
  end
end
remove_to_addrs_from_bounces(sendgrid_mail) click to toggle source

@param [::SendGrid::Mail]

# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 58
def remove_to_addrs_from_bounces(sendgrid_mail)
  sendgrid_mail.personalizations.each do |personalization|
    personalization['to'].each do |to|
      @logger.info("Calling deleteBounce API, #{to}")
      # success => 204, not_found => 404
      sendgrid_client.suppression.bounces._(to['email']).delete
      @logger.info('End calling deleteBounce API')
    end
  end
end
sendgrid_client() click to toggle source
# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 53
def sendgrid_client
  @sendgrid_client ||= ::SendGrid::API.new(**@settings[:sendgrid]).client
end
with_retry(max_count:, wait_seconds:) { || ... } click to toggle source
# File lib/sendgrid_actionmailer_adapter/delivery_method.rb, line 69
def with_retry(max_count:, wait_seconds:)
  tryable_count = max_count + 1
  begin
    tryable_count -= 1
    yield
  rescue ::SendGridActionMailerAdapter::ApiClientError => e
    @logger.error(e)
    raise
  rescue StandardError => e
    if tryable_count > 0
      @logger.warn("Retry mail sending, tryable_count: #{tryable_count}")
      @logger.warn(e)
      sleep(wait_seconds)
      retry
    end
    @logger.error('Give up retrying')
    @logger.error(e)
    raise
  end
end