Apsose.Mail.Imap方式收取邮件
目前为止找到的比较好用的邮件组件,支持对exhcange服务器上的邮件阅读状态的保存
public class ImapStyle
{
/// <summary>
/// 存储单个账户的邮件信息
/// </summary>
private List<MailInLocal> AllMail = new List<MailInLocal>();
/// <summary>
/// 归档根目录
/// </summary>
private const string InbOx = "INBOX";
/// <summary>
///
/// </summary>
/// <param name="serverAddr">服务器地址</param>
/// <param name="port">端口</param>
/// <param name="mailAddr">邮件帐号地址</param>
/// <param name="pswd">邮件帐号密码</param>
/// <param name="laseAchineTime">上次归档时间</param>
public void GetEmails(string serverAddr, int port, string mailAddr, string pswd, DateTime laseAchineTime)
{
try
{
AllMail.Clear();
using (var client = new ImapClient())
{
//port = 993;
client.Port = port;
client.Host = serverAddr;
client.Username = mailAddr;
client.Password = pswd;
//client.SecurityMode = ImapSslSecurityMode.Implicit;
//client.EnableSsl = true;
client.Connect();
client.Login();
client.SelectFolder(InbOx);
LoadMails(client, InbOx, laseAchineTime);
var folders = client.ListFolders(InbOx);
Utility.WriteLog(string.Format("收件箱下的子目录数:{0} ", folders.Count));
foreach (var folder in folders)
{
LoadMails(client, folder.Name, laseAchineTime);
}
}
}
catch (Exception e)
{
Utility.WriteLog(string.Format("归档邮箱:{0}失败,异常信息:{1} ", mailAddr, e));
}
}
/// <summary>
/// load账户邮件信息
/// </summary>
/// <param name="client">imapclient</param>
/// <param name="folderName">收件箱里文件夹名称</param>
/// <param name="laseAchineTime">上次归档时间</param>
private void LoadMails(ImapClient client, string folderName, DateTime laseAchineTime)
{
client.SelectFolder(folderName);
var list = client.ListMessages();
var ls = list.OrderByDescending(mail => mail.Date);
Utility.WriteLog(string.Format("开始归档目录:{0},当前目录总的邮件数目:{1}", folderName, list.Count));
foreach (var eachItem in ls)
{
#region exchnage,支持 阅读状态
var isRead = client.ListMessage(eachItem.UniqueId).IsRead;
var msg = client.FetchMessage(eachItem.UniqueId);
if (!isRead)
client.ChangeMessageFlags(eachItem.UniqueId, ImapMessageFlags.Recent);
#endregion
#region 163等,不维持阅读状态
// var msg = client.FetchMessage(eachItem.UniqueId);
#endregion
var to = msg.To.Aggregate("", (current, item) => current + (item.Address + ";"));
var cc = "";
if (msg.CC != null)
cc = msg.CC.Aggregate(cc, (current, item) => current + (item.Address + ";"));
var mail = new MailInLocal
{
MailId = msg.MessageId,
Refrence = FilterReferences(msg.Headers.Get("References")),
From = msg.From.DisplayName,
FormAddr = msg.From.Address,
ToRecipients = to,
CcRecipients = cc,
MailSubject = msg.Subject
};
mail.MailSubject = FilterString(mail.MailSubject);
mail.SendTime = msg.Date.AddHours(8);//utc 时间 +8
Utility.WriteLog(string.Format("文件夹 {0} 下符的邮件:{1},发送时间:{2} ,是否归档:{3} ", folderName, mail.MailSubject, mail.SendTime, mail.SendTime >= laseAchineTime));
//上次归档前的不再归档
if (mail.SendTime < laseAchineTime)
return;
var id = mail.MailId == null ? "" : mail.MailId.Replace("<", "").Replace(">", "").Split('@')[0];
var path = AppDomain.CurrentDomain.BaseDirectory + "MailArchiveTemp\\" + mail.MailSubject + id + ".eml";
Utility.WriteLog(string.Format("文件夹 {0} 下符符合条件的邮件:{1} ", folderName, path));
var dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
if (!File.Exists(path))
msg.Save(path);
mail.MailPath = path;
AllMail.Add(mail);
}
}
/// <summary>
/// 按照时间先后顺序排序
/// </summary>
/// <returns></returns>
public List<MailInLocal> MailListInOrder()
{
var reult = from item in AllMail orderby item.SendTime select item;
return reult.ToList();
}
/// <summary>
/// 过滤命名规则不允许的字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private static string FilterString(string str)
{
return str
.Replace("\\", "")
.Replace("/", "")
.Replace(":", "")
.Replace("?", "")
.Replace("\"", "")
.Replace("=", "")
.Replace("<", "")
.Replace(">", "")
.Replace("*", "")
.Replace(":", "")
.Replace("|", "").Trim()
;
}
/// <summary>
/// 过滤邮件的引用id,只保留原始引用
/// </summary>
/// <param name="refStr">引用字符串</param>
/// <returns></returns>
private static string FilterReferences(string refStr)
{
if (string.IsNullOrEmpty(refStr))
return refStr;
return refStr.Split(',')[0];
}
}