class Griddler::AmazonSES::Adapter

Attributes

sns_json[R]

Public Class Methods

new(params) click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 9
def initialize(params)
  @sns_json = params
end
normalize_params(params) click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 13
def self.normalize_params(params)
  adapter = new(params)
  adapter.normalize_params
end

Public Instance Methods

normalize_params() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 18
def normalize_params
  sns_msg = AWS::SnsMessage.new sns_json
  raise "Invalid SNS message" unless sns_msg.authentic? && sns_msg.topic_arn.end_with?('griddler')

  case sns_msg.type
  when :SubscriptionConfirmation
    confirm_sns_subscription_request
    # this is not an actual email reply (and griddler has no way to bail at this point), so return empty parameters
    {}
  when :Notification
    ensure_valid_notification_type!
    sns_json.merge(
      to: recipients,
      from: sender,
      cc: cc,
      bcc: bcc,
      subject: subject,
      text: text_part,
      html: html_part,
      headers: raw_headers,
      attachments: attachment_files
    )
  else
    raise "Invalid SNS message type"
  end
end

Private Instance Methods

attachment_files() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 106
def attachment_files
  # also based on griddler-sparkpost (https://github.com/PrestoDoctor/griddler-sparkpost, MIT license);
  # AWS doesn't presently support sending the attachments from the message through SNS, but ready if they do!
  message.attachments.map do |attachment|
    ActionDispatch::Http::UploadedFile.new({
      type: attachment.mime_type,
      filename: attachment.filename,
      tempfile: tempfile_for_attachment(attachment)
    })
  end
end
bcc() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 66
def bcc
  email_json['mail']['commonHeaders']['bcc'] || []
end
cc() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 62
def cc
  email_json['mail']['commonHeaders']['cc'] || []
end
confirm_sns_subscription_request() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 131
def confirm_sns_subscription_request
  confirmation_endpoint = URI.parse(sns_json['SubscribeURL'])
  Net::HTTP.get confirmation_endpoint
end
email_json() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 46
def email_json
  @email_json ||= JSON.parse(sns_json['Message'])
end
ensure_valid_notification_type!() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 127
def ensure_valid_notification_type!
  raise "Invalid SNS notification type (\"#{notification_type}\", expecting Received" unless notification_type == 'Received'
end
force_body_to_utf_8_string(message_body) click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 94
def force_body_to_utf_8_string(message_body)
  message_body.to_s.force_encoding(Encoding::UTF_8)
end
header_array() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 74
def header_array
  email_json['mail']['headers']
end
html_part() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 90
def html_part
  multipart? ? force_body_to_utf_8_string(message.html_part.body) : nil
end
message() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 78
def message
  @message ||= Mail.read_from_string(Base64.decode64(email_json['content']))
end
multipart?() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 82
def multipart?
  message.parts.count > 0
end
notification_type() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 50
def notification_type
  email_json['notificationType']
end
raw_headers() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 98
def raw_headers
  # SNS gives us an array of hashes with name value, which we need to convert back to raw headers;
  # based on griddler-sparkpost (https://github.com/PrestoDoctor/griddler-sparkpost, MIT license)
  header_array.inject([]) { |raw_headers, sns_hash|
    raw_headers.push("#{sns_hash['name']}: #{sns_hash['value']}")
  }.join("\r\n")
end
recipients() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 54
def recipients
  email_json['mail']['commonHeaders']['to']
end
sender() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 58
def sender
  email_json['mail']['commonHeaders']['from'].first
end
subject() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 70
def subject
  email_json['mail']['commonHeaders']['subject']
end
tempfile_for_attachment(attachment) click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 118
def tempfile_for_attachment(attachment)
  filename = attachment.filename.gsub(/\/|\\/, '_')
  tempfile = Tempfile.new(filename, Dir::tmpdir, encoding: 'ascii-8bit')
  content = attachment.body.decoded
  tempfile.write(content)
  tempfile.rewind
  tempfile
end
text_part() click to toggle source
# File lib/griddler/amazon_ses/adapter.rb, line 86
def text_part
  force_body_to_utf_8_string(multipart? ? message.text_part.body : message.body)
end