How to send a String as an attachment with the Mailgun API and RestClient

Sometimes at work, I run one-off reports on the server console and generate CSVs. I need an easy way to get the data off the server so I can look at it. Naturally, I decided to email it to myself. We use Mailgun for email, so I looked for a way to email a String as an attachment using RestClient.

Mailgun attachments must be multipart/form-encoded in the POST body. However, RestClient will only encode multipart if the argument responds to read and path, like a File object would. StringIO but responds to read but not path in Ruby 1.9, so it won’t work.

Monkey patching to the rescue! Defining a fake path method on the StringIO instance will allow sending it as an multipart/form-encoded file field.

my_string = "foobar"
string_io = StringIO.new(my_string)
def string_io.path
  "string_io.txt"
end

RestClient.post(Mailgun::API_ENDPOINT_URL, 
                :from => 'me@company.com',
                :to => 'me@company.com',
                :subject => 'hi',
                :text => 'hi. again.',
                :attachment => string_io,
                :multipart => true)