Process e-mail failures with C# - c#

I am looking to have C# connect to an e-mail account and process undelivered mail or failures. And I would like the failed address or the original e-mail to be written to a text file.
I'm sure I could figure out how to identify failed message. Example: WHERE subject CONTAINS 'failure', 'returned', etc.
What I do not know how to do is collect the failed address from the e-mail.
I was using a program called popmonger for a client at one point, but now it is collecting the wrong e-mail addresses. It is collecting mailer-daemon#gateway03.websitewelcome.com as an example instead of the original or failed e-mail. I thought it might be easier if I wrote a C# service.
The e-mail account I am connecting to is at hostgator. Does anyone know where to start on this?
Thanks,
Jake

Since the mail client being used is called popmonger, it sounds like you will be dealing with POP3 protocol and although .Net provides a way to send email via SMTP easily, it doesn't really do the same justice when checking emails.
You will have to use a 3rd party DLL that has a POP3 client to retrieve the emails. Most importantly you will need to inspect one of the failure email notifications to see what what your application will be expecting. There should be something common in the subject, body, originator address, etc. to tip off which emails are failure notifications. Then you need to see where in the body of the email it specifies the error information you need to retrieve to write to the text file. Basically your steps should go something like this:
Check for and retrieve email messages
Add each failure email object to a collection (List<T> works just fine)
Read/parse each email to extract the information you need
Write the extracted data to a file
As long as everything goes well and you get no exceptions, delete the email from the POP server with your POP client object (that way you don't read the same failure notices every time and fill your text file with redundant data)
I've used a POP3 class from this codeproject article and it does include code for attachments but I never use it for attachments because it's a bit buggy with them. For reading email body text, it hasn't failed me yet (knocking on wood).
Once you have the failure notice you can extract the failed address per your prescribed format with a simple regular expression pattern and matching it. Let's assume the body text is already retrieved from the server and you stored it in a stringed named bodyText
using System.Text.RegularExpressions;
// ...
string failedAddressPattern = #"The mail system <(?<address>.+)>";
string capturedAddress = null;
Match match = Regex.Match(bodyText, failedAddressPattern, RegexOptions.IgnoreCase);
if(match.Groups["address"].Success)
{
capturedAddress = match.Groups["address"].Value.Trim();
}
if(capturedAddress == null)
{
// do some form of debug logging here because the pattern no longer works, etc.
}

Beside text scan there is standar for that too, it's called DSN(delivery status notifications, defined in RFC 3464). You can dedect such messages by content-type header "multipart/report; report-type=delivery-status". You can check http://www.lumisoft.ee/lsWWW/download/downloads/Examples/ - it has all you need POP3/IMAP client with examples. It also has MIME message parser what you need, it has also DSN message support. Full soruce code is provided, so getting started should be easy.

Related

Artalk XMPP library questions

I used Artalk XMPP nuget package in my C# application. I was able to send messages from the user account userA#domain.com to the user account userB#domain.com through Ignite OpenFire server on our LAN. There were several minor issues with the messages that are not showstoppers:
If I tried to provide a subject, it was prefixed with the word "Subject: " in the client. This is not a problem but I am wondering if this is a remote client or server thing.
The message body was wrapped in square brackets as [test message body]. This is not a big problem but I would rather avoid it, to preserve the message being sent as-is, for the possible automatic processing. Is this a remote client or server thing?
If message body contained XML, then it was sent successfully but never received. Is sending XML not allowed by XMPP protocol? Or is it a server or remote client thing?
Edit:
Since I asked the above bullet, I tried to use System.Security.SecurityElement.Escape() on the message body and wrapped it in <![CDATA[]]> and it was delievered with its XML preserved. The question still stands.
All successfully delivered messages have been also copied by userB back to userA. This is all right if userA is not interactive, but if it is also a real human being, then it may be annoying. Is this a server or remote client thing, and is there any way to avoid it? I know that the remote user's client does not do it with regular chat messages sent through a Jabber client to them.
Next, I had userB#domain.com invite userA#domain.com to a chat room conference.domain.com#conference.domain.com and tried to send messages to that chat room, still from userA#domain.com. No messages have been received in the conference room, and there was no exception thrown during the sending.
ArtalkXmppClient xmpp;
xmpp = new ArtalkXmppClient("domain.com", "userA#domain.com", "secret", 5222, true);
try
{
var msg = new Message(
"conference.domain.com#conference.domain.com",
"test message body",
"conference subject", // conference allows participants to change subject
null,
MessageType.Groupchat,
CultureInfo.CurrentCulture);
if (!xmpp.Connected)
{
xmpp.Connect("myapp");
}
xmpp.SendMessage(msg);
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The solution to the group chat part of the question was to pre-create the group on the server before trying to send to it and to use MessageType.Chat.
The last part was counter-intuitive and I would have never figured it out, if I did not forget to enable group chat in the configuration during testing. When using MessageType.GroupChat or any type other than Chat it simply did not work.
Also, subject must be null, otherwise subject will change but no messages will be delivered. Changes of subject have to be sent on their own, separate messages without bodies.
The only side effect that I am noticing is that with group chat, as opposed to person-to-person chat, the messages appear escaped. I am not sure what escapes them as opposed to person-to-person chat, but this is kind of acceptable.

How to send an e-mail from *any* email address in ASP.NET?

I have a basic SmtpClient and I use it to send e-mails.
using (var client = new SmtpClient())
using (var mail = new MailMessage())
{
mail.From = new MailAddress(fromEmailAddress);
mail.Body = "body text";
mail.To.Add(new MailAddress(myEmailAddress));
client.Send(mail);
}
This code works well if I set the fromEmailAddress to a real e-mail address. If I set it to a fake e-mail address, let's say test#test.com, the code sends the message, but I don't receive the e-mail.
I'm using it on a contact form where there is a field for their e-mail and a field for their message.
Is there a way to send the e-mail regardless of whether the e-mail is valid or not? (In PHP's mail method, it was possible)
Optionally, is it possible to check if the e-mail had been received by me? (to display an error to the user)
You make a mistake in thinking your end matters.
What matters is how stupid or not - and in these days you can count on not - the receiving email server is in regarding to spam.
Your email is simply thrown away for being spam, and it is likely obvious - like the domain you send "from" (fake address) either not existing or having an SPF or other record listing the allowed senders - which you aren't one of.
Simple like that. The internet is a bad place and every sysadmin not a total idiot deploys anti spam mechanisms.
Now, if you put up some form like that or something, it needs to be fixed. Seen that many times. You can not do that - because domains are protected. Which means you can not just pretend you are allowed to send on another domain's behalf. I have seen this type sometimes with contact forms - it's a mistake of programmers not understanding that my domains have SPF records.
C# aside, thats not a good idea if you can avoid it. Setting the 'From' field doesnt actually send from that address - this would mean that anyone could impersonate your bank, for instance.
Most mail providers will regard it quite poorly in terms of spam score - meaning you are likely to have delivery issues if you are sending from a domain that you are not authorised to send from - and that is at least one possible reason why you are experiencing issues with fake addresses.
Here's some more info on why this is bad (see point #4), and some other useful tips - https://www.campaignmonitor.com/blog/email-marketing/2015/09/9-things-that-are-killing-your-email-deliverability/

Is it possible to capture the "Message-ID" of an email message sent with SmtpClient?

Using the SmtpClient and MailMessage classes in .NET to send emails through a local mail server (hMailServer), I currently found no way to get the Message-ID header value of a sent message.
The idea behind
I'm trying to programmatically track messages that are undeliverable, so I have to find a way to identify replies from the destination SMTP server that rejects a certain message.
Now I thought of simply remembering the Message-ID SMTP header value and parse incoming mails for this ID.
I've tried to inspect the Headers collection after sending the message, but I did not find any Message-ID.
My question
Is it possible to get the Message-ID header value that my SMTP server adds during sending of a MailMessage instance?
Update 2012-05-27
As per this example I've successfully tried to manually generate a Message-ID on my own, just before sending.
All my examples work so far, so it seems that this is a solution to my question.
You can add your own message id before send the email. I use the next code:
Guid id = Guid.NewGuid(); //Save the id in your database
mensajeEmail.Headers.Add("Message-Id", String.Format("<{0}#{1}>",id.ToString(),"mail.example.com"));
Note: For download messages I use OpenPop.Net, I check the message.Headers.InReplyTo property, and there is the message id sended.
The standard solution to your problem is VERP. Read Bernstein's original article to find out why Message-Id et al. are not reliable. http://cr.yp.to/proto/verp.txt
I'm Using MailKit library for .Net and SMTP Client.
I tried another solution to get the ID of the message sent with SMTP Client, to trace any replied messages.
Before you send your message add a hidden ID property to the message headers,
Now continue and send your message,
Wait about 10 Seconds, Then you will use the IMAP Client to get your Sent folder and for each message in your folder,
loop over the message headers and check if anyone of them is ==messageIdentity, now you catch your
sent message successfully and get any information about it you wand like ID etc...

How Do Email Campaign Managers Report On Bounced Emails?

Can anyone point me in the right direction to how I would handle capturing bounced email info. I'm looking into writing an email campaign manager and would like the ability to report that data.
You can write an app to poll your bad mail folder to identify returned email. You should wait for sometime after sending the email before checking whether it is delivered or returned.
Bounced email is slang for a Non Delivery Report or NDR. Most smtp servers have their own ways to handle NDRs, typically via a BADMAIL folder.
So first of all, confirm what your SMTP server software does for NDRs. Then confirm that this is working correctly. I think that if an email fails to send, the sender will get notified .. but if the sender can't be notified (ie. do not reply email, etc) I think this is how it ends up in the BADMAIL folder.
Anyway - you need to find out and confirm that the software you're using handles NDRs. Once it does, it's easy to write some code to check that folder every 'whatever' or even put a filewatcher on it, and then parse the content of each file that is added to that folder.
Bounced email can be parsed and you can use that information to mark email address invalid or whatever. What smtp server are you using to send emails?
And can you be more specific about the kind of help you're looking for? It's not very clear if you have access to these bounds emails and if so are they in the bounced queue of your smtp server or are they in your email client's (outlook etc.) inbox.

How to know whether I send the email successfully using System.Net.Mail

I use C# to send email using System.Net.Mail.
But How can I know whether the email has been sent successfully or fail?
Not a direct answer of course, but here is a great article from Coding Horror about sending emails through code, which addresses your question.
The simple answer is that if it's a detectable failure then SmtpClient.Send will throw an SmtpFailedRecipientsException (it will throw an SmtpException if there is a connection problem).
The long answer is that, for many reasons, you won't necessarily get an exception. This can be because your SMTP server is buffering the sends (or if you have it set to local iis or local directory), or simply because the SMTP server does not support returning those error codes.
Most advertising mailing systems track bouncebacks by setting a valid "from address" and monitoring the inbox for that account. Even that, however, is not foolproof (out of office messages, for example).
I would stick to catching exceptions and leaving the others. If you're not sure if emails are valid, maybe you should send users a code to have them validate their email address.
Considering Emails are fire-and-forget, this can be quite hard. Unless you get an exception, denoting a client-server communication issue due to wrong credentials etc, you have no means of knowing if a mail was sucessfully send (meaning: arrived at the addressee).
I've personally never come across an answer to this as there's not really a way you can grantee mail leaving your location is'nt going to get thrown away as soon as it leaves you. You could maybe try and check the sending mailbox for an NDR (none delivery report) but your not always granted to get one
If you mean sent successfully then as other posters say, if it cannot be sent then you will get an exception. If you actually mean recieved succesfully then that is an entirely different matter. SMTP simply does not have a mechanism to find out if the message has been recieved by the recipient, sometimes you will get an ndr if a server can't deliver other times you won't. You could try and do what spammers do and that is to put some kind of image link in your html email body with a unique identifier in the query string. That would allow you to link someone hitting the image url with the email. However that would only tell you the email had been read if the url was hit, it would not tell you that the email hadn't been recieved becuase the recipient might simply not have allowed images to be displayed in their email client.

Categories

Resources