class Griddler::Ses::Adapter

Attributes

sns_json[R]

Public Class Methods

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

Public Instance Methods

normalize_params() click to toggle source
# File lib/griddler/ses/adapter.rb, line 19
def normalize_params
  # use sns_endpoint to parse and validate the sns message
  sns_msg = SnsEndpoint::AWS::SNS::Message.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/ses/adapter.rb, line 104
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/ses/adapter.rb, line 68
def bcc
  email_json['mail']['commonHeaders']['bcc'] || []
end
cc() click to toggle source
# File lib/griddler/ses/adapter.rb, line 64
def cc
  email_json['mail']['commonHeaders']['cc'] || []
end
confirm_sns_subscription_request() click to toggle source
# File lib/griddler/ses/adapter.rb, line 129
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/ses/adapter.rb, line 48
def email_json
  @email_json ||= JSON.parse(sns_json['Message'])
end
ensure_valid_notification_type!() click to toggle source
# File lib/griddler/ses/adapter.rb, line 125
def ensure_valid_notification_type!
  raise "Invalid SNS notification type (\"#{notification_type}\", expecting Received" unless notification_type == 'Received'
end
header_array() click to toggle source
# File lib/griddler/ses/adapter.rb, line 76
def header_array
  email_json['mail']['headers']
end
html_part() click to toggle source
# File lib/griddler/ses/adapter.rb, line 92
def html_part
  multipart? ? message.html_part.body.to_s : nil
end
message() click to toggle source
# File lib/griddler/ses/adapter.rb, line 80
def message
  @message ||= Mail.read_from_string(Base64.decode64(email_json['content']))
end
multipart?() click to toggle source
# File lib/griddler/ses/adapter.rb, line 84
def multipart?
  message.parts.count > 0
end
notification_type() click to toggle source
# File lib/griddler/ses/adapter.rb, line 52
def notification_type
  email_json['notificationType']
end
raw_headers() click to toggle source
# File lib/griddler/ses/adapter.rb, line 96
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/ses/adapter.rb, line 56
def recipients
  email_json['mail']['commonHeaders']['to']
end
sender() click to toggle source
# File lib/griddler/ses/adapter.rb, line 60
def sender
  email_json['mail']['commonHeaders']['from'].first
end
subject() click to toggle source
# File lib/griddler/ses/adapter.rb, line 72
def subject
  email_json['mail']['commonHeaders']['subject']
end
tempfile_for_attachment(attachment) click to toggle source
# File lib/griddler/ses/adapter.rb, line 116
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/ses/adapter.rb, line 88
def text_part
  multipart? ? message.text_part.body.to_s : message.body.to_s
end