lib/mandrill_dm/message.rb
require 'base64'
module MandrillDm
class Message # rubocop:disable ClassLength
attr_reader :mail
def initialize(mail)
@mail = mail
end
# Returns a Mandrill API compatible attachment hash
def attachments
regular_attachments = mail.attachments.reject(&:inline?)
regular_attachments.collect do |attachment|
{
name: attachment.filename,
type: attachment.mime_type,
content: Base64.encode64(attachment.body.decoded)
}
end
end
# Mandrill uses a different hash for inlined image attachments
def images
inline_attachments = mail.attachments.select(&:inline?)
inline_attachments.collect do |attachment|
{
name: attachment.cid,
type: attachment.mime_type,
content: Base64.encode64(attachment.body.decoded)
}
end
end
def auto_text
nil_true_false?(:auto_text)
end
def auto_html
nil_true_false?(:auto_html)
end
def bcc_address
return_string_value(:bcc_address)
end
def from_email
from.address
end
def from_name
from.display_name
end
def global_merge_vars
get_value(:global_merge_vars)
end
def headers
mail.header_fields.reduce({}) do |acc, field|
acc.merge(field.name => field.value)
end
end
def html
return mail.html_part.body.decoded if mail.html_part
return_decoded_body('text/html')
end
def template
return_string_value(:template)
end
def template_content
get_value(:template_content)
end
def important
mail[:important].to_s == 'true'
end
def inline_css
nil_true_false?(:inline_css)
end
def ip_pool
return_string_value(:ip_pool)
end
def merge
nil_true_false?(:merge)
end
def merge_language
return_string_value(:merge_language)
end
def merge_vars
get_value(:merge_vars)
end
def metadata
get_value(:metadata)
end
def preserve_recipients
nil_true_false?(:preserve_recipients)
end
def return_path_domain
return_string_value(:return_path_domain)
end
def send_at
value = get_value(:send_at)
value ? send_at_formatted_string(value) : nil
end
# mandrill expects `send_at` in UTC as `YYYY-MM-DD HH:MM:SS`
def send_at_formatted_string(obj)
return obj if obj.is_a?(String)
obj = obj.to_time if obj.is_a?(DateTime)
return obj.utc.strftime('%Y-%m-%d %H:%M:%S') if obj.is_a?(Time)
raise ArgumentError, 'send_at should be Time/DateTime or String'
end
def signing_domain
return_string_value(:signing_domain)
end
def subaccount
return_string_value(:subaccount)
end
def subject
mail.subject
end
def tags
collect_tags
end
def text
return mail.text_part.body.decoded if mail.text_part
return_decoded_body('text/plain')
end
def to
combine_address_fields.reject(&:nil?).flatten
end
def track_clicks
nil_true_false?(:track_clicks)
end
def track_opens
nil_true_false?(:track_opens)
end
def tracking_domain
return_string_value(:tracking_domain)
end
def url_strip_qs
nil_true_false?(:url_strip_qs)
end
def view_content_link
nil_true_false?(:view_content_link)
end
def to_json # rubocop:disable MethodLength, AbcSize
json_hash = {
auto_html: auto_html,
auto_text: auto_text,
bcc_address: bcc_address,
from_email: from_email,
from_name: from_name,
global_merge_vars: global_merge_vars,
headers: headers,
html: html,
important: important,
inline_css: inline_css,
merge: merge,
merge_language: merge_language,
merge_vars: merge_vars,
metadata: metadata,
preserve_recipients: preserve_recipients,
return_path_domain: return_path_domain,
signing_domain: signing_domain,
subaccount: subaccount,
subject: subject,
tags: tags,
text: text,
to: to,
track_clicks: track_clicks,
track_opens: track_opens,
tracking_domain: tracking_domain,
url_strip_qs: url_strip_qs,
view_content_link: view_content_link
}
json_hash[:attachments] = attachments if attachments?
json_hash[:images] = images if inline_attachments?
json_hash
end
private
# Returns an array of tags
def collect_tags
mail[:tags].to_s.split(', ').map { |tag| tag }
end
# Returns a single, flattened hash with all to, cc, and bcc addresses
def combine_address_fields
%w[to cc bcc].map do |field|
hash_addresses(mail[field])
end
end
# Returns a Mail::Address object using the from field
def from
address = mail[:from].formatted
Mail::Address.new(address.first)
end
# rubocop:disable Metrics/AbcSize
def get_value(field)
if mail[field].respond_to?(:unparsed_value) # `mail` gem > 2.7.0
mail[field].unparsed_value
elsif mail[field].instance_variable_defined?('@unparsed_value') # `mail` gem = 2.7.0
mail[field].instance_variable_get('@unparsed_value')
elsif mail[field].instance_variable_defined?('@value') # `mail` gem < 2.7.0
mail[field].instance_variable_get('@value')
end
end
# rubocop:enable Metrics/AbcSize
# Returns a Mandrill API compatible email address hash
def hash_addresses(address_field)
return nil unless address_field
address_field.formatted.map do |address|
address_obj = Mail::Address.new(address)
{
email: address_obj.address,
name: address_obj.display_name,
type: address_field.name.downcase
}
end
end
def attachments?
mail.attachments.any? { |a| !a.inline? }
end
def inline_attachments?
mail.attachments.any?(&:inline?)
end
def return_decoded_body(mime_type)
mail.mime_type == mime_type ? mail.body.decoded : nil
end
def return_string_value(field)
mail[field] ? mail[field].to_s : nil
end
def nil_true_false?(field)
return nil if mail[field].nil?
mail[field].to_s == 'true'
end
end
end