Help with emailing attachments with Ruby...


G

grooveska

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 Fulton'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', '(e-mail address removed)',
'xxx', :plain) do |smtp|
smtp.sendmail(mailtext, '(e-mail address removed)', ['(e-mail address removed)'])
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*[email protected]%X97,L+"P*57-E<DE$+%!A9V5S
M(%)E8V5I=F5D+"!,:6UI="[email protected]<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,[email protected]"C4W,S(P,C(S.3(L,C`U+#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!
 
Ad

Advertisements

G

Gregory Brown

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 Fulton'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 => "(e-mail address removed)"

r.send_to("(e-mail address removed)") 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.
 
G

grooveska

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:smtp+server

2. 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 = "(e-mail address removed)"
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 = '(e-mail address removed)'
fromaddress = '(e-mail address removed)'
#
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.
 
G

Gregory Brown

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.
 
Ad

Advertisements

B

Bill Guindon

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?
 
G

Gregory Brown

That does raise the question... should it be it's own library?

It is :)

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.
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top