Archive for the ‘Component’ Category

Email template engine

Friday, February 19th, 2010

Newest version of Mail.dll email client includes a simple template engine.

It allows you to easily create html template for your emails:

Loading and rendering such template requires one line of code:

Contact contact = ...;

 string html = Template
     .FromFile("template.txt")
     .DataFrom(contact)
     .Render();

This is how the template looks like:

<html>
<head>
    <title>Your order</title>
</head>
<body>
	Hi {FirstName} {LastName},
	<br />
	<p>
	Your account {if Verified}has{else}<strong>has not</strong>{end} been verified. <br/>
	Your password is: {Password}.
	</p>
	<p>
	Here are your orders:
	</p>
	{foreach Orders}
		<p>
		Order sent to <strong>{Street}</strong>:
		</p>
		<table style="width: 30%;">
			{foreach Items}
				<tr style="background-color: #E0ECFF;">
					<td>{Name}</td><td>{Price}</td>
				</tr>
			{end}
		</table>
	{end}
	<p>
		Thank you for your orders.
	<p>
</body>
</html>

Here’s the sample of how to load, fill the template and send it using Mail.dll:

Mail.Html(Template
              .FromFile("template.txt")
              .DataFrom(_contact)
              .Render())
    .Text("This is text version of the message.")
    .From(new MailBox("alice@mail.com", "Alice"))
    .To(new MailBox("bob@mail.com", "Bob"))
    .Subject("Your order")
    .UsingNewSmtp()
    .WithCredentials("alice@mail.com", "password")
    .Server("mail.com")
    .WithSSL()
    .Send();

And this is how the data used by template look like:

public class Contact
{
    public List<Order> Orders { get; private set; }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public bool Verified;
    private string Password { get; set; }

    public Contact()
    {
        Orders = new List<Order>();
    }
} ;

Mark emails as read using IMAP

Wednesday, January 27th, 2010

First you need to download Mail.dll IMAP client.

The following code connects to IMAP server, downloads unique ids of all unseen emails and marks the first one as seen.

// C# version

using(Imap imap = new Imap())
{
	imap.Connect("server");

	imap.User = "user";
	imap.Password = "password";
	imap.Login();

	imap.SelectInbox();
	List<long> uids = client.SearchFlag(Flag.Unseen);
	if (uids.Count > 0)
		client.MarkMessageSeenByUID(uids[0]);
    imap.Close(true);
}
' VB.NET version

Using imap As New Imap()
	imap.Connect("server")

	imap.User = "user"
	imap.Password = "password"
	imap.Login()

	imap.SelectInbox()
	Dim uids As List(Of Long) = client.SearchFlag(Flag.Unseen)
	If uids.Count > 0 Then
		client.MarkMessageSeenByUID(uids(0))
	End If
	imap.Close(True)
End Using

Please note that it is not possible to mark messages as read using POP3 protocol.

Download email attachments in .NET

Monday, January 25th, 2010

First you’ll need an IMAP client or POP3 client to download emails from the server.

The email attachments are downloaded as a part of the message. Attachments are stored within the email as part of a mime tree. Usually Quoted-Printable or Base64 encoding are used. Mail.dll is going to parse such tree for you and expose all attachments as well known .NET collections.

ISimpleMailMessage uses 2 collections for storing attachments:

  • Attachments - contains all attached documents
  • Visuals - contains files that should be ‘displayed’ to the user (like images or music that should be played in background)

Following you’ll find samples of how you can save all attachments to disk using C# and VB.NET via POP3 and IMAP protocols.

When you use IMAP server:

// C# version
using(Imap imap = new Imap())
{
	imap.Connect("server");

	imap.User = "user";
	imap.Password = "password";
	imap.Login();

	imap.SelectInbox();
	List<long> uids = imap.SearchFlag(Flag.All);
	foreach (long uid in uids)
	{
		string eml = imap.GetMessageByUID(uid);
		ISimpleMailMessage email = new SimpleMailMessageBuilder()
			.CreateFromEml(eml);

		Console.WriteLine(email.Subject);

		// save all attachments to disk
		email.Attachments.ForEach(mime => mime.Save(mime.FileName));
		email.Visuals.ForEach(mime => mime.Save(mime.FileName));
	}
	imap.Close(true);
}

You can also save attachment to stream: void MimeData.Save(Stream stream)
Or get direct access to it: MemoryStream MimeData.GetMemoryStream()

' VB.NET version
Using imap As New Imap()
	imap.Connect("server")

	imap.User = "user"
	imap.Password = "password"
	imap.Login()

	imap.SelectInbox()
	Dim uids As List(Of Long) = imap.SearchFlag(Flag.All)
	For Each uid As Long In uids
		Dim eml As String = imap.GetMessageByUID(uid)
		Dim email As ISimpleMailMessage = New SimpleMailMessageBuilder()_
			.CreateFromEml(eml)

		Console.WriteLine(email.Subject)

		' save all attachments to disk
		email.Attachments.ForEach(Function(mime) mime.Save(mime.FileName))
		email.Visuals.ForEach(Function(mime) mime.Save(mime.FileName))
	Next
	imap.Close(True)
End Using

When you use POP3 server:

// C# version
using(Pop3 pop3 = new Pop3())
{
	pop3.Connect("server");

	pop3.User = "user";
	pop3.Password = "password";
	pop3.Login();

	pop3.GetAccountStat();
	for (int i = 1; i <= pop3.MessageCount; i++)
	{
		string eml = pop3.GetMessage(i);
		ISimpleMailMessage email = new SimpleMailMessageBuilder()
			.CreateFromEml(eml);

		Console.WriteLine(email.Subject);

		// save all attachments to disk
		email.Attachments.ForEach(mime => mime.Save(mime.FileName));
		email.Visuals.ForEach(mime => mime.Save(mime.FileName));
	}
	pop3.Close(true);
}
' VB.NET version
Using pop3 As New Pop3()
	pop3.Connect("server")

	pop3.User = "user"
	pop3.Password = "password"
	pop3.Login()

	pop3.GetAccountStat()
	For i As Integer = 1 To pop3.MessageCount
		Dim eml As String = pop3.GetMessage(i)
		Dim email As ISimpleMailMessage = New SimpleMailMessageBuilder()_
			.CreateFromEml(eml)

		Console.WriteLine(email.Subject)

		' save all attachments to disk
		email.Attachments.ForEach(Function(mime) mime.Save(mime.FileName))
		email.Visuals.ForEach(Function(mime) mime.Save(mime.FileName))
	End While
	pop3.Close(True)
End Using

Uploading emails using IMAP

Monday, January 4th, 2010

Uploading emails to the IMAP server is fairly easy with Mail.dll IMAP client

First we’ll use Mail.dll to upload an existing email in eml format to the IMAP server:

// C# code

using (Imap imap = new Imap())
{
    imap.Connect("server");

    imap.User = "user";
    imap.Password = "password";
    imap.Login();

    string eml = File.ReadAllText("email.eml");

    // The name of the folder depends on your IMAP server
    imap.UploadMessage("[Gmail]/Sent Mail", eml);

    imap.Close(true);
}
' VB.NET code

Using imap As New Imap()
	imap.Connect("server")

	imap.User = "user"
	imap.Password = "password"
	imap.Login()

	Dim eml As String = File.ReadAllText("email.eml")

	' The name of the folder depends on your IMAP server
	imap.UploadMessage("[Gmail]/Sent Mail", eml)

	imap.Close(True)
End Using

Second sample shows how to create new email message and upload it to IMAP server.

// C# code

using (Imap imap = new Imap())
{
    imap.Connect("server");

    imap.User = "user";
    imap.Password = "password";
    imap.Login();

    // Create new mail message
    SimpleMailMessageBuilder builder = new SimpleMailMessageBuilder();
    builder.Subject = "subject";
    builder.From.Add(new MailBox("alice@email.com", "Alice"));
    builder.To.Add(new MailBox("bob@email.com", "Bob"));
    builder.SetTextData("This is plain text email");

    // Upload
    // The name of the folder depends on your IMAP server
    imap.UploadMessage("[Gmail]/Sent Mail", builder.Create());

    imap.Close(true);
}
' VB.NET code

Using imap As New Imap()
	imap.Connect("server")

	imap.User = "user"
	imap.Password = "password"
	imap.Login()

	' Create new mail message
	Dim builder As New SimpleMailMessageBuilder()
	builder.Subject = "subject"
	builder.From.Add(New MailBox("alice@email.com", "Alice"))
	builder.[To].Add(New MailBox("bob@email.com", "Bob"))
	builder.SetTextData("This is plain text email")

	' Upload
	' The name of the folder depends on your IMAP server
	imap.UploadMessage("[Gmail]/Sent Mail", builder.Create())

	imap.Close(True)
End Using

Please note that only few IMAP servers are going to send the message to the actual recipients. Most servers will only upload the message without sending it.
You should use SMTP protocol for this.
You can download Mail.dll IMAP client here.

Sending email with embedded image

Monday, December 21st, 2009

We’ll use Mail.dll email client.

  1. We need to create an email message
  2. Use src=”cid:imageID” as image source in HTML
  3. Add the image to Visuals collection using AddVisual method
  4. Apply image id by setting ContentId
  5. And finally send the message
// Use builder class to create an email
SimpleMailMessageBuilder builder = new SimpleMailMessageBuilder();

// Set From, To
builder.From.Add(new MailBox("alice@mail.com", "Alice"));
builder.To.Add(new MailBox("bob@mail.com", "Bob"));
builder.Subject = "Test";
builder.SetTextData("This is text version of th message.");

// Set HTML content (Notice the src="cid:..." attribute)
builder.SetHtmlData(@"<html><body><img src=""cid:image1"" /></body></html>");

// Add image and set its Content-Id
MimeData visual = builder.AddVisual(@"c:\image.jpg");
visual.ContentType = new ContentType(MimeType.Image, MimeSubtype.Jpeg);
visual.ContentId = "image1";

ISimpleMailMessage email = builder.Create();

// Send the message
using (Smtp smtp = new Smtp())
{
    smtp.User = "lesnikowski";
    smtp.Password = "password";
    smtp.Connect("mail.host.com");
    smtp.Ehlo(HeloType.EhloHelo, "yourname");
    smtp.Login();
    smtp.SendMessage(email);
    smtp.Close(false);
}

And of course the VB.NET version of the same code:

' Use builder class to create an email
Dim builder As New SimpleMailMessageBuilder()

' Set From, To
builder.From.Add(New MailBox("alice@mail.com", "Alice"))
builder.To.Add(New MailBox("bob@mail.com", "Bob"))
builder.Subject = "Test"
builder.SetTextData("This is text version of th message.")

' Set HTML content (Notice the src="cid:..." attribute)
builder.SetHtmlData("<html><body><img src=""cid:image1"" /></body></html>")

' Add image and set its Content-Id
Dim visual As MimeData = builder.AddVisual("c:\image.jpg")
visual.ContentType = New ContentType(MimeType.Image, MimeSubtype.Jpeg)
visual.ContentId = "image1"

Dim email As ISimpleMailMessage = builder.Create()

' Send the message
Using smtp As New Smtp()
	smtp.User = "lesnikowski"
	smtp.Password = "password"
	smtp.Connect("mail.host.com")
	smtp.Ehlo(HeloType.EhloHelo, "yourname")
	smtp.Login()
	smtp.SendMessage(email)
	smtp.Close(False)
End Using

Same code using fluent interface:

Mail.Html(@"<html><body><img src=""cid:image1"" /></body></html>")
	.Text("This is text version of th message.")
        .From(new MailBox("alice@mail.com", "Alice"))
        .To(new MailBox("bob@mail.com", "Bob"))
        .Subject("Test")
        .AddVisual(@"c:\image.jpg")
        .SetContentId("image1")
        .SetContentType(
                new ContentType(MimeType.Image, MimeSubtype.Jpeg))
        .UsingNewSmtp()
        .WithCredentials("lesnikowski","password")
        .Server("mail.host.com")
        .Send();

And of course the VB.NET version using fluent interface:

Mail.Html("<html><body><img src=""cid:image1"" /></body></html>")_
	.Text("This is text version of th message.")_
	.From(New MailBox("alice@mail.com", "Alice"))_
	.To(New MailBox("bob@mail.com", "Bob"))_
	.Subject("Test").AddVisual("c:\image.jpg")_
	.SetContentId("image1")_
	.SetContentType(_
                New ContentType(MimeType.Image, MimeSubtype.Jpeg))_
	.UsingNewSmtp()_
	.WithCredentials("lesnikowski", "password")_
	.Server("mail.host.com")_
	.Send()

You can download Mail.dll email client here.