Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package site.icebang.domain.email.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import lombok.RequiredArgsConstructor;

import site.icebang.domain.email.dto.EmailRequest;
import site.icebang.domain.email.service.EmailService;

@RestController
@RequestMapping("/api/v1/email")
@RequiredArgsConstructor
public class EmailTestController {
private final EmailService emailService;

@GetMapping("/test")
@PreAuthorize("permitAll()")
public ResponseEntity<String> sendTestEmail(@RequestParam String to) {
try {
EmailRequest emailRequest =
EmailRequest.builder()
.to(to)
.subject("IceBang 실제 테스트 이메일")
.body("안녕하세요!\n\nIceBang에서 보내는 실제 Gmail 테스트 이메일입니다.\n\n성공적으로 연동되었습니다!")
.isHtml(false)
.build();

emailService.send(emailRequest);
return ResponseEntity.ok("실제 Gmail 테스트 이메일 전송 완료! 받은편지함을 확인하세요!");

} catch (Exception e) {
return ResponseEntity.badRequest().body("이메일 전송 실패: " + e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,92 @@
// package site.icebang.domain.email.service;
//
// import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
// import org.springframework.stereotype.Service;
//
// import lombok.RequiredArgsConstructor;
//
// import site.icebang.domain.email.dto.EmailRequest;
//
// @Service
// @RequiredArgsConstructor
package site.icebang.domain.email.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import site.icebang.domain.email.dto.EmailRequest;

@Slf4j
@Service
@Profile({"production"})
@RequiredArgsConstructor
// @ConditionalOnMissingBean(EmailService.class)
// public class EmailServiceImpl implements EmailService {
// @Override
// public void send(EmailRequest emailRequest) {}
// }
public class EmailServiceImpl implements EmailService {

private final JavaMailSender mailSender;

@Value("${spring.mail.username}")
private String defaultSender;

@Override
public void send(EmailRequest request) {
try {
if (request.isHtml()) {
sendHtmlEmail(request);
} else {
sendSimpleEmail(request);
}
} catch (Exception e) {
log.error("❌ 이메일 전송 실패 - To: {}", request.getTo(), e);
throw new RuntimeException("이메일 전송 실패: " + e.getMessage(), e);
}
}

private void sendSimpleEmail(EmailRequest request) {
try {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(request.getTo());
message.setSubject(request.getSubject());
message.setText(request.getBody());
message.setFrom(defaultSender);

// CC 설정
if (request.getCc() != null && !request.getCc().isEmpty()) {
message.setCc(request.getCc().toArray(new String[0]));
}

// BCC 설정
if (request.getBcc() != null && !request.getBcc().isEmpty()) {
message.setBcc(request.getBcc().toArray(new String[0]));
}

mailSender.send(message);
log.info("✅ 실제 Gmail 전송 성공! To: {}, Subject: {}", request.getTo(), request.getSubject());

} catch (Exception e) {
log.error("❌ Gmail 텍스트 전송 실패", e);
throw e;
}
}

private void sendHtmlEmail(EmailRequest request) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

helper.setTo(request.getTo());
helper.setSubject(request.getSubject());
helper.setText(request.getBody(), true); // HTML 모드
helper.setFrom(defaultSender);

// CC 설정
if (request.getCc() != null && !request.getCc().isEmpty()) {
helper.setCc(request.getCc().toArray(new String[0]));
}

// BCC 설정
if (request.getBcc() != null && !request.getBcc().isEmpty()) {
helper.setBcc(request.getBcc().toArray(new String[0]));
}

mailSender.send(message);
log.info("✅ 실제 Gmail HTML 전송 성공! To: {}, Subject: {}", request.getTo(), request.getSubject());
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package site.icebang.domain.email.service;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

import site.icebang.domain.email.dto.EmailRequest;

@Service
// @Profile({"test-unit", "test-e2e", "test-integration", "local", "develop", "production"})
@Profile({"develop", "test-e2e", "test-integration", "test-unit"})
@Slf4j
public class MockEmailService implements EmailService {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.permitAll()
.requestMatchers("/v0/workflows/**")
.permitAll()
.requestMatchers("/api/v1/email/**") // 이메일 API 경로 허용
.permitAll()
.requestMatchers("/v0/auth/check-session")
.authenticated()
.requestMatchers(SecurityEndpoints.DATA_ADMIN.getMatchers())
Expand Down
16 changes: 16 additions & 0 deletions apps/user-service/src/main/resources/application-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ spring:
minimum-idle: 5
pool-name: HikariCP-MyBatis

# Gmail 연동 설정
mail:
host: smtp.gmail.com
port: 587
username: ${MAIL_USERNAME}
password: ${MAIL_PASSWORD}
properties:
mail:
smtp:
auth: true
starttls:
enable: true
connectiontimeout: 5000
timeout: 5000
writetimeout: 5000
debug: true
# quartz:
# jdbc:
# initialize-schema: never
Expand Down
Loading