Не так давно у меня появилась необходимость на нескольких проектах сделать регистрацию с подтверждением email, так же хотелось минимизировать затраты и исключить лишние телодвижения, так сказать методом ctrl+c ctrl+v, без танцев с бубном. Так же нам не нужно принимать почту и прочее, просто отправка, не более
P.s. Для прожженных отцов разработки ничего нового тут не будет
Итак, поехали ;-)
Аренда VPS
Самое важное чтоб был открыт порт - 465 (Многие их или закрывают полностью, или нужно пройти 7 кругов ада)
Так же ресурсы, опытным путем было выявлено что необходимо 2 ядра CPU и 2 GB RAM, на меньших ресурсах зависает даже в простое, про минимальные рассылки и вовсе стоит забыть
У одного известного немецкого хостера можно взять так (конечно есть проблемы с оплатой из РФ, но если заморочиться то это выгоднее чем переплачивать реселлерам х3-х4)
Настройка ОС и SMTP
Девственно чистая Ubuntu последних версий из коробки
Установка Mailu, у них есть классный конфигуратор
Как конфигурировать ?
Добавить А запись аля mail.example.com A ваш_ip (иначе letsencrypt не подтянет сертификат)
У хостера добавить к IP адресу PTR запись которая будет ссылаться на mail.example.com
Далее
По сути все, далее конфигуратор нам даст набор команд
Выполняем команды, заходим в админку https://mail.example.com
Единственное что важно, на последнем этапе вместо PASSWORD можно указать свой_пароль, чтоб потом его не менять через UI
Настройка Mailu
Зайти в админку указав admin@mail.example.com и свой_пароль
В самой админке переходим на вкладку - Почтовые домены - Действия
Тут нам важно Сгенерировать ключи и скачать все настройки (Download zonefile)
Далее импортируем zonefile в свой домен
И последний этап создать пользователя - указать логин (например noreply) и пароль
На выходе получится noreply@mail.example.com и пароль
По сути все, почтовый сервер настроен и готов к использованию, остается только использовать его в приложении
Java
Используем Spring Boot, в зависимости добавим
implementation 'org.springframework.boot:spring-boot-starter-mail'
В application.yml
spring:
mail:
host: mail.example.com
port: 465
username: noreply@mail.example.com
password: qwer1234
properties:
mail:
smtp:
auth: true
ssl:
enable: true
И само использование
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
@Service
@RequiredArgsConstructor
public class MailService {
private final MailProperties mailProperties;
private final JavaMailSender mailSender;
public Mono<Boolean> send(String email, String title, String text) {
return Mono.fromCallable(() -> {
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true);
mimeMessageHelper.setFrom("BestCompany <" + mailProperties.getUsername() + ">");
mimeMessageHelper.setTo(email);
mimeMessageHelper.setSubject(title);
mimeMessageHelper.setText(text, true);
mailSender.send(mimeMessageHelper.getMimeMessage());
} catch (Exception e) {
e.printStackTrace();
}
return true;
});
}
}
Go
Добавим пакет
go get gopkg.in/gomail.v2
Инициализируем клиент
mailDialer := gomail.NewDialer(
"mail.exmaple.com",
465,
"noreply@mail.exmaple.com",
"qwer1234",
)
mailDialer.SSL = true
Отправим письмо
m := gomail.NewMessage()
m.SetHeader("From", "noreply@mail.exmaple.com")
m.SetHeader("To", to)
m.SetHeader("Subject", subject)
m.SetBody("text/plain", body)
err := mailDialer.DialAndSend(m)
Профит ;-)
Мой Telegram канал — Синдром ИТшника
KotPoliglot
Слишком сложная схема для отправки писем о регистрации, когда приложение все равно отправляет по smtp xD
sensei_developer Автор
Вы всегда можете поделиться более лучшим вариантом ;-)
tuxi
С учетом того, что созданный мейл-сервер с высокой вероятностью очень скоро окажется в блеклистах основных почтовых служб, проще использовать готовые почтовые службы с их готовыми api, и думаю, что это будет не дороже оплаты VPS.
Ну и теми строками кода вы не отделаетесь. Надо делать очередь отправки, вводить лимиты на отправку, проверять на дубли, проверять на спам, проверять на сетевые ошибки, повторять отправку, чистить очередь если превышен предел повторных отправок, кучу кучу всего придется доделывать/дописывать.
sensei_developer Автор
А почему с высокой вероятностью очень скоро окажется в блеклистах основных почтовых служб ?
geirby
А вы точно "сенсей"?
tuxi
Полный набор причин для бана не раскрывается обычно, но как правило это
1. низкое доверие к домену
2. рассылка однотипных по содержанию писем
3. частота и плотность рассылки, все это выбивается обычно из нормальной модели поведения
плюс некоторые недовольные клиенты будут постить репорты, по некоторым базам, на основании которых потом составляются черные списки, насколько я помню, достаточно 10 репортов чтобы попасть в их список.
sensei_developer Автор
И как эти все пункты относятся к почтовому серверу ? Это история уже про бизнес логику, нет ?
egribanov
Большие компании очень не любят, когда письма шлют со своих самоподнятых серверов и сразу шлют в спам. Такова жизнь
tuxi
Я выше писал, что это работа ради работы. Создать почтовую службу которая будет дергать SMTP сервер - это не сложно. Есть в конце концов org.apache.commons.mail никакого спринг бута совсем не надо.
Я указывал на две проблемы. Первая: затраты на развертывание и администрирование VPS превышают пользу от него. Вторая: организовать отправку писем правильно, это еще на вскидку +90% к той работе, которая была выполнена в рамках статьи.
В тоже время сторонние почтовые службы уже решили все эти проблемы, поддерживают очереди отправки, повторные отправки в случае сетевых ошибок и тп и тд. Использовать свой почтовый сервер целесообразно как правило только в рамках отправки почты внутри своего домена. Как то так если коротенько.
KotPoliglot
Да exim, postfix и т.д, да и куча инструментов и с докером и без для отправки писем. Основная работа, как и написал @tuxiзаключается в том, чтобы не уйти в спам-листы и убедиться что все твои письма отправлены