OpenPop实现接受QQ邮件
MIME邮件格式解析
Message的属性
Headers是邮件得头部信息
- Subject (主题): 邮件的主题或标题。
- From (发件人): 邮件的发件人地址。
- To (收件人): 邮件的收件人地址列表。
- CC (抄送): 邮件的抄送(抄送副本)地址列表。
- BCC (密送): 邮件的密送(密送副本)地址列表,这些地址不会在邮件中显示给其他收件人。
- Date (日期): 邮件的发送日期和时间。
- Message ID (消息标识符): 邮件的唯一标识符,通常用于跟踪和引用邮件。
- Content-Type (内容类型): 邮件消息的内容类型,例如文本、HTML、附件等。
- Content-Disposition (内容分配): 邮件消息的内容分配类型,例如附件的内联或附件类型。
- Content-Description (内容描述): 描述邮件消息内容的文本。
- Content-Transfer-Encoding (内容传输编码): 指定了邮件消息内容的传输编码,例如 Base64。
- MIME-Version (MIME 版本): MIME 协议的版本号。
- X-Priority (优先级): 邮件的优先级,通常有 “High”(高)、“Normal”(正常)和 “Low”(低)等选项。
MassagePart
- ContentType (内容类型): ContentType 属性指定了 MessagePart 的内容类型,它告诉你这部分消息是文本、HTML、附件还是其他类型的内容。例如,“text/plain” 表示纯文本内容,“text/html” 表示 HTML 内容。
- Content-Disposition (内容分配): ContentDisposition 属性指定了消息部分的内容分配类型。它告诉你这部分消息是以内联方式显示还是作为附件。
- Content-Description (内容描述): ContentDescription 属性提供了描述消息部分内容的文本,通常用于提供附件的描述信息。
- Content-Transfer-Encoding (内容传输编码): ContentTransferEncoding 属性指定了消息部分的内容传输编码,例如 Base64 编码。
- Body (内容体): Body 属性包含了消息部分的实际内容,它可以是文本、HTML 或二进制数据,具体取决于消息部分的内容类型。
- IsText (是否为文本): IsText 属性指示消息部分是否包含文本内容。如果为 true,则消息部分包含文本内容,否则它可能是二进制数据或其他非文本内容。
- IsMultiPart (是否为多部分内容): IsMultiPart 属性指示消息部分是否包含多个子部分,通常用于表示消息部分的内容是多部分 MIME 消息。
- IsAttachment (是否为附件): IsAttachment 属性指示消息部分是否是一个附件。如果为 true,则消息部分是附件;如果为 false,则它可能是正文内容。
- ContentId (内容 ID): ContentId 属性包含消息部分的内容 ID,通常用于标识嵌入式内容。
补充
ContentType
由于RFC822邮件格只适合用来表达纯文本的邮件内容,针对这个问题,后来人们为此定义了MIME(Multipurpose Internet Mail Extension,多用途Internet邮件扩展)协议
MIME协议用于定义复杂邮件体的格式,可以在邮件体中内嵌图片数据和附件。
MIME消息的头字段Content-Type有三种类型:multipart/mixed、multipart/related、multipart/alternative(一封MIME邮件中的MIME消息可以有这三种组合关系)
multipart/mixed,只要包含附件就必须使用这种格式。multipart/related、包含一些内嵌资源需要使用这个格式,比如嵌入图片,通过ContentId让链接嵌入的内容 。只有纯文本内容使用multipart/alternative。
MassageParts与MassagePart的关系。
Message有根属性MessagePart,MessagePart与MessageParts的关系是树形关系。
这里是Message.MessagePart,因为包含了附件所以ContentType是multipart/mixed.
MassgePart.MessageParts包含了附件和正文两个部分,所以是Count = 2
MessagePart的MessageParts包括了正文,附件等信息。
【0】就是正文部分,正文包含了两种类型的信息,有内嵌数据资源,所以格式为multipart/related,被分割为两部分。
【1】是附件,无法分割,到这里MessagePart与MessageParts你中有我的树形关系就结束了。
判断是否是附件
如果Contentdisposition没有Attachment且,IsAttachmen为false就不是附件,如果满足一个就是附件。
判断是否是内嵌资源
Contentdisposition是inline则是内嵌资源。
一、首先打开QQ的Pop服务
进入设置,选择账户,选择开启服务,会进入验证环节,验证通过后会有一个授权码,记录下来。
二、引入OpenPop的Nuget包
三、实现QQ服务器连接并接受邮件
[HttpGet("Pop")]
public async Task Pop()
{
// QQ 邮箱的设置
string hostname = "pop.qq.com";
int port = 995; // 使用 SSL 的 POP3 端口
bool useSsl = true; // 使用 SSL 加密
string username = "qq邮件地址";
string password = "获取的授权码";
using (Pop3Client client = new Pop3Client())
{
// 连接到 QQ 邮箱服务器
client.Connect(hostname, port, useSsl);
client.Authenticate(username, password);
// 获取邮件数量
int messageCount = client.GetMessageCount();
Console.WriteLine($"Total messages: {messageCount}");
// 遍历邮件消息
for (int i = 1; i <= messageCount; i++)
{
Message message = client.GetMessage(i);
Console.WriteLine($"Subject: {message.Headers.Subject}");
Console.WriteLine($"From: {message.Headers.From.Address}");
Console.WriteLine($"Date: {message.Headers.DateSent}");
Console.WriteLine($"Message body: {message.FindFirstPlainTextVersion().GetBodyAsText()}");
Console.WriteLine("-----------------------------------");
}
// 断开连接
client.Disconnect();
}
}
四、发送邮件(这个不用OpenPop就行)
[HttpGet("SendMail")]
public async Task SendMail()
{
// QQ 邮箱的设置
string smtpHost = "smtp.qq.com";
int smtpPort = 587; // 使用 SSL 的 SMTP 端口
bool enableSsl = true; // 使用 SSL 加密
string fromEmail = "发件邮箱地址";
string fromPassword = "获取的授权码";
string toEmail = "接收邮件地址"; // 接收方邮箱地址
// 创建 SmtpClient 实例
SmtpClient smtpClient = new SmtpClient(smtpHost, smtpPort)
{
UseDefaultCredentials = false,
Credentials = new NetworkCredential(fromEmail, fromPassword),
EnableSsl = enableSsl
};
// 创建 MailMessage 实例
MailMessage mailMessage = new MailMessage(fromEmail, toEmail)
{
Subject = "Test Email Subject",
Body = "This is a test email from C#.",
IsBodyHtml = false
};
try
{
// 发送邮件
smtpClient.Send(mailMessage);
Console.WriteLine("Email sent successfully.");
}
catch (Exception ex)
{
Console.WriteLine($"Error sending email: {ex.Message}");
}
}
五、发送附带文件的邮件
using (MemoryStream excelStream = new MemoryStream(dto))
{
try
{
var mailUserName = _internalConfigStoreService.GetData()?.FirstOrDefault(_ => _.SubKey == 8)?.Value;
var mailPassword = _internalConfigStoreService.GetData()?.FirstOrDefault(_ => _.SubKey == 9)?.Value;
MailMessage mailMessage = new MailMessage();
// 发件人
mailMessage.From = new MailAddress(mailUserName);
//收件人
mailMessage.To.Add("123456@qq.cn,78945@qq.cn");
mailMessage.Subject = "excel";
mailMessage.Body = "excel";
ContentType contentType = new ContentType(MediaTypeNames.Application.Octet)
{
Name = "excel.xlsx"
};
Attachment attachment = new Attachment(excelStream, contentType);
mailMessage.Attachments.Add(attachment);
//服务器地址,端口
SmtpClient smtpClient = new SmtpClient("qq.cn", 587)
{
Credentials = new NetworkCredential(mailUserName, mailPassword),
EnableSsl = false
};
// 发送邮件
smtpClient.Send(mailMessage);
}
catch (Exception e)
{
var a = e;
}
}