How to get bounce emails from SparkPost without using webhooks? - email-bounces

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

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.

Ruby Net:Http get request gives different response than with Browser

I am trying to fetch from API server using Net::HTTP.
puts "#{uri}".green
response = Net::HTTP.new('glassdoor.com').start { |http|
# always proxy via your.proxy.addr:8080
response = http.get(uri, {'Accept' => 'application/json'})
puts "Res val: #{response.body}".blue
}
I got the uri from the console and pasted in the browser, and I received the JSON response.
But using the Ruby Net::HTTP get I receive some security message:
Why the difference? The browser and the Ruby script are behind the same public IP.
You were detected as a crawler (correctly, by the way). Note that those requests (from browser and the script) are not just the same. The browser sends some headers, such as accepted language, user agent etc. You can peek into it using web inspector tool in the browser. On the other side, in your script you only set Accept header (and to JSON, suspicious on its own, as browser would never do that). And you do not send any user agent. It's easy to see that this is an automates request, not natural traffic from the browser.

How to hit gmail end points from postman?

I need to hit gmail end points to send emails and get the email details. I got one url which can be used to send and get the emails i.e. google api explorer. https://developers.google.com/gmail/api/v1/reference/users/messages/get
But it's not written here about the end points. So somebody please explain what things are required to send and retrieve the email by using gmail api end points through postman?
The end point for sending messages can be found on the documentation page.
User.messages.send there is also information about the post body.
Upload URI, for media upload requests:
POST https://www.googleapis.com/upload/gmail/v1/users/userId/messages/send
Metadata URI, for metadata-only requests:
POST https://www.googleapis.com/gmail/v1/users/userId/messages/send
authentcation
You are going to have to set up authnecation as well. the easest way to do this will be to use the Oauth 2.0 play ground to get a bearer token and apply that to your calls within postman

Post a private message to the user frined using Ruby and fb_graph gem?

I want to send a private message to a user's friend using fb_graph. In the docs I can see how to send a post in the users wall but not how to send a message on behalf of that user.
You can use Facebook Chat API to send private messages, here is an example in Ruby using xmpp4r_facebook gem:
sender_chat_id = "-#{sender_uid}#chat.facebook.com"
receiver_chat_id = "-#{receiver_uid}#chat.facebook.com"
message_body = "message body"
message_subject = "message subject"
jabber_message = Jabber::Message.new(receiver_chat_id, message_body)
jabber_message.subject = message_subject
client = Jabber::Client.new(Jabber::JID.new(sender_chat_id))
client.connect
client.auth_sasl(Jabber::SASL::XFacebookPlatform.new(client,
ENV.fetch('FACEBOOK_APP_ID'), facebook_auth.token,
ENV.fetch('FACEBOOK_APP_SECRET')), nil)
client.send(jabber_message)
client.close
Unfortunately it cannot be done; Facebook removed the functionality due to abuse (spam etc).
Please refer to: how send message facebook friend through graph api using Accessstoken
It seems that is not possible but posting to the user's wall might be an alternative: https://github.com/nov/fb_graph/issues/issue/28/#comment_591398

Ruby send mail with smtp

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.

Resources