Last active
August 29, 2015 14:07
-
-
Save hadees/bbfda3e2002e57f340bc to your computer and use it in GitHub Desktop.
Better way to create the crazy email Mailgun wants you to send for batch emails through SMTP.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ActionMailer::Base.register_interceptor(MailgunBatch) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MailgunBatch | |
# This is where the magic happens | |
def self.delivering_email(message) | |
if batch?(message) | |
add_recipient_variables(message) | |
end | |
end | |
# Have either of the batch headers been set? | |
def self.batch?(message) | |
message.header_fields.any? { |header_field| header_field.name.to_s.starts_with?('X-Mailgun-Batch') } | |
end | |
def self.add_recipient_variables(message) | |
# Building the individual recipient email | |
recipient_message = Mail.new(message) | |
recipient_message.to = '%recipient%' | |
recipient_variables = retrive_recipient_variables(recipient_message) | |
recipient_variables.reverse_merge! extract_to_addresses(message) | |
# Mail gun headers should only be on the main message | |
remove_headers_starting_with!(recipient_message, 'X-Mailgun') | |
message.body = nil # Clearing the body so we can build the new message | |
message.content_type = 'multipart/mailgun-variables' # Setting a special content type | |
# The recipient variables hash is converted to base64 encoded json then added to the message | |
message.add_part Mail::Part.new(content_type: 'application/json', content_transfer_encoding: 'base64', body: Base64.encode64(recipient_variables.to_json)) | |
#Removing the batch headers after already addeding the encoded json | |
remove_headers_starting_with!(message, 'X-Mailgun-Batch') | |
# Adding the customized message with headers | |
message.add_part Mail::Part.new(content_type: 'message/rfc822', body: recipient_message.encoded) | |
end | |
# Takes headers that are either json or hashes and merges them together into one hash | |
def self.retrive_recipient_variables(message) | |
message.header_fields.each_with_object({}) do |field, h| | |
if field.name === 'X-Mailgun-Batch-Variables' | |
case field.value | |
when Hash then h.merge! field.value | |
when String then h.merge! JSON.parse(field.value) | |
end | |
end | |
end | |
end | |
# Pulls out the to addresses and adds them as empty recipient variables | |
# Enable using headers['X-Mailgun-Batch-Send'] = true | |
def self.extract_to_addresses(message) | |
message.to.each.each_with_object({}) do |address, h| | |
h[address] = {} | |
end | |
end | |
# Delete any headers that start with the given string | |
def self.remove_headers_starting_with!(message, str) | |
message.header.fields.delete_if { |header| header.name.to_s.starts_with?(str) } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment