ABOUT ME

-

Total
-
  • Spring Boot: Mailsender HTML 보내기
    컴퓨터/HTML & JS & TS 2023. 11. 28. 17:32
    728x90
    반응형

    templates에 있는 passcode.html을 사용하려고 아래처럼 thymeleaf 엔진 설정을 했다.

    spring:
        thymeleaf:
            cache: false
            prefix: classpath:/templates/

     

    Bean 하나 만들어준다. 구글을 사용했다.

    @Configuration
    public class EmailConfig {
        @Value("${spring.mail.username}")
    
        private String FROM_ADDRESS;
    
        @Value("${spring.mail.password}")
        private String EMAIL_PASSWORD;
    
        @Bean
        public JavaMailSender javaMailService() {
            JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
    
            javaMailSender.setHost("smtp.gmail.com");
            javaMailSender.setUsername(FROM_ADDRESS);
            javaMailSender.setPassword(EMAIL_PASSWORD);
            javaMailSender.setPort(587);
            javaMailSender.setJavaMailProperties(getMailProperties());
    
            return javaMailSender;
        }
    
        private Properties getMailProperties() {
            Properties properties = new Properties();
            properties.setProperty("mail.smtp.auth", "true");
            properties.setProperty("mail.smtp.starttls.enable", "true");
            properties.setProperty("mail.smtp.allow8bitmime", "true");
            properties.setProperty("mail.smtps.allow8bitmime", "true");
            return properties;
        }
    }

     

    MULTIPART_MODE_NO 로 했는데 이미지 첨부 안 하고 순수 html 만 보내기 때문이다 그냥 true로 하면 mixed이다.

    @Slf4j
    @Service
    public class EmailService {
    
        @Value("${spring.mail.username}")
    
        private String FROM_ADDRESS;
    
        @Value("${server.address-text}")
        private String server;
    
        @Autowired
        private JavaMailSender emailSender;
    
        @Autowired
        private SpringTemplateEngine templateEngine;
        
        @Async
        public void sendVerificationEmail(String to, String token) {
            String subject = "이메일 인증";
    
            // HTML content
            Context context = new Context();
            context.setVariable("token", token);
    
            String htmlContent = templateEngine.process("passcode", context);
            try {
                MimeMessage message = emailSender.createMimeMessage();
                MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_NO, StandardCharsets.UTF_8.name());
    
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(htmlContent, true); //true' to send HTML
    
                emailSender.send(message);
            } catch (MessagingException e) {
                log.error(e.getMessage());
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "failed to send an email.");
            }
        }

     

    passcode.html은 다음과 같았다.

    <!DOCTYPE html>
    <html>
    <head>
        <style>
            body {
                font-family: 'Arial', sans-serif;
                background-color: #f3f3f3;
                color: #333;
                text-align: center;
                padding: 40px;
            }
            h1 {
                color: #ff4081;
            }
            p {
                font-size: 16px;
            }
            .token {
                display: inline-block;
                background-color: #fff;
                border: 2px dashed #ff4081;
                padding: 10px 20px;
                margin-top: 20px;
                font-size: 20px;
                font-weight: bold;
                letter-spacing: 2px;
            }
        </style>
    </head>
    <body>
        <h1>이메일 인증 토큰</h1>
        <p>아래의 토큰을 사용하여 이메일을 인증해주세요:</p>
        <div class="token">${token}</div>
    </body>
    </html>

     

    근데 지메일에서 스타일이 보이는데 네이버와 같은 곳에서는 텍스트만 나왔다.

    계속 찾아보다가 결국 좀 old 한 클라이언트들을 위해 table로 만들면 된다고 한다.

    그래서 아래처럼 table로 body를 만들고 했더니 잘 보인다.

    (네이버 메일 - 환경 설정 - 서명/빠른 답장 - 사용함 (서명 만들기에 만들 html을 전체 복붙해서 미리 보고 확인하는 게 좋다)

    (스타일도 inplace 하는게 작동할 때도 있다.)

    <body>
    <table style="background-color: #f3f3f3; color: #333; font-size: 16px; text-align: center; margin: 0; padding: 0;" width="100%" cellspacing="0" cellpadding="0">
        <tr>
            <td align="center">
                <table style="margin: 40px auto; border-collapse: separate;" width="600" cellspacing="0" cellpadding="0">
                    <tr>
                        <td style="padding-bottom: 20px;" align="center"> <!-- Added padding-bottom here -->
                            <h1 style="color: #e5b000;">이메일 인증 토큰</h1>
                        </td>
                    </tr>
                    <tr>
                        <td style="padding-bottom: 20px;" align="center"> <!-- And here -->
                            <p>아래의 토큰을 사용하여 이메일을 인증해주세요:</p>
                        </td>
                    </tr>
                    <tr>
                        <td align="center">
                            <div style="background-color: #fff; border: 2px dashed #e5b000; padding: 10px 20px; margin-top: 20px; font-size: 20px; font-weight: bold; letter-spacing: 2px;" th:text="${token}">[Token]</div>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    </body>
    </html>

     

     

    728x90

    댓글