class SesApi::Rails::Api
defines Mail::delivery_method
Constants
- ALGO
constants
- SERVICE
- TERM_STR
Public Class Methods
new(values)
click to toggle source
# File lib/ses_api/rails/api.rb, line 13 def initialize(values) self.settings = { }.merge!(values) self.conn = Faraday.new(:url => "https://#{SesApi::Rails.configuration.ses_endpoint}") do |faraday| faraday.request :url_encoded # form-encode POST params faraday.response :logger # log requests to STDOUT faraday.adapter Faraday.default_adapter # make requests with Net::HTTP end end
Public Instance Methods
build_destination_addresses(display_names)
click to toggle source
# File lib/ses_api/rails/api.rb, line 86 def build_destination_addresses(display_names) to = mail.to.each_with_index.map { |email, i| "&Destination.ToAddresses.member.#{i+1}=#{format_email(email, display_names)}"}.join cc = mail.cc.each_with_index.map { |email, i| "&Destination.CcAddresses.member.#{i+1}=#{format_email(email, display_names)}"}.join if mail.cc.present? bcc = mail.bcc.each_with_index.map { |email, i| "&Destination.BccAddresses.member.#{i+1}=#{format_email(email, display_names)}"}.join if mail.bcc.present? return "#{to}#{cc}#{bcc}" end
create_auth_header(request_datetime, credential_scope, hashed_payload, headers)
click to toggle source
# File lib/ses_api/rails/api.rb, line 105 def create_auth_header(request_datetime, credential_scope, hashed_payload, headers) signing_key = create_signing_key(request_datetime) signed_headers = headers.sort.map { |k,v| "#{k.downcase}" }.join(";") string_to_sign = create_str_to_sign(request_datetime, credential_scope, headers, hashed_payload, signed_headers) signing_signature = create_signature(signing_key, string_to_sign) return "#{ALGO} Credential=#{SesApi::Rails.configuration.access_key_id}/#{credential_scope}, SignedHeaders=#{signed_headers}, Signature=#{signing_signature}" end
create_canonical_request(headers, hashed_payload, signed_headers)
click to toggle source
# File lib/ses_api/rails/api.rb, line 97 def create_canonical_request(headers, hashed_payload, signed_headers) http_request_method = "POST" canonical_uri = "/" canonical_query_str = "" canonical_headers = headers.sort.map { |k,v| "#{k.downcase}:#{v.strip}\n"}.join canonical_request = [http_request_method, canonical_uri, canonical_query_str, canonical_headers, signed_headers, hashed_payload].join("\n") end
create_credential_scope(request_datetime)
click to toggle source
# File lib/ses_api/rails/api.rb, line 52 def create_credential_scope(request_datetime) "#{request_datetime[0,8]}/#{SesApi::Rails.configuration.aws_region}/#{SERVICE}/#{TERM_STR}" end
create_datetime()
click to toggle source
# File lib/ses_api/rails/api.rb, line 46 def create_datetime # returns ISO8601 Basic format YYYYMMDD'T'HHMMSS'Z' timestamp = Time.now.getutc timestamp.strftime('%Y%m%dT%H%M%SZ') end
create_display_names()
click to toggle source
# File lib/ses_api/rails/api.rb, line 73 def create_display_names display_names = {} mail.header.fields.each do |f| if %w[To From Cc Bcc].include? f.name f.address_list.addresses.each do |a| email = "#{a.local}@#{a.domain}" display_names.[]=(email, a.display_name) ? a.display_name.present? : a.local end end end display_names end
create_payload()
click to toggle source
# File lib/ses_api/rails/api.rb, line 56 def create_payload display_names = create_display_names destinations = build_destination_addresses(display_names) from = "&Source=#{format_email(mail.from[0], display_names)}" subject = "&Message.Subject.Data=#{CGI::escape(mail.subject)}" if mail.body.raw_source.present? body = "&Message.Body.Html.Data=#{CGI::escape(mail.body.raw_source)}&Message.Body.Html.Charset=UTF-8" body << "&Message.Body.Text.Data=#{CGI::escape(mail.body.raw_source)}&Message.Body.Text.Charset=UTF-8" else body = "&Message.Body.Html.Data=#{CGI::escape(mail.html_part.body.raw_source)}&Message.Body.Html.Charset=UTF-8" body << "&Message.Body.Text.Data=#{CGI::escape(mail.text_part.body.raw_source)}&Message.Body.Text.Charset=UTF-8" end payload = "AWSAccessKeyId=#{SesApi::Rails.configuration.access_key_id}&Action=SendEmail#{destinations}#{body}#{subject}#{from}" end
create_signature(signing_key, string_to_sign)
click to toggle source
# File lib/ses_api/rails/api.rb, line 125 def create_signature(signing_key, string_to_sign) hexhmac(signing_key, string_to_sign) end
create_signing_key(request_datetime)
click to toggle source
# File lib/ses_api/rails/api.rb, line 113 def create_signing_key(request_datetime) key_date = hmac("AWS4" + SesApi::Rails.configuration.secret_access_key, request_datetime[0,8]) key_region = hmac(key_date, SesApi::Rails.configuration.aws_region) key_service = hmac(key_region, SERVICE) key_credentials = hmac(key_service, TERM_STR) end
create_str_to_sign(request_datetime, credential_scope, headers, hashed_payload, signed_headers)
click to toggle source
# File lib/ses_api/rails/api.rb, line 120 def create_str_to_sign(request_datetime, credential_scope, headers, hashed_payload, signed_headers) canonical_request = create_canonical_request(headers, hashed_payload, signed_headers) return "#{ALGO}\n#{request_datetime}\n#{credential_scope}\n#{Digest::SHA256.hexdigest(canonical_request)}" end
deliver!(mail)
click to toggle source
# File lib/ses_api/rails/api.rb, line 28 def deliver!(mail) self.mail = mail dt = create_datetime credential_scope = create_credential_scope(dt) response = conn.post do |req| req.body = create_payload hashed_payload = Digest::SHA256.hexdigest(req.body) #.downcase headers = { :'X-Amz-Date' => dt, Host: "#{SesApi::Rails.configuration.ses_endpoint}", :'X-Amz-Content-Sha256' => hashed_payload } headers.each do |addtl_header, value| req.headers[addtl_header.to_s.camelize] = value end req.headers['Authorization'] = create_auth_header(dt, credential_scope, hashed_payload, headers) end raise SesApi::Rails::SesError if response.status != 200 end
format_email(email, display_names)
click to toggle source
# File lib/ses_api/rails/api.rb, line 93 def format_email(email, display_names) CGI::escape("#{display_names[email]}<#{email}>") end
hexhmac(key, value)
click to toggle source
# File lib/ses_api/rails/api.rb, line 133 def hexhmac(key, value) OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value) end
hmac(key, value)
click to toggle source
# File lib/ses_api/rails/api.rb, line 129 def hmac(key, value) OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value) end
settings()
click to toggle source
# File lib/ses_api/rails/api.rb, line 24 def settings {} end