Help with emailing attachments with Ruby

I am working on a script that will send an email with a .csv file
attachment. I can get everything set correctly, and the email gets
sent properly. The problem is with the attachments. This maybe a MIME
thing instead of something wrong with my script. My script is based
on an example from Hal F.'s The Ruby Way book. If anyone has any
suggestions or see something I did wrong I would greatly appreciate
it. Below is my script. Below that is what the email I receive looks
like.

Thanks!

Begin Script

require ‘time’
require ‘net/smtp’
require ‘date’

##################################################################

This portion of the code assembles the filenames of the files

to be attached in the email

##################################################################

time = Time.now #set time object to the current time
month = time.month #grab the number of the month from the
current time
day = time.day #grab the day of the current time
year = time.year #grab the year of the current time

month = month + 1 #to match the format of Ian’s file names

if month < 10 #formatting
fullmonth = “0” + month.to_s
else
fullmonth = month.to_s
end

if day < 10
fullday = “0” + day.to_s
else
fullday = day.to_s
end #end of formatting

filename1 = “pagecount-” + year.to_s + fullmonth + fullday + “.csv”
#assemble file name

#####################################

Attach files and send the email

####################################

def text_plus_attachment (subject, body, filename)
marker = “MIME_boundary”
middle = “–#{marker}\n”
ending = “–#{middle}–\n”
content = “Content-Type: Multipart/Related; " + “boundary=#{marker};
" + “typw=text/plain”
head1 = <<-EOF
MIME-Version: 1.0
#{content}
Subject: #{subject}
EOF
binary = File.read(filename)
encoded = [binary].pack(“m”) # base64 econding
head2 = <<-EOF
Content-Description: “#{filename}”
Content-Type: text/plain; name=”#{filename}”
Content-Transfer-Encoding: Binary
Content-Disposition: attachment; filename="#{filename}"

EOF

#Return

head1 + middle + body + middle + head2 + encoded + ending

end

body = <<EOF
The GFIFax Monthly report is attached.
EOF

mailtext = text_plus_attachment(“Monthly Report”, body,
filename1)

Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
Net::SMTP.start(‘smtp.xxx.xxx’, ‘25’, ‘xxx.xxx’, ‘[email protected]’,
‘xxx’, :plain) do |smtp|
smtp.sendmail(mailtext, ‘[email protected]’, [‘[email protected]’])
end

End Script

Begin Email results (This is all in the body of the email
instead of in the headers)

MIME-Version: 1.0
Content-Type: Multipart/Related; boundary=MIME_boundary; typw=text/
plain
Subject: GFIFax Service Monthly Report --MIME_boundary The GFIFax
Monthly report is attached.
–MIME_boundary
Content-Description: “pagecount-20070631.csv”
Content-Type: text/plain; name=“pagecount-20070631.csv”
Content-Transfer-Encoding: Uencode
Content-Disposition: attachment; filename=“pagecount-20070631.csv”

M4V5N="!&87AE<RPL+I5<V5R240L(%!A9V5S(%-E;G0L($QI;6ET+"!/=F5R M86=E"C4W,S(P,C(Q,30L,BPU,"PP"C4W,S(P,C(Q,34L-"PU,"PP"C4W,S,T M,3<X-#8L,2PU,"PP"@H*4F5C96EV960@1F%X97,L+"P*57-E<DE$+%!A9V5S M(%)E8V5I=F5D+"!,:6UI="P@3W9E<F%G90HU-S,S-#$V,C,S+#$R+#$P,"PP M"C4W,S(P,C(Q,30L,RPQ,#L,HU-S,S-#$T.#@Y+#(Q.2PQ,#L,3$Y"C4W
M,S,T,38R-S$…@L.3DY.2PP"C4W,S(P,C(S.3(L,CU+#DY.3DL,HU-S,R
E,#(R,SDW+#4T+#DY.3DL,`HU-S,R,#(R,SDV+#$Q+#$P,“PP”@``
----MIME_boundary

End Email

I hope someone can help me out!

Thanks!

Hello,

Take a look at this:

and compare with what you get. I’d say your output is pretty different.

Anyway, I’d use Ruby-Mail or ActionMailer

http://rubyforge.org/projects/rubymail/
http://rubyforge.org/projects/actionmailer/


Pau Garcia i Quiles
http://www.elpauer.org
(Due to the amount of work, I usually need 10 days to answer)

Quoting grooveska [email protected]:

Thanks for the input.

I would really like to avoid going through all the steps of setting up
actionmailer for an email that gets sent once a month to one person.
That and I would like to avoid put a full blown rails install (even if
it is easy to do) on a server when a single ruby script is so close to
doing the job.

That looks awesome. Nice and simple. I’m going to give that a try.

Thanks!!

On 6/1/07, grooveska [email protected] wrote:

I am working on a script that will send an email with a .csv file
attachment. I can get everything set correctly, and the email gets
sent properly. The problem is with the attachments. This maybe a MIME
thing instead of something wrong with my script. My script is based
on an example from Hal F.'s The Ruby Way book. If anyone has any
suggestions or see something I did wrong I would greatly appreciate
it.

Hi, with ruport-util, that looks like this:

require “rubygems”
require “ruport”
require “ruport/util”

r = Ruport::Report.new

r.add_mailer :default,
:host => “mail.adelphia.net”,
:address => “[email protected]

r.send_to(“[email protected]”) do |mail|
mail.subject = “Hello”
mail.attach “foo.csv”
mail.text = “This is an email with attached csv”
end

I understand if you want to lighten the dependency load, so you might
just want to use the lib we wrap, MailFactory.

On 6/7/07, grooveska [email protected] wrote:

That looks awesome. Nice and simple. I’m going to give that a try.

Cool. If you run into any troubles, feel free to catch us on the ruport
list:
http://list.rubyreports.org

On Jun 8, 5:05 pm, grooveska [email protected] wrote:

I ended up just using mailfactory that was included with ruport-util,
and it worked great. I may work on reformatting the csv file know
that I have found a great tool for that task. So for anyone looking
for help with email attachments here is what worked for me:

Yeah, MailFactory is a seriously under-praised lib that really works
quite nicely.

On 6/8/07, Gregory B. [email protected] wrote:

On Jun 8, 5:05 pm, grooveska [email protected] wrote:

I ended up just using mailfactory that was included with ruport-util,
and it worked great. I may work on reformatting the csv file know
that I have found a great tool for that task. So for anyone looking
for help with email attachments here is what worked for me:

Yeah, MailFactory is a seriously under-praised lib that really works
quite nicely.

That does raise the question… should it be it’s own library?

I ended up just using mailfactory that was included with ruport-util,
and it worked great. I may work on reformatting the csv file know
that I have found a great tool for that task. So for anyone looking
for help with email attachments here is what worked for me:

  1. I had to get an updated copy of the smtp.rb file that included SSL/
    TLS support since our smtp server requires SSL/TLS. Found that here:

http://www.koders.com/ruby/fid4B13D002144D0985D12CB47DA041D8E59E0E8667.aspx?s=cdef%3Asmtp%2Bserver

  1. Then here is my script:

require ‘net/smtp’
require ‘rubygems’
require ‘mailfactory’
require ‘date’
require ‘time’

##################################################################

This portion of the code assembles the filenames of the files

to be attached in the email

##################################################################

time = Time.now #set time object to the current time
month = time.month #grab the number of the month from the
current time
day = time.day #grab the day of the current time
year = time.year #grab the year of the current time

month = month + 1 #to match the format of file names

if month < 10 #formatting
fullmonth = “0” + month.to_s
else
fullmonth = month.to_s
end

if day < 10
fullday = “0” + day.to_s
else
fullday = day.to_s
end #end of formatting

filename = “pagecount-” + year.to_s + fullmonth + fullday + “.csv”
#assemble file name
filename1 = “send_report-” + year.to_s + fullmonth + fullday +
“.csv” #assemble file name

mail = MailFactory.new()
mail.to = “[email protected]
mail.from = “sendername [email protected]
mail.subject = “Insert your subject line here”
mail.text = “Insert the body of the email text here.”
mail.attach(“pathtofile” + filename)
mail.attach(“pathtofile” + filename1)
toaddress = ‘[email protected]
fromaddress = ‘[email protected]

Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
Net::SMTP.start(‘smtp.xxx.xx’, ‘25’, ‘domain_name’, ‘userid’,
‘password’, :plain) do |smtp|
smtp.send_mail(mail.to_s(), fromaddress, toaddress)
end

Hopefully that will help some one out.

On 6/8/07, Bill G. [email protected] wrote:

Yeah, MailFactory is a seriously under-praised lib that really works
quite nicely.

That does raise the question… should it be it’s own library?

It is :slight_smile:

http://rubyforge.org/projects/mailfactory

The wrapper in ruport-util is quite light, so unless you’re using
other functionality from us, you’ll do just as well using MailFactory
directly. The only thing we really abstract is the Net::SMTP call and
add a barebones configuration system to it.

I think the work is from David Powers, but I’ve never had a problem
with the gem so I’ve never emailed him.

On 6/8/07, Gregory B. [email protected] wrote:

On 6/8/07, Bill G. [email protected] wrote:

Yeah, MailFactory is a seriously under-praised lib that really works
quite nicely.

That does raise the question… should it be it’s own library?

It is :slight_smile:

http://rubyforge.org/projects/mailfactory

Good to know. Thanks for the link.