通常使用 SMTP 协议发送邮件。发送邮件需要访问 SMTP 服务器,需要在网络上找到服务器地址,确定端口和加密类型,以及登录和授权方式。一些邮件提供商还要求在账户设置中启用对 SMTP 服务器的访问。如果您不想在软件中实现 OAuth 授权,可以尝试在账户设置中为应用创建单独的密码。
因此,在完成所有准备工作后,就可以开始发送邮件了。您可以使用 Aspose.Email for C++ 库。以下是最简单的示例:
auto smtpClient = MakeObject<SmtpClient>(u"smtp.gmail.com", u"login", u"password", SecurityOptions::SSLAuto);
smtpClient->Send(u"login@gmail.com", u"to@gmail.com", u"subject", u"body");
如果您想发送纯文本邮件,请使用此选项。
使用 C++ 发送带附件的邮件
如果需要使用 C++ 发送复杂邮件,MailMessage 类将非常有用。例如,发送类似于前述的邮件:
auto message = MakeObject<MailMessage>(u"login@gmail.com", u"to@aspose.com", u"subject", u"body");
smtpClient->Send(message);
MailMessage 类是极佳的工具。它允许发送存储在 EML 和 MSG(Outlook 消息格式)文件中的邮件。您还可以使用该格式发送附件或 iCalendar 对象,以安排或确认会议。MailMessage 让您精细控制收件人、抄送和密送列表。可以发送带 HTML 标记的邮件,亦可在发送前为消息添加各种标记、元数据、加密等。
人们为何选择 Aspose.Email for C++ 来发送邮件?
是的,Aspose.Email for C++ 不仅是发送邮件的工具,而是一个提供发送、接收、存储和处理电子邮件等多种任务完整支持的综合解决方案。您可以放心,在执行这些任务时不会受到库的限制。我们多年来一直深耕此领域,并不断扩展功能。
您可能遇到过一些最近出现的小型库,它们轻松自然地解决了许多用户面临的简单问题。但稍作停留后,您会发现继续使用这套不够成熟的库会迫使您不断编写临时代码、模块来绕过限制、适配器来与其他小库配合等。于是,这个看似巧妙的方案不再巧妙。更糟的是,将其部署到服务器后常常自寻烦恼,因为没有人事先测试过如此庞杂的临时补丁和集成。无论怎么努力,迟早会碰到该库的局限,迫使您寻找新方案。因此,在处理邮件时,您或许应考虑 Aspose.Email for C++!
我们提供的不仅是 SMTP 客户端。首先,这并非使用 C++ 发送邮件的唯一协议。使用我们的产品,您还能通过 Exchange EWS 和 Microsoft Graph 发送邮件!
我们已在本文中介绍了 MailMessage 的功能。但它并非唯一的邮件准备工具。您还可以:
- 使用 TemplateEngine 从模板生成邮件;
- 得益于对 OST、PST 和 MBOX 格式的支持,解压包含邮件的容器;
- 使用 IMAP、POP3、Exchange EWS、WebDav 协议以及 Microsoft Graph 支持从邮箱下载邮件;
- 将邮件从一种格式转换为另一种格式。
您可以轻松使用 Exchange EWS 协议接收邮件,默认为 MAPI 格式。但可轻松转换为 EML 格式,以便后续通过 SMTP 发送。同时,您可以随时更改收件人列表或发件人。
使用 C++ 和 SMTP 发送邮件的工作原理是怎样的?
SMTP 配置
当您实例化 SmtpClient 类时,并不会立即发生任何特殊操作。您只需提供若干设置,以便日后能够连接 SMTP 服务器发送邮件。所有实际工作将在第一次调用 send 方法。此时发生了什么?
实际上,这取决于您所指定的设置。下面列举几种情况。假设您已指定服务器主机,但未指定端口和加密类型。此时会启动自动选择设置机制。该机制会依次尝试使用标准端口和对应的加密算法连接 SMTP 服务器。首先尝试通过加密通道连接;若失败,机制会尝试建立未加密的连接。如果您不想使用未加密的协议,请指定 SecurityOptions.SSL_AUTO 设置。此设置同样用于选择服务器配置,但仅检查加密通道。
如果成功建立与服务器的连接,则进行授权尝试。若授权失败,会保存错误码以供后续使用。匹配器会尝试其他连接方式。只要能够连接并登录,邮件就会发送。若连接失败,用户将收到授权错误码(若在选择过程中已保存)。如此用户即可判断是密码错误还是其他问题。如果所有端口和加密类型的组合均不匹配,甚至未进行授权尝试,用户将收到有关服务器设置错误的提示。
顺便说明,我们的 SmtpClient(以及库中所有其他客户端)均可通过代理连接 SMTP 服务器,您也可以在初始化时指定代理服务器设置。
SMTP 客户端授权
SmtpClient 不仅支持多种连接方式,还支持多种授权方式。例如,您可使用 OAuth 机制。为此我们一次性提供了多种工具。
首先是 TokenProvider 类。它用于存放和刷新 OAuth 令牌的所有必要数据。您需要自行完成 OAuth 授权并保存从 OAuth 服务器获取的所有信息。RefreshToken 在此发挥关键作用,它是授权服务器随 AccessToken 一起下发的额外令牌。两者的区别在于 AccessToken 通常仅在限定时间内有效,而 RefreshToken 的有效期更长,甚至无限(直至用户撤销)。凭借 RefreshToken,TokenProvider 类可以在 AccessToken 失效时随时刷新获取新的 AccessToken。
另一种方案是使用 ITokenProvider 接口。这样您既可以自行实现 OAuth 机制,又可以将其传递给 SmtpClient,由其在需要时使用。
需要说明的是,OAuth 机制并非总是必需的。有时使用用户名和密码登录更为简便,而且无需重新配置邮箱、关闭双因素认证等。更安全的做法是为应用生成单独的密码。要使用此功能,请检查您的邮箱账户设置,通常在账户中设置后会自动生成应用密码,请妥善保存。我们还建议在配置时尽可能限制应用的权限。当然,即使攻击者获取了该密码,也无法直接窃取您的账户,但仍可能实施许多不良行为。此时您也无能为力,因为密码是唯一的防护手段。总体而言,此工具非常便利,却会降低账户安全性,请自行斟酌使用。
使用 C++ 通过 SMTP 发送邮件
因此,已成功建立与服务器的连接并完成授权。接下来是发送邮件。发送时使用 MailMessage 类的实例。技术上您可以直接将所有必要数据传给 send 方法,但实际上这些数据仍会被收集到 MailMessage 对象中。随后,利用 MailMessage 能序列化为 EML 格式的特性,我们获得可传递给 SMTP 服务器的数据流。于是向服务器发出发送指令,并以文本数据形式传输邮件的全部内容。如果邮件中包含二进制数据(如附件),这些数据会以 Base64 编码,邮件元数据会标明收件人需进行解码。SMTP 服务器可以检查收到的消息是否正确(例如,对比 FROM 字段与服务器上发件人账户),并可自行补充消息元数据。随后服务器根据邮件元数据中的收件人列表将邮件发送给相应收件人。