lib/multi_mail/sendgrid/receiver.rb
module MultiMail
module Receiver
# SendGrid's incoming email receiver.
class SendGrid
include MultiMail::Receiver::Base
# Initializes a SendGrid incoming email receiver.
#
# @param [Hash] options required and optional arguments
# @option option [Float] :spamassassin_threshold the Spamassassin score
# needed to flag a message as spam
def initialize(options = {})
super
@spamassassin_threshold = options[:spamassassin_threshold] || 5
end
# Transforms the content of SendGrid's webook into a list of messages.
#
# @param [Hash] params the content of Mandrill's webhook
# @return [Array<MultiMail::Message::SendGrid>] messages
# @see http://sendgrid.com/docs/API_Reference/Webhooks/parse.html
def transform(params)
# Make variables available to the `encode` method.
@params = params
@charsets = JSON.load(params['charsets'])
# Mail changes `self`.
this = self
message = Message::SendGrid.new do
# SendGrid includes a `charsets` parameter, which describes the
# encodings of the `from`, `to`, `cc` and `subject` parameters, which
# we don't need because we parse the headers directly.
# @see http://sendgrid.com/docs/API_Reference/Webhooks/parse.html#-Character-Sets-and-Header-Decoding
header params['headers']
# The following are redundant with `headers`:
#
# from params['from']
# to params['to']
# cc params['cc']
# subject params['subject']
text_part do
body this.encode('text')
end
if params.key?('html')
html_part do
content_type 'text/html; charset=UTF-8'
body this.encode('html')
end
end
1.upto(params['attachments'].to_i) do |n|
attachment = params["attachment#{n}"]
add_file(this.class.add_file_arguments(attachment))
end
end
# Extra SendGrid parameters.
message.dkim = params['dkim']
message.spf = params['SPF']
message.spam_report = params['spam_report']
message.spam_score = params['spam_score']
# Discard `envelope`, which contains `to` and `from`, and the
# undocumented `attachment-info`.
[message]
end
# Returns whether a message is spam.
#
# @param [Mail::Message] message a message
# @return [Boolean] whether the message is spam
def spam?(message)
message.spam_score.to_f > @spamassassin_threshold
end
def encode(key)
if @charsets.key?(key)
if @params[key].respond_to?(:force_encoding)
@params[key].force_encoding(@charsets[key]).encode('UTF-8')
else
Iconv.conv('UTF-8', @charsets[key], @params[key])
end
else
@params[key]
end
end
end
end
end