views:

1206

answers:

6

Hi all,

Can anyone recommend software or even a .net library to develop software, that will check for bounced emails and the reason for the bounce? I get bounced emails into a pop3 account that I can read then...

I need it to keep my user database clean from invalid email addresses and want to automate this (mark user as invalid email).

Thanks

+2  A: 

It's pretty easy to do with a TcpClient. Open the server:

TcpClient tcpClient = new TcpClient();
tcpClient.Connect(POP3Server, POP3Port);
NetworkStream stream = tcpClient.GetStream();

Read the welcome message:

int read = stream.Read(inBuffer, 0, inBuffer.Length);
string response = Encoding.ASCII.GetString(inBuffer, 0, read);
if (response.IndexOf("+OK") != 0) throw new ...;

Write back to the server:

byte[] outBuffer = Encoding.ASCII.GetBytes("USER " + account + "\r\n");
stream.Write(outBuffer, 0, outBuffer.Length);

That sends the USER command. You need to login and then you can start grabbing messages - see the POP3 RFC for the full list of commands. If you're not looking to roll your own check out this CodeProject article.

abfo
+2  A: 

as abfo says, the POP3 protocol is super simple, getting the messages is a no brainer. Parsing the messages to get the failures is harder, and reliably parsing out which email caused the failure and why it failed is really hard. The problem is that bounce messages don't have a standard format, the default forms vary from MTA to MTA. Then the failure reason can be tweaked by the site admin making it harder to recognize, and the site admin could modify the failure message template which makes it darn near impossible.

See if you can find a .NET mailing list manager and if you can repurpose the bounce handling code. Failing that, see if you can change the tool that's sending the messages to send each email from a unique (and reversible) enveloper sender (VERP I think it's called?). That way you don't need to scan the body of the email, you can tell which recipient failed by examining the recipient address of the failure message.

jj33
+4  A: 

I have done a great deal of work handling bounce emails and there different types. If you want to be absolutely sure that the email your looking at is indeed a bounce of a specific kind I highly recommend getting a good filter. I have worked with Boogie Tools and it has worked very well. It lets you know what kind of bounce it is, Hard, Soft, Transient or if its even someone trying to unsubscribe. It has a muliple API's including .Net and I found it quite easy to get working.

Tanerax
A: 

Thanks for the answer, great! I did some research myself and found ListNanny - also super simple to use and tells you the type of bounce. Will write some proof of concept and see which one I like better...

Johannes
A: 

Your question made me realize that the Wordpress Newsletter plugin I was going to use, did not have bounce management, and I'd need something as well.

I looked around for awhile, and I've settled on the free and open-source PHPlist newsletter manager.

They describe in detail their settings for handling bounces and they do have an experimental advanced bounce handling feature that will allow you to customize the bounce handling exactly the way you want.

Evem if you decide not to use PHPlist, reading how they do it will be useful information for you.

lkessler
A: 

Handling Bounce Messages is very tricky. However, you may want to use the Ultimate Bounce Inspector to make it easy. See this blogpost for more details.

Here is the code that handles bounced emails on a POP3 account:

// POP3 server information.
const string serverName = "myserver";
const string user = "[email protected]";
const string password = "mytestpassword";
const int port = 995;
const SecurityMode securityMode = SecurityMode.Implicit;
// Create a new instance of the Pop3Client class.
Pop3Client client = new Pop3Client();
Console.WriteLine("Connecting Pop3 server: {0}:{1}...", serverName, port);
// Connect to the server.
client.Connect(serverName, port, securityMode);
// Login to the server.
Console.WriteLine("Logging in as {0}...", user);
client.Authenticate(user, password);
// Initialize BounceInspector.
BounceInspector inspector = new BounceInspector();
inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.
// Register processed event handler.
inspector.Processed += inspector_Processed;
// Download messages from Pop3 Inbox to 'c:\test' and process them.
BounceResultCollection result = inspector.ProcessMessages(client, "c:\\test");
// Display processed emails.
foreach (BounceResult r in result)
{
   // If this message was identified as a bounced email message.
   if (r.Identified)
   {
       // Print out the result
       Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
                       System.IO.Path.GetFileName(r.FilePath),
                       r.MailMessage.Subject,
                       r.Addresses[0],
                       r.BounceCategory.Name,
                       r.BounceType.Name,
                       r.FileDeleted,
                       r.Dsn.Action,
                       r.Dsn.DiagnosticCode);
   }
}
Console.WriteLine("{0} bounced message found", result.BounceCount);
// Disconnect.
Console.WriteLine("Disconnecting...");
client.Disconnect();
Mark Attwood