Getting Started with SMTP, POP, & IMAP
Requirements: IPWorks
Contents
Introduction
IPWorks includes components for the standard mail protocols: SMTP for sending email, and IMAP and POP for retrieving email and managing mailboxes. This guide shows how to use each of them, with examples in C#. All common authentication methods are supported, as well as SSL/TLS connections.
To work with mail through REST APIs (e.g., Microsoft 365 and Gmail), please see our Getting Started with Cloud Mail article.
Authentication
Authentication works in the same way in all of the mail components. Set the User and Password properties, and if needed, set the AuthMechanism property to the mechanism the server expects. The default is amUserPassword, and other values include amCRAMMD5, amNTLM, amAPOP (POP only), amSASLPlain, amSASLDigestMD5, and amKerberos.
SMTP mail = new SMTP();
mail.MailServer = "smtp.example.com";
mail.User = "user@example.com";
mail.Password = "password";
mail.AuthMechanism = SMTPAuthMechanisms.amUserPassword; // The default.
mail.Connect();
Many providers, including Gmail and Microsoft 365, no longer accept passwords for SMTP, IMAP, and POP, and require OAuth 2.0 instead (the amXOAUTH2 mechanism). For more information, please see our Using OAuth with the SMTP, IMAP, and POP Components article.
SMTP
Applicable Components: SMTP, HTMLMailer, FileMailer
The HTMLMailer component sends HTML messages with embedded images and attachments, the FileMailer component sends plaintext messages with attachments, and the SMTP component sends messages that are built by the application. Most of the examples below use HTMLMailer, and the last example uses the SMTP and MIME components together.
Send a Basic Email
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "A Basic Email";
mail.MessageText = "Dear Madam,\n\nThis is a plaintext message.\n\nRegards,\nJohn";
mail.Send();
Send an HTML Email
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "A Simple HTML Email";
mail.MessageHTML = "<h2>A Title Might Go Here</h2><p>Followed by some text.</p>";
// MessageText is populated automatically with a plaintext version of MessageHTML, unless it is set by the application.
mail.Send();
Embed an Image
There are three ways to embed an image in an HTML email. The simplest is to use the path of the image file in the src attribute of the img tag. When the ParseHTML property is true (the default), the component finds these images and embeds them in the message.
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "An HTML Email with an Embedded Image";
mail.MessageHTML = "<h2>A Title Might Go Here</h2><p>Followed by an image:</p><img src='C:\\path\\to\\image.jpg' />";
mail.Send();
To control the content ID of the image, set ParseHTML to false, reference the image using a cid: URL, and add the image to the Images collection.
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "An HTML Email with an Embedded Image";
mail.ParseHTML = false;
mail.MessageHTML = "<h2>A Title Might Go Here</h2><p>Followed by an image:</p><img src='cid:image1' />";
HTMLImage image = new HTMLImage("C:\\path\\to\\image.jpg");
image.ImageType = "image/jpeg";
image.Id = "image1";
mail.Images.Add(image);
mail.Send();
Images that are included in the HTML as base64 data (data: URLs) can be converted to embedded images by setting the ConvertImgData2CID configuration setting to true. Many email clients do not display data: URLs, so converting them is recommended. The setting must be set before MessageHTML, since the HTML is parsed when MessageHTML is set.
NetCode nc = new NetCode();
nc.DecodedFile = "C:\\path\\to\\image.jpg";
nc.Format = NetCodeFormats.fmtBase64;
nc.Encode();
string base64Image = nc.EncodedData;
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "An HTML Email with an Embedded Image";
mail.Config("ConvertImgData2CID=true");
mail.MessageHTML = "<h2>A Title Might Go Here</h2><p>Followed by an image:</p><img src='data:image/jpeg;base64," + base64Image + "' />";
mail.Send();
Add an Attachment
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "An Email with an Attachment";
mail.MessageHTML = "<h2>A Title Might Go Here</h2><p>Please read the attached file.</p>";
mail.AddAttachment("C:\\path\\to\\report.pdf");
mail.Send();
Save the Raw Message
The message that was sent can be saved in RFC 822 format (e.g., as an .eml file) using the MessageHeadersString and TransferText configuration settings, which are available after the message is sent.
HTMLMailer mail = new HTMLMailer();
// ...
mail.Send();
string rawMessage = mail.Config("MessageHeadersString") + "\r\n" + mail.Config("TransferText");
File.WriteAllText("C:\\path\\to\\sent.eml", rawMessage);
For more information, please see our Saving Sent Messages to the Sent Folder with the IMAP Component entry.
Advanced Example Using SMTP and MIME
The SMTP and MIME components can be used together for the most control over the structure of the message. The example below builds a message with a plaintext part, an HTML part, an embedded image, and an attachment. The message is a nested MIME message: a multipart/alternative message that contains the plaintext and HTML parts, inside a multipart/mixed message that also contains the image and the attachment.
string imagePath = "C:\\path\\to\\image.jpg";
string attachmentPath = "C:\\path\\to\\attachment.pdf";
string attachmentName = Path.GetFileName(attachmentPath);
MIME mime = new MIME();
// First, build the inner message, which contains the plaintext and HTML versions of the text.
mime.ContentType = "multipart/alternative";
MIMEPart textPart = new MIMEPart();
textPart.ContentType = "text/plain";
textPart.Encoding = MIMEPartEncodings.peQuotedPrintable;
textPart.DecodedString = "The plaintext message goes here.";
mime.Parts.Add(textPart);
MIMEPart htmlPart = new MIMEPart();
htmlPart.ContentType = "text/html";
htmlPart.Encoding = MIMEPartEncodings.peQuotedPrintable;
htmlPart.DecodedString = "<html><p>The HTML message goes here.</p><img src='cid:image1' /></html>";
mime.Parts.Add(htmlPart);
mime.EncodeToString();
// Save the inner message, so that it can be added to the outer message as a part.
string innerMessage = mime.Message;
string innerHeaders = mime.MessageHeadersString;
mime.Reset();
// Next, build the outer message, which contains the inner message, the embedded image, and the attachment.
mime.ContentType = "multipart/mixed";
MIMEPart innerPart = new MIMEPart();
innerPart.Headers = innerHeaders;
innerPart.Encoding = MIMEPartEncodings.peBinary;
innerPart.DecodedString = innerMessage;
mime.Parts.Add(innerPart);
MIMEPart imagePart = new MIMEPart();
imagePart.ContentType = "image/jpeg";
imagePart.Encoding = MIMEPartEncodings.peBase64;
imagePart.Headers = "Content-ID: <image1>";
imagePart.DecodedStringB = File.ReadAllBytes(imagePath);
mime.Parts.Add(imagePart);
MIMEPart attachmentPart = new MIMEPart();
attachmentPart.ContentType = "application/pdf";
attachmentPart.ContentDisposition = "attachment";
attachmentPart.ContentDispositionAttr = "filename=\"" + attachmentName + "\"";
attachmentPart.Encoding = MIMEPartEncodings.peBase64;
attachmentPart.DecodedStringB = File.ReadAllBytes(attachmentPath);
mime.Parts.Add(attachmentPart);
mime.EncodeToString();
// Send the message with the SMTP component.
SMTP mail = new SMTP();
mail.MailServer = "smtp.example.com";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "An Advanced Email Built with MIME";
mail.OtherHeaders = mime.MessageHeadersString;
mail.Message = mime.Message;
try
{
mail.Send();
}
catch (IPWorksException ex)
{
Console.WriteLine(ex.Message);
}
IMAP
Applicable Components: IMAP
The IMAP component retrieves messages and manages mailboxes on the server. To connect, set MailServer (and if needed, MailPort), and call Connect, which connects and authenticates to the server. Then, select a mailbox by setting Mailbox and calling SelectMailbox, after which the other operations can be performed.
Connect to a Mail Server
IMAP mail = new IMAP();
mail.MailServer = "imap.example.com";
mail.User = "user@example.com";
mail.Password = "password";
mail.Connect();
List Available Mailboxes
IMAP mail = new IMAP();
mail.OnMailboxList += (s, e) => Console.WriteLine(e.Mailbox);
// ...
mail.ListMailboxes();
Select a Mailbox
IMAP mail = new IMAP();
// ...
mail.Mailbox = "INBOX";
mail.SelectMailbox();
List All Messages in a Mailbox
Messages in the selected mailbox are numbered from 1 to MessageCount. To get information about the messages, set MessageSet to the range of messages, and call RetrieveMessageInfo. The MessageInfo event fires for each message, with information such as the Subject, From, and MessageDate of the message.
IMAP mail = new IMAP();
mail.OnMessageInfo += (s, e) => Console.WriteLine(e.Subject + " | " + e.From + " | " + e.MessageDate);
// ...
mail.SelectMailbox();
mail.MessageSet = "1:" + mail.MessageCount;
mail.RetrieveMessageInfo();
Save the Raw Message
To get a message in RFC 822 format, call RetrieveMessageHeaders and RetrieveMessageText, which populate the MessageHeadersString and MessageText properties.
IMAP mail = new IMAP();
// ...
mail.MessageSet = "1";
mail.RetrieveMessageHeaders();
mail.RetrieveMessageText();
File.WriteAllText("C:\\path\\to\\message.eml", mail.MessageHeadersString + "\r\n" + mail.MessageText);
For more information, please see our Export Email Contents to a Local File entry.
Save Attachments
Each attachment is a separate part of the message. First, call RetrieveMessageInfo to populate the MessageParts collection, and then call RetrieveMessagePart for each part that is an attachment. If LocalFile is set, the part is saved to that file, and otherwise its contents are stored in MessageText.
IMAP mail = new IMAP();
// ...
mail.MessageSet = "1";
mail.RetrieveMessageInfo();
foreach (MessagePart part in mail.MessageParts)
{
if (part.ContentDisposition.ToLower().Contains("attachment"))
{
mail.LocalFile = Path.Combine("C:\\path\\to", part.FileName);
mail.RetrieveMessagePart(part.Id);
}
}
Delete Messages
IMAP mail = new IMAP();
// ...
mail.MessageSet = "1:23";
mail.DeleteFromMailbox(); // Marks the messages with the Deleted flag.
mail.ExpungeMailbox(); // Removes all messages with the Deleted flag from the mailbox.
POP
Applicable Components: POP
The POP component retrieves messages from the server. To connect, set MailServer (and if needed, MailPort), and call Connect, which connects and authenticates to the server. Then, set MessageNumber to select the message to work with.
Connect to a Mail Server
POP mail = new POP();
mail.MailServer = "pop.example.com";
mail.User = "user@example.com";
mail.Password = "password";
mail.Connect();
List All Messages in a Mailbox
Messages are numbered from 1 to MessageCount. To get information about each message, set MessageNumber and call RetrieveHeaders. The Header event fires for each header of the message, which can be used to read fields such as Subject, From, and Date.
POP mail = new POP();
string subject = "", date = "", from = "";
mail.OnHeader += (s, e) =>
{
switch (e.Field.ToLower())
{
case "subject":
subject = e.Value;
break;
case "date":
date = e.Value;
break;
case "from":
from = e.Value;
break;
}
};
// ...
for (int i = 1; i <= mail.MessageCount; i++)
{
subject = date = from = "";
mail.MessageNumber = i;
mail.RetrieveHeaders();
Console.WriteLine(subject + " | " + from + " | " + date);
}
Save the Raw Message
POP mail = new POP();
// ...
mail.MessageNumber = 1;
mail.Retrieve();
Console.WriteLine(mail.MessageHeadersString + "\r\n" + mail.MessageText);
To save the message directly to a file, set the LocalFile property, and set IncludeHeaders to true so that the headers are included in the file.
POP mail = new POP();
// ...
mail.IncludeHeaders = true;
mail.LocalFile = "C:\\path\\to\\message1.eml";
mail.MessageNumber = 1;
mail.Retrieve();
Delete a Message
Messages are marked for deletion when Delete is called, and removed from the server when the connection is closed with Disconnect.
POP mail = new POP();
// ...
mail.MessageNumber = 1;
mail.Delete();
mail.Disconnect();
Using SSL & TLS
To connect to a server over SSL/TLS, set the SSLStartMode property, and if needed, the MailPort property. SSLStartMode works in the same way in all of the mail components, and has the following values:
| Value | Description |
|---|---|
| sslAutomatic | If MailPort is the standard plaintext port of the protocol, STARTTLS is used (as with sslExplicit). Otherwise, SSL/TLS is used from the start of the connection (as with sslImplicit). |
| sslImplicit | SSL/TLS is used from the start of the connection, on a dedicated SSL/TLS port. |
| sslExplicit | The connection starts in plaintext, and the component sends the STARTTLS command to upgrade it to SSL/TLS. |
| sslNone | SSL/TLS is not used (the default). |
The example below sends a message over an implicit SSL/TLS connection.
HTMLMailer mail = new HTMLMailer();
mail.MailServer = "smtp.example.com";
mail.MailPort = 465;
mail.SSLStartMode = HTMLMailerSSLStartModes.sslImplicit;
mail.User = "user@example.com";
mail.Password = "password";
mail.SendTo = "recipient@example.com";
mail.From = "sender@example.com";
mail.Subject = "A Basic Email";
mail.MessageText = "Dear Madam,\n\nThis is a plaintext message.\n\nRegards,\nJohn";
mail.Send();
The standard port numbers for SMTP, IMAP, and POP are listed below. Note that some servers use different ports.
| Connection | SMTP | IMAP | POP |
|---|---|---|---|
| Plaintext | 25 | 143 | 110 |
| STARTTLS (sslExplicit) | 587 | 143 | 110 |
| SSL/TLS (sslImplicit) | 465 | 993 | 995 |
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.