Reading Emails from Gmail in C#

Reading emails from Gmail in C#

Using the library from: https://github.com/pmengal/MailSystem.NET

Here is my complete code sample:

Email Repository

using System.Collections.Generic;
using System.Linq;
using ActiveUp.Net.Mail;

namespace GmailReadImapEmail
{
public class MailRepository
{
private Imap4Client client;

public MailRepository(string mailServer, int port, bool ssl, string login, string password)
{
if (ssl)
Client.ConnectSsl(mailServer, port);
else
Client.Connect(mailServer, port);
Client.Login(login, password);
}

public IEnumerable<Message> GetAllMails(string mailBox)
{
return GetMails(mailBox, "ALL").Cast<Message>();
}

public IEnumerable<Message> GetUnreadMails(string mailBox)
{
return GetMails(mailBox, "UNSEEN").Cast<Message>();
}

protected Imap4Client Client
{
get { return client ?? (client = new Imap4Client()); }
}

private MessageCollection GetMails(string mailBox, string searchPhrase)
{
Mailbox mails = Client.SelectMailbox(mailBox);
MessageCollection messages = mails.SearchParse(searchPhrase);
return messages;
}
}
}

Usage

[TestMethod]
public void ReadImap()
{
var mailRepository = new MailRepository(
"imap.gmail.com",
993,
true,
"yourEmailAddress@gmail.com",
"yourPassword"
);

var emailList = mailRepository.GetAllMails("inbox");

foreach (Message email in emailList)
{
Console.WriteLine("<p>{0}: {1}</p><p>{2}</p>", email.From, email.Subject, email.BodyHtml.Text);
if (email.Attachments.Count > 0)
{
foreach (MimePart attachment in email.Attachments)
{
Console.WriteLine("<p>Attachment: {0} {1}</p>", attachment.ContentName, attachment.ContentType.MimeType);
}
}
}
}

Another example, this time using MailKit

public class MailRepository : IMailRepository
{
private readonly string mailServer, login, password;
private readonly int port;
private readonly bool ssl;

public MailRepository(string mailServer, int port, bool ssl, string login, string password)
{
this.mailServer = mailServer;
this.port = port;
this.ssl = ssl;
this.login = login;
this.password = password;
}

public IEnumerable<string> GetUnreadMails()
{
var messages = new List<string>();

using (var client = new ImapClient())
{
client.Connect(mailServer, port, ssl);

// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");

client.Authenticate(login, password);

// The Inbox folder is always available on all IMAP servers...
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
var results = inbox.Search(SearchOptions.All, SearchQuery.Not(SearchQuery.Seen));
foreach (var uniqueId in results.UniqueIds)
{
var message = inbox.GetMessage(uniqueId);

messages.Add(message.HtmlBody);

//Mark message as read
//inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
}

client.Disconnect(true);
}

return messages;
}

public IEnumerable<string> GetAllMails()
{
var messages = new List<string>();

using (var client = new ImapClient())
{
client.Connect(mailServer, port, ssl);

// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");

client.Authenticate(login, password);

// The Inbox folder is always available on all IMAP servers...
var inbox = client.Inbox;
inbox.Open(FolderAccess.ReadOnly);
var results = inbox.Search(SearchOptions.All, SearchQuery.NotSeen);
foreach (var uniqueId in results.UniqueIds)
{
var message = inbox.GetMessage(uniqueId);

messages.Add(message.HtmlBody);

//Mark message as read
//inbox.AddFlags(uniqueId, MessageFlags.Seen, true);
}

client.Disconnect(true);
}

return messages;
}
}

Usage

[Test]
public void GetAllEmails()
{
var mailRepository = new MailRepository("imap.gmail.com", 993, true, "YOUREMAILHERE@gmail.com", "YOURPASSWORDHERE");
var allEmails = mailRepository.GetAllMails();

foreach(var email in allEmails)
{
Console.WriteLine(email);
}

Assert.IsTrue(allEmails.ToList().Any());
}

Reading Emails from Gmail C# - IMAP

You should use the solution of the second post of the topic were you have found something, S22.Imap.
(Here you can find a compiled version).

After download, you can read the documentation. It is simple and readable.

Actually, I use this library and that works well !

How can I download emails from Gmail using C#/WinForms?

No you dont require to have Google API for getting(downloading) emails from Gmail account. You can read more about Reading Gmail Inbox Message

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Net.NetworkInformation;
using System.Net.Security;
using System.Net.Sockets;

namespace mail
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void Button1_Click(object sender, EventArgs e)
{

Imap client = new Imap();
// connect to server

client.Connect("imap.gmail.com", 993, SslMode.Implicit);

// authenticate
client.Login("username", "password");

// select folder
client.SelectFolder("Inbox");

int NoOfEmailsPerPage = 10;
int totalEmails = client.CurrentFolder.TotalMessageCount;
// get message list - envelope headers
ImapMessageCollection messages = client.GetMessageList(ImapListFields.Envelope);

// display info about each message

foreach (ImapMessageInfo message in messages)
{

TableCell noCell = new TableCell();

noCell.CssClass = "emails-table-cell";

noCell.Text = Convert.ToString(message.To);
TableCell fromCell = new TableCell();
fromCell.CssClass = "emails-table-cell";
fromCell.Text = Convert.ToString(message.From);
TableCell subjectCell = new TableCell();
subjectCell.CssClass = "emails-table-cell";
subjectCell.Style["width"] = "300px";
subjectCell.Text = Convert.ToString(message.Subject);
TableCell dateCell = new TableCell();
dateCell.CssClass = "emails-table-cell";
if (message.Date.OriginalTime != DateTime.MinValue)
dateCell.Text = message.Date.OriginalTime.ToString();
TableRow emailRow = new TableRow();
emailRow.Cells.Add(noCell);
emailRow.Cells.Add(fromCell);
emailRow.Cells.Add(subjectCell);
emailRow.Cells.Add(dateCell);
EmailsTable.Rows.AddAt(2 + 0, emailRow);

}
int totalPages;
int mod = totalEmails % NoOfEmailsPerPage;
if (mod == 0)
totalPages = totalEmails / NoOfEmailsPerPage;
else
totalPages = ((totalEmails - mod) / NoOfEmailsPerPage) + 1;

}
}
}

How to retrieve my Gmail messages using Gmail API?

Currently for some reason or another many of the properties are coming back null from any of the requests. We can still get around that if we have a list of the email ids. We then can use these email ids to send out another request to retrieve further details: from, date, subject, and body. @DalmTo was on the right track as well, but not close enough about the headers as it has changed recently which will require a few more requests.

private async Task getEmails()
{
try
{
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
// This OAuth 2.0 access scope allows for read-only access to the authenticated
// user's account, but not other types of account access.
new[] { GmailService.Scope.GmailReadonly, GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailModify },
"NAME OF ACCOUNT NOT EMAIL ADDRESS",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}

var gmailService = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});

var emailListRequest = gmailService.Users.Messages.List("EMAILADDRESSHERE");
emailListRequest.LabelIds = "INBOX";
emailListRequest.IncludeSpamTrash = false;
//emailListRequest.Q = "is:unread"; // This was added because I only wanted unread emails...

// Get our emails
var emailListResponse = await emailListRequest.ExecuteAsync();

if (emailListResponse != null && emailListResponse.Messages != null)
{
// Loop through each email and get what fields you want...
foreach (var email in emailListResponse.Messages)
{
var emailInfoRequest = gmailService.Users.Messages.Get("EMAIL ADDRESS HERE", email.Id);
// Make another request for that email id...
var emailInfoResponse = await emailInfoRequest.ExecuteAsync();

if (emailInfoResponse != null)
{
String from = "";
String date = "";
String subject = "";
String body = "";
// Loop through the headers and get the fields we need...
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if(mParts.Name == "From" )
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}

if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts == null && emailInfoResponse.Payload.Body != null)
{
body = emailInfoResponse.Payload.Body.Data;
}
else
{
body = getNestedParts(emailInfoResponse.Payload.Parts, "");
}
// Need to replace some characters as the data for the email's body is base64
String codedBody = body.Replace("-", "+");
codedBody = codedBody.Replace("_", "/");
byte[] data = Convert.FromBase64String(codedBody);
body = Encoding.UTF8.GetString(data);

// Now you have the data you want...
}
}
}
}
}
}
catch (Exception)
{
MessageBox.Show("Failed to get messages!", "Failed Messages!", MessageBoxButtons.OK);
}
}

static String getNestedParts(IList<MessagePart> part, string curr)
{
string str = curr;
if (part == null)
{
return str;
}
else
{
foreach (var parts in part)
{
if (parts.Parts == null)
{
if (parts.Body != null && parts.Body.Data != null)
{
str += parts.Body.Data;
}
}
else
{
return getNestedParts(parts.Parts, str);
}
}

return str;
}
}

Currently, this method will retrieve all email ids and for each email id get the subject,from, date and body of each email. There are comments throughout the method. If there is something you do not understand, please let me know. On another note: this was tested again before posting this as an answer.



Related Topics



Leave a reply



Submit