Отправка email на C++
Как использовать C++ и SMTP для отправки письма с вложением или iCalendar
Скачать бесплатную пробную версиюКак правило, для отправки писем используется протокол SMTP. Для отправки сообщения необходим доступ к SMTP‑серверу: нужно узнать его адрес в сети, определить порт и тип шифрования, способ входа и авторизации. Некоторые провайдеры также требуют включить доступ к SMTP‑серверу в настройках аккаунта. Если вам не удобно реализовывать OAuth‑авторизацию в приложении, можно создать отдельный пароль для приложения в настройках аккаунта.
Итак, если вы завершили подготовительные работы, пора начать отправлять сообщения. Для этого можно воспользоваться библиотекой Aspose.Email для 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");
Используйте эту опцию, если хотите отправить простое текстовое письмо.
Отправка email с вложениями на 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 Message Format). С его помощью можно отправлять вложения или даже объекты iCalendar для организации или подтверждения встречи. MailMessage позволяет точно настраивать список получателей, копий (Cc) и скрытых копий (Bcc). Можно отправлять письмо с разметкой HTML, а также помечать сообщение различными флагами, добавлять метаданные, шифровать его и т.д.
Почему люди выбирают Aspose.Email for C++ для отправки писем?
Да, Aspose.Email for C++ — это не просто утилита для отправки писем. Это комплексное решение, предоставляющее полную поддержку различных задач, связанных с отправкой, получением, хранением и обработкой электронной почты. Вы можете быть уверены, что при выполнении этих задач вы не столкнётесь с ограничениями библиотеки. Мы изучаем эту тему много лет и постоянно расширяем её функциональность.
Вы, вероятно, сталкивались с небольшими библиотеками, появившимися относительно недавно. Они легко и естественно решают простую задачу, с которой сталкивается множество пользователей. Но как только вы отодвигаетесь чуть дальше, понимаете, что продолжая использовать эту скромную библиотеку, вам постоянно приходится обходить её ограничения различными костылями, модулями, адаптерами, чтобы «подружить» её с другими библиотеками. И теперь ваше маленькое удобное решение перестаёт быть таким удобным. К тому же, отправляя его на сервер, оно постоянно «стрелит себе в ногу», потому что никто не тестировал такой зоопарк костылей и интеграций до вас. Как бы вы ни пытались, рано или поздно вы всё равно столкнётесь с ограничениями этой библиотеки и придётся искать что‑то новое. Поэтому, когда речь идёт о работе с email, стоит обратить внимание на 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, если тот более недействителен.
Другой вариант — интерфейс ITokenProvider. В этом случае вы можете не только самостоятельно реализовать механизм OAuth, но и передать его в SmtpClient, чтобы он использовал его при необходимости.
Следует отметить, что механизм OAuth не всегда обязателен. Иногда гораздо проще войти, используя имя пользователя и пароль. Для этого не требуется перенастраивать аккаунт, отказываться от двухфакторной аутентификации и т.д. Более безопасное решение — отдельный пароль для приложения. Чтобы воспользоваться этой функцией, проверьте настройки вашего почтового аккаунта. Скорее всего, пароль для приложения будет сгенерирован автоматически при его создании в аккаунте. Не забудьте сохранить его где‑нибудь. Мы также рекомендуем по возможности ограничить права приложения при настройке. Конечно, если злоумышленник получит доступ к этому паролю, он не сможет полностью захватить ваш аккаунт, но всё равно сможет нанести значительный вред. Здесь ничего нельзя сделать, поскольку пароль — единственная защита ваших данных от злоумышленников. В целом инструмент очень удобен, но снижает безопасность вашего аккаунта; используйте его на свой страх и риск.
Отправка email через SMTP с C++
Итак, соединение с сервером установлено, и авторизация прошла успешно. Пришло время отправлять письма. Для отправки используется объект класса MailMessage. Технически можно просто передать все необходимые данные методу send, но на самом деле они всё равно собираются в объект MailMessage. Затем, благодаря возможности класса MailMessage сериализовать данные в формат EML, мы получаем поток данных, который можно передать нашему SMTP‑серверу. Таким образом, мы отдаем серверу команду отправить письмо и передаём ему всё содержимое в виде текстовых данных. Если в письме передаются бинарные данные, например, вложенные файлы, они кодируются в формате Base64, а метаданные письма указывают получателю, что их нужно декодировать обратно. SMTP‑сервер может проверить корректность полученного сообщения (например, сопоставить поле FROM с аккаунтом отправителя на сервере), а также по своему усмотрению дополнить метаданные сообщения. Затем сервер отправит email получателям, список которых он также получает из метаданных письма.