Ruby send mail with smtp - ruby

I'm trying to send simple email via Ruby (no rails) on OS X, with XCode (which installs Ruby.) But I'm running into a problem with my smtp server which requires the email client to check mail before sending as a form of authentication.
How can I get Ruby to authenticate with the smtp server in a "POP" fashion before I can send mail? Not download mail; I only want to send html formatted email (eventually via Applescript calling Ruby, because Applescript doesn't support smtp), but the server requires that I check mail before I send.
Edit 4/05/10:
Well, that's embarrasing. Turned out to be simpler; I was trying to make it more complex than it needed to be. Even though my mail server requires pop before smtp, this sends OK:
require 'net/smtp'
message = <<MESSAGE_END
From: Private Person <me#fromdomain.com>
To: A Test User <test#todomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
MESSAGE_END
Net::SMTP.start('mail.mydomain.com', 25) do |smtp|
smtp.send_message message,
'mark#mydomain.com',
'mark#mydomain.com'
end
Edit 4/04/10:
With this I get a 500 unrecognized command error; the pop server is responding, though.
require 'net/smtp'
require 'net/pop'
message = <<MESSAGE_END
From: Private Person <me#fromdomain.com>
To: A Test User <test#todomain.com>
Subject: SMTP e-mail test
This is a test e-mail message.
MESSAGE_END
Net::POP3.start('mail.mydomain.com', 110, 'mark#mydomain.com', 'password') do |pop|
// If this line is included,
// I get a printout of the number
// of emails on the server
// right before the error:
//
// puts pop.n_mails end
Net::SMTP.start('mail.markratledge.com',
25,
'localhost',
'mark#mydomain.com', 'password', :plain) do |smtp|
smtp.send_message message, 'mark#mydomain.com',
'mark#mydomain.com'
end
end

POP before SMTP isn't one of the authentication types supported by Net::SMTP so I think you're going to have to use Net::POP3 to do your POP3 login e.g.
require 'net/pop'
pop = Net::POP3.start(addr, port, account, password)
pop.finish
Net::POP3 is in the Standard Library so should be available anywhere that Net::SMTP is.

If that doesn't make your server happy then Net::Telnet will let you send the raw commands yourself.

Related

Cannot send emails to yahoo using mailkit

I am creating a system that sends emails (pricing, orders, invoices, etc) to out customers. But due to the number of emails that ends up being, we hit limits when trying to send through gmail or any other mail client. And since these are all customer specific emails using a bulk sending client is not ideal.
So I have created a system using mailkit and others to send our emails from our own servers without needing to set up a relay or email server for sending. This works great with everyone (Gmail, outlook, etc) except for yahoo. For some reason when I connect and mailkit tries to switch to STL (via startstl) yahoo sends garbage and mail kit fails.
I have enabled all ssl and tsl protocols. And I have ServerCertificateValidationCallback always to return true. In fact ServerCertificateValidationCallback doesn't even get called.
The errors that are thrown start with:
A call to SSPI failed, see inner exception
then
The message received was unexpected or badly formatted.
If I try to connect to any of the other SMTP ports 465 or 587 the system just hangs.
This all happens when connecting, before the email is sent. So it cannot be a DKIM issue. And the SPF record is set up correctly. We don't have the reverse dns setup because we plan on sending from multiple servers with different IPs.
I don't know why yahoo is being so difficult.
Tried talking with MailKit, tries allowing all TLS and SSL connections. Tried finding any YAHOO support.
using (var client = new SmtpClient())
{
client.LocalDomain = "MyDomain";
// right now we don't care about all SSL certificates (in case the server supports STARTTLS)
client.ServerCertificateValidationCallback = (s, c, h, e) => {
return true;
};
client.SslProtocols = System.Security.Authentication.SslProtocols.Tls11 |
System.Security.Authentication.SslProtocols.Tls12 |
System.Security.Authentication.SslProtocols.Tls |
System.Security.Authentication.SslProtocols.Ssl3 |
System.Security.Authentication.SslProtocols.Ssl2;
client.CheckCertificateRevocation = false;
client.Connect("mta6.am0.yahoodns.net", 25, false); //<--- fails here
client.Send("test", fromMailBoxAddress, recipientsEmailBoxAddresses);
client.Disconnect(true);
}
To answer your question, I might have an idea why Yahoo is being so difficult - it's possibly your message construction. Verify your MimeMessage has the same exact email address for your From and Sender addresses. Ensure your ReplyTo only contains the Sender email address. I had both the sender and recipient email addresses in the ReplyTo and Yahoo did NOT like that. And, of course, you are using a Yahoo App password for authentication. Once I made these two changes, Yahoo sent the email successfully.
Settings
client.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
client.DeliveryStatusNotificationType = mail.DeliveryStatusNotificationType.Full;
await client.ConnectAsync("smtp.mail.yahoo.com", 587, SecureSocketOptions.StartTls);
await client.AuthenticateAsync(yourEmailAddress#yahoo.com, yourYahooAppPassword);
await client.SendAsync(Message);
await client.DisconnectAsync(true);
Research
Bad message construction breaks one of Yahoo's many policies. This was ONLY happening with SMTP via Yahoo. SMTP via Gmail and Outlook work fine. I kept comparing a simple MailMessage with MimeMessage message construction. MailMessage sent, MimeMessage failed, I kept getting a 550 request failed; mailbox unavailable response from Yahoo every time with my MimeMessage. I verified by using ProtocolLogger. My From was empty and that is one issue, and, I had the recipient in my ReplyTo. If I merely added the sender to the ReplyTo, it still throws that same 550 error. I had to ensure the sender was the only email in the ReplyTo.
Hope this helps.
Use client.Connect("mta6.am0.yahoodns.net", 25, SecureSocketOptions.None); if you want to disable STARTTLS or use client.Connect("smtp.mail.yahoo.com", 587, SecureSocketOptions.Auto); which works fine.
Not sure where you are getting "mta6.am0.yahoodns.net" from, but I can't even make a normal socket connection to that address.

Mandrill for outgoing mail in a mail client

I'm using Mandrill for my transaction email needs and it works great. Unfortunately very often when I send emails via my email client the emails go to the recipients spam folder.
Is there a way to use Mandrill for outgoing emails via a mail client (such as Apple Mail or Thunderbird)?
You can use the Mandrill's Outgoing Server (SMTP) Setting in the MailClient of your choice.
SMTP Settings
Outgoing Server: smtp.mandrillapp.com
Outgoing Server Port: 587
Auth Required: True
TLS: True
Username: complete email-id
Changing the MailClient is not probably going to mark your mails as legitimate.
There are multiple reasons for mail going to spam folder of recipient like:
Mandrill's IP address got blacklisted in recipient's SMTP (MX) server.
Your mail contains some links or content which is recognized as suspicious and hence recipient marks such mails as spam.
In short, mail getting marked as spam depends upon:
Sender SMTP server's reputation.
Sender's mail content.
Receiving SMTP (MX) (i.e recipient's) server business logic for mail classification.

How to get bounce emails from SparkPost without using webhooks?

We are working at the integration of our email application with SparkPost. The only issue we have is getting bounce emails from SparkPost to exclude them from future mailings. Our application retrieves bounce emails directly from the mail server. When the user uses the SparkPost SMTP settings in our software, he cannot retrieve and process bounce emails because SparkPost does not forward bounce messages to the user's bounce email address.
Webhooks will not work for us because they pull data in real time only. If our software is turned to off when the bounce email comes, the bounce will not be caught and will be lost for our software as there is no way to retrieve it at a later time.
So, please, let me know if there is a way to get bounce emails from SparkPost through API or via email just like Amazon SES does. Amazon SES simply forwards bounce emails to the email address specified by the user in our application (Return email header field in the message header).
If you cannot accept pushed data via HTTP like event webhooks or even our relay webhooks, the next best thing would be our Message Events API(https://www.sparkpost.com/api#/reference/message-events/message-events/search-for-message-events)
You could make a request to just get bounces for last hour like this:
https://api.sparkpost.com/api/v1/message-events?events=bounce,out_of_band
If you want more specific time ranges just add a from/to as well as a timezone if you need that:
https://api.sparkpost.com/api/v1/message-events?from=2015-09-10T00:00&to=2015-09-10T23:59&timezone=America/New_York
I wrote the following ruby code to get them as CSV:
require 'net/http'
require 'json'
require 'csv'
uri = URI('https://api.sparkpost.com/api/v1/message-events?events=bounce,out_of_band')
req = Net::HTTP::Get.new(uri)
req['Content-Type'] = 'application/json'
req['Authorization'] = ENV['API_KEY'] || raise('please provide API_KEY env variable')
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |https|
https.request(req)
end
bounces = JSON.parse(res.body)['results']
puts "#{bounces.count} bounces found"
CSV.open("bounces.csv", "wb") do |csv|
csv << %w(Timestamp Recipient Reason)
bounces.each do |bounce|
csv << [bounce['timestamp'], bounce['rcpt_to'], bounce['reason']]
end
end
Available as gist here: https://gist.github.com/schmijos/05d2f989c7a5854fe2cd31c666f61c39

AUTH not available (Net::SMTPAuthenticationError) in Ruby 1.9.2

I am trying to send mail from MS exchange server but I am getting error as
`check_auth_response': 503 #5.3.3 AUTH not available (Net::SMTPAuthenticationError)
The code I used to send mail is
require 'net/smtp'
require 'mail'
smtp = Net::SMTP.new('mycompanydomain',25)
smtp.start('mycompanydomain', 'name#company.com', 'pwd',:plain) do |smtp|
# code to send mail
end
Note: It works fine with Gmail account but fails for company account.
Any help would be useful.
Are you sure that your server supports AUTH? You can find out by:
If the connection is not encrypted:
telnet mycompanydomain 25
ehlo testing
It should respond with something that that says AUTH PLAIN in it. If it doesn't, your server does not support plain auth, it may list other auth methods. You may need to set it to one of them.
More information http://qmail.jms1.net/test-auth.shtml

Help with problem using mail in ruby

The error that I get is:
Net::SMTPFatalError: 550 5.7.1 Unable to relay for you#test.lindsaar.net
I am using mail-2.3.0
With Ruby 1.9
on windows XP.
The exact code I used is:
require 'rubygems'
require 'mail'
Mail.deliver do
from 'me#test.lindsaar.net'
to 'you#test.lindsaar.net'
subject 'Here is the image you wanted'
end
I don't understand what I am missing. Thanks for your help.
The error message comes from your SMTP server. Although this message can have many causes, it is most likely you forgot to provide the necessary authentication data to your SMTP server.
Taken from http://www.eudora.com/techsupport/kb/1593hq.html:
Most Internet Service Providers restrict access to their outgoing mail
servers to prevent SPAM from being sent through their mail servers. If
you are getting the "550 Relay Denied" error message, the outgoing
mail server cannot verify who you are and will not allow you to send
mail.
To configure Mail you have to prepare your own SMTP connection. See https://github.com/mikel/mail/wiki/Sending-email-via-google-smtp for an example.
You can get your username/password from your ISP (the one providing the SMTP server)

Resources