package ru.ulstu.user.service; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.mail.MailProperties; import org.springframework.mail.MailException; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.thymeleaf.context.Context; import org.thymeleaf.spring4.SpringTemplateEngine; import ru.ulstu.configuration.ApplicationProperties; import ru.ulstu.configuration.Constants; import ru.ulstu.user.model.User; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import java.nio.charset.StandardCharsets; import java.util.Map; @Service public class MailService { private static final String USER = "user"; private static final String BASE_URL = "baseUrl"; private final Logger log = LoggerFactory.getLogger(MailService.class); private final JavaMailSender javaMailSender; private final SpringTemplateEngine templateEngine; private final MailProperties mailProperties; private final ApplicationProperties applicationProperties; public MailService(JavaMailSender javaMailSender, SpringTemplateEngine templateEngine, MailProperties mailProperties, ApplicationProperties applicationProperties) { this.javaMailSender = javaMailSender; this.templateEngine = templateEngine; this.mailProperties = mailProperties; this.applicationProperties = applicationProperties; } @Async public void sendEmail(String to, String subject, String content) throws MessagingException, MailException { log.debug("Send email to '{}' with subject '{}'", to, subject); MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper message = new MimeMessageHelper(mimeMessage, false, StandardCharsets.UTF_8.name()); message.setTo(to); message.setFrom(mailProperties.getUsername()); message.setSubject(subject); message.setText(content, true); modifyForDebug(message, subject); javaMailSender.send(mimeMessage); log.debug("Sent email to User '{}'", to); } private void modifyForDebug(MimeMessageHelper message, String originalSubject) throws MessagingException { if (!StringUtils.isEmpty(applicationProperties.getDebugEmail())) { message.setTo(applicationProperties.getDebugEmail()); message.setSubject("To " + applicationProperties.getDebugEmail() + "; " + originalSubject); } } @Async public void sendEmailFromTemplate(User user, String templateName, String subject) { Context context = new Context(); context.setVariable(USER, user); context.setVariable(BASE_URL, applicationProperties.getBaseUrl()); String content = templateEngine.process(templateName, context); try { sendEmail(user.getEmail(), subject, content); } catch ( Exception e) { if (log.isDebugEnabled()) { log.warn("Email could not be sent to user '{}'", user.getEmail(), e); } else { log.warn("Email could not be sent to user '{}': {}", user.getEmail(), e.getMessage()); } } } //Todo: выделить сервис нотификаций @Async public void sendEmailFromTemplate(Map variables, User user, String templateName, String subject) { Context context = new Context(); variables.entrySet().forEach(entry -> context.setVariable(entry.getKey(), entry.getValue())); context.setVariable(USER, user); context.setVariable(BASE_URL, applicationProperties.getBaseUrl()); String content = templateEngine.process(templateName, context); try { sendEmail(user.getEmail(), subject, content); } catch ( Exception e) { if (log.isDebugEnabled()) { log.warn("Email could not be sent to user '{}'", user.getEmail(), e); } else { log.warn("Email could not be sent to user '{}': {}", user.getEmail(), e.getMessage()); } } } @Async public void sendEmailFromTemplate(Map variables, String templateName, String subject, String email) throws MessagingException { Context context = new Context(); variables.entrySet().forEach(entry -> context.setVariable(entry.getKey(), entry.getValue())); context.setVariable(BASE_URL, applicationProperties.getBaseUrl()); String content = templateEngine.process(templateName, context); sendEmail(email, subject, content); } @Async public void sendActivationEmail(User user) { sendEmailFromTemplate(user, "activationEmail", Constants.MAIL_ACTIVATE); } public void sendPasswordResetMail(User user) throws MessagingException, MailException { sendEmailFromTemplate(user, "passwordResetEmail", Constants.MAIL_RESET); } public void sendInviteMail(Map variables, String email) throws MessagingException, MailException { sendEmailFromTemplate(variables, "userInviteEmail", Constants.MAIL_INVITE, email); } @Async public void sendChangePasswordMail(User user) { sendEmailFromTemplate(user, "passwordChangeEmail", Constants.MAIL_CHANGE_PASSWORD); } }