Need Help Using Net::SMTP


#1

I am trying to send email from my comcast email account (say
removed_email_address@domain.invalid) to my yahoo email accout (say removed_email_address@domain.invalid) from a ruby
script using net/smtp:

require ‘net/smtp’
Net::SMTP.start(“smtp.comcast.net”, 25,“localhost”,“user”,“pass”) do
|smtp|
smtp.send_message “hello”,“removed_email_address@domain.invalid”,“removed_email_address@domain.invalid”
end

After trying the above ruby in irb I get the following message with no
email delivered:

=> “250 Mail queued for delivery.\n”

I don’t understand how the third argument to Net::SMTP.start should be
specified; its called “helo” and documentation says it defaults to
‘localhost.localdomain’. I would appreciate it if anyone could point out
what I am doing wrong.

I am pretty sure I have the smtp, pop3 and ports identified correctly
as I can send email using the command line utility postie
(http://www.infradig.com/postie/index.shtml):

postie -esmtp -host:smtp.comcast.net -to:removed_email_address@domain.invalid
-from:removed_email_address@domain.invalid -s:subject -msg:hello -user:user -pass:pass

#Incoming mail (POP3): mail.comcast.net
#Incoming mail (POP3): 110
#Outgoing mail (SMTP): smtp.comcast.net
#Outgoing mail (SMTP): port is set to 25


#2

On Thursday 29 December 2005 06:59 pm, Dan D. wrote:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/167128
The “250 Mail queued for delivery.\n” message is from the mail server.
You
may be getting caught by a spam filter. The email is supposed to be
received.

Tsume


#3

You may be getting caught by a spam filter.

I can post email using postie so I can’t see a problem with the basic
credentials being sent. There must be some configuration of Net::SMTP
that will allow me to email from Ruby. Anyone have a clue what to do?


#4

On 2005-12-29, Dan D. removed_email_address@domain.invalid wrote:

–0-1020623145-1135855120=:46005
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

You may be getting caught by a spam filter.

I can post email using postie so I can’t see a problem with the basic c
redentials being sent. There must be some configuration of Net::SMTP that
will allow me to email from Ruby. Anyone have a clue what to do?

$ ri send_message
------------------------------------------------- Net::SMTP#send_message
send_message( msgstr, from_addr, *to_addrs )

 Sends msgstr as a message. Single CR ("\r") and LF ("\n") found in
 the msgstr, are converted into the CR LF pair. You cannot send a
 binary message with this method. msgstr should include both the
 message headers and body.

“…both the message headers and the body” does not seem to be covered
by a
string like “hello”, in other words you are complying to SMTP but not to
RFC
822. Lacking a From/Reply-To address you do not receive the Delivery
Failure
message, I suppose. An (incomplete!) snippet from what I use:

header = [
  "To: #{to.join(', ')}",
  "Subject: #{subject}",
  "Date: #{Time.now.rfc822}",
  "From: Arena II <#{ArenaMail}>"
]
Net::SMTP.start("localhost", 25, SiteDNS) { |smtp|
  smtp.sendmail(header.join("\n")+"\n\n"+msg, ArenaMail, rcpts)
}

(in which I should use \r\n but as the docs say, it does not matter)

Hth,
Kero.

PS: there are higher level mail libraries for Ruby, iirc.


#5

On Thu, 29 Dec 2005 12:15:41 -0000, Ross B.
removed_email_address@domain.invalid wrote:

A couple of things you might check:

No sender/subject is also a trigger for many spam filters I believe…


#6

On Thu, 29 Dec 2005 11:18:52 -0000, Dan D. removed_email_address@domain.invalid
wrote:

You may be getting caught by a spam filter.
I can post email using postie so I can’t see a problem with the basic
credentials being sent. There must be some configuration of Net::SMTP
that will allow me to email from Ruby. Anyone have a clue what to do?

Seriously, 250 is the SMTP +OK code so your mail is good to go. My guess
is it’s getting rejected somewhere down the line.

A couple of things you might check:

SMTP HELO is often used to determine authorization
to relay mail, and it should be the domain you're
sending mail from. So from your example I guess you
want comcast.net.

Most SMTP accounts don't require username/password,
and if they do you'll need to specify an auth type
too. Check out your account settings in your mailer
to see what you want to use. It's the last arg to
Net::SMTP.start.

Hope that helps,


#7

this is my email tester script. worth a shot.

#!/bin/env ruby

This is used to send email.

require ‘net/smtp’

# Helper method.
# Append _appendage_ to end of string if it already doesn't exist
# at the end of the string.
class String #:nodoc:
	def appendIfMissing(appendage)
		return self if appendage.nil? || appendage.size < 1
		return appendage if size < 1
		if self[-appendage.size..-1] == appendage
			self
		else
			self + appendage
		end
	end
end


class String #:nodoc:
  def blank?
	empty? || strip.empty?
  end
end


# Print an error message.
def err(msg, printRubyErr=false, fatal=true) #:nodoc:
	STDERR.print "\n### ERROR: #{msg}\n\n"
	STDERR.print "\n#{$!}\n\n" if printRubyErr
	exit if fatal
	"### ERROR: #{msg}\n#{$!}\n"
end



# simple check of email address.
def checkMailAddress(address, descr) #:nodoc:
	address.strip!
	addr = address[/<?\w+@\w+\.\w+>?$/]
	if addr.blank?
		err(descr,false,false)
		return nil
	end
	addr
end


# Send email.
def mail( od )
	# The email is composed of the 'From', 'To', and 'Subject' fields, 

followed by the body text.
# Strip off leading white space.
(msgstr = <<-END_OF_MAIL_MESSAGE).gsub!(/^\s+/, ‘’)
From: #{od[’-=’]}
To: #{od[’-t’]}
Subject: #{od[’-j’].blank? ? ‘No Subject’ : od[’-j’]}

	END_OF_MAIL_MESSAGE

	msgstr += od['-b']

	return if (addr_from = checkMailAddress(od['-='], "no 'From' address 

(#{od[’-=’]})") ).nil?
return if (addr_to = checkMailAddress(od[’-t’], “no ‘To’ address
(#{od[’-t’]})”) ).nil?

	# The email is actually sent here.
	begin
		Net::SMTP.start(od['-m'], 25, od['-n'], od['-S'], od['-P'], :login) { 

|smtp|
smtp.send_message msgstr, addr_from, addr_to
}

		puts "-- mail sent to #{addr_to}" if od['-V']
	rescue Exception => ex
		err("unable to send mail.\n#{msgstr}\n#{$!}\naddr 

from:#{addr_from}\naddr to:#{addr_to}", true)
end
end # mail

od = {  '-=' => 'My Long Name<removed_email_address@domain.invalid>', # mail from
	'-t' => 'My Long Name<removed_email_address@domain.invalid>', # mail to
	'-j' => 'This is a test',		# mail subject
	'-b' => 'Body text of the email.',	# mail body text
	'-m' => 'smtp.XXX.net',			# mail server
	'-n' => 'www.XXX.net',			# domain sending mail from
	'-S' => 'mailusername',			# mail user name
	'-P' => 'super_secret_password',	# mail password
	'-V' => true }                        # verbose?

mail od

END


#8

Dan D. wrote:

I don’t understand how the third argument to Net::SMTP.start should be specified; its called “helo” and documentation says it defaults to ‘localhost.localdomain’. I would appreciate it if anyone could point out what I am doing wrong.

You should probably read the SMTP protocol spec in the SMTP RFC linked
to at the top of the documentation for Net::SMTP (RFC2821). Maybe your
copy is out of date, in which case try
URL:http://www.ruby-doc.org/stdlib/

You should also note the bit that says:

This library does NOT provide functions to compose internet mails.
You
must create them by yourself. If you want better mail support, try
RubyMail or TMail. You can get both libraries from RAA.
(www.ruby-lang.org/en/raa.html)

The thing you are attempting to send (the word “hello”) is not an
Internet format e-mail. Look at the example for Net::SMTP, or read
RFC2822, also linked to from the documentation for Net::SMTP.

The HELO parameter is the fully-qualified DNS name of your system. The
server you are connecting to may or may not choose to check that (a) it
resolves to a real IP address, and (b) it resolves to the same IP
address you’re connecting from. Again, the documentation mentions this.

mathew