Email to SMS
Written by Harry Fairhead   
Monday, 27 July 2009
Article Index
Email to SMS
POP3
You have mail
Reading the mail
A Skype class

 

Reading the mail

Now we come to the “big” method of the class, the one that reads a specific email from the server. The POP3 command to do this is just “RETR n” where n is the number of the email you want to retrieve and the method starts off simply enough:

public EmailMessage getMail(int n)
{
try
{
SendData("RETR " + n.ToString());
if (!WaitFor("+OK")) POPerror();

The complication is that the response can now be multiline. The key to knowing when to stop reading lines is that the final line contains only “.” as an “end of email” marker.

So to read all the lines in we need a simple loop:

  String temp;
StringBuilder mess =
new StringBuilder();
temp = InStream.ReadLine();
while (temp != ".")
{
mess.Append(temp + CRLF);
temp = InStream.ReadLine();
}

At this point we have read all of the lines of the email, headers and body, into the StringBuilder mess – the only question is what to do with it? We could simply return it as the result but in most cases the user will want to access the headers and the body separately and it’s a good idea to parse the result into set of fields in a special EmailMessage object.

For the moment assume that the class EmailMessage exists:

  EmailMessage Emess =
new EmailMessage(mess.ToString());
return Emess;
}

The catch class is a little more interesting in this case because if the try clause fails we still return an instance of the EmailMessage class but with nothing much stored in it:

 catch
{
EmailMessage Emess =
new EmailMessage(
"No email was retrieved");
return Emess;
}

To complete the POP3 class we need to add:

private TcpClient TCP;
private NetworkStream POP3Stream;
private StreamReader InStream;
private string data;
private string CRLF = "\r\n";

to declare the global variables that we have been using throughout.

An email class

Everything now depends on the EmailMessage class. This is going to provide properties that correspond to the email headers we consider important (you can add more if you want to):

public class EmailMessage
{
public string From;
public string To;
public string ReplyTo;
public string Subject;
public string Date;
public string ContentType;

We also need public properties for the body text of the email:

 public string Body;

and a private variable to store the entire text of the email:

 private string m_MessageSource;

The idea is that when an instance of EmailMessage is created the entire text of the email is passed to the constructor and it parses it and stores all of the relevant text in each of the header fields and the body.

This is worth thinking about for a moment – what we have is a data structure that “understands” and processes its own raw data into something more usable. This is the power of object-oriented programming!

The constructor is simply:

public EmailMessage(string Message)
{
m_MessageSource = Message;
ParseEmail();
}

In case there is some reason to need to change the MessageSource after the constructor has set it, we can create a corresponding property so that the set operation also parses the raw data into the data fields:

public string MessageSource
{
get
{
return m_MessageSource;
}
set
{
m_MessageSource = value;
ParseEmail();
}
}

Of course the previous routines are only simple because we have off-loaded all the work to a function called ParseEmail which in turn off-loads it to ParseHeader and ParseBody functions:

private void ParseEmail()
{
this.ReplyTo =
ParseHeader("Reply-To:");
this.From = ParseHeader("From:");
this.To = ParseHeader("To:");
this.Subject = ParseHeader("Subject:");
this.Date = ParseHeader("Date:");
this.ContentType =
ParseHeader("Content-Type:");
this.Body = ParseBody();
}

The parse functions aren’t difficult but they do make use of some tricky string processing to find the headers, which all take the form “name:value”. The trick is to locate “name:” and then take everything after the colon to the end of the line as the value of the header. The body of the email is identified by a blank line at the end of the headers – the body text follows the blank line to the end of the email.


private string ParseHeader(
string header)
{
int s = m_MessageSource.
IndexOf(header);
if (s == -1) return "";
s = m_MessageSource.
IndexOf(':', s) + 1;
int e = m_MessageSource.
IndexOf("\r\n", s);
if (e == -1)
e = m_MessageSource.Length;
return m_MessageSource.
Substring(s, e - s);
}

private string ParseBody()
int s = m_MessageSource.
IndexOf("\r\n\r\n");
if (s == -1) return "";
return m_MessageSource.
Substring(s + 4);
}
}
<ASIN:159257551X>

<ASIN:B001PLWTLG@COM@CA>

<ASIN:B000B8Y5PC@COM@CA>

<ASIN:B000ET1ZM4@UK@DE@FR>

<ASIN:B000JOZWXC@UK@DE@FR>



Last Updated ( Wednesday, 18 November 2015 )