diff --git a/build.gradle b/build.gradle index 2ad29ec..0db97ed 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,8 @@ dependencies { implementation 'org.springdoc:springdoc-openapi-starter-common:2.1.0' implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + // Mail + implementation 'org.springframework.boot:spring-boot-starter-mail' } tasks.named('test') { diff --git a/src/main/java/com/hackathon/momento/global/config/EmailConfig.java b/src/main/java/com/hackathon/momento/global/config/EmailConfig.java new file mode 100644 index 0000000..0023063 --- /dev/null +++ b/src/main/java/com/hackathon/momento/global/config/EmailConfig.java @@ -0,0 +1,50 @@ +package com.hackathon.momento.global.config; + +import java.util.Properties; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.JavaMailSenderImpl; + +@Configuration +public class EmailConfig { + + @Value("${spring.mail.host}") + private String host; + + @Value("${spring.mail.port}") + private int port; + + @Value("${spring.mail.username}") + private String username; + + @Value("${spring.mail.password}") + private String password; + + @Bean + public JavaMailSender javaMailSender() { + JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); + mailSender.setPort(port); + mailSender.setHost(host); + mailSender.setUsername(username); + mailSender.setPassword(password); + mailSender.setDefaultEncoding("UTF-8"); + mailSender.setJavaMailProperties(getMailProperties()); + + return mailSender; + } + + private Properties getMailProperties() { + Properties properties = new Properties(); + properties.put("mail.smtp.auth", true); + properties.put("mail.smtp.starttls.enable", true); + properties.put("mail.smtp.starttls.required", true); + properties.put("mail.smtp.connectiontimeout", 5000); + properties.put("mail.smtp.timeout", 5000); + properties.put("mail.smtp.writetimeout", 5000); + + return properties; + } +} + diff --git a/src/main/java/com/hackathon/momento/notification/domain/Notification.java b/src/main/java/com/hackathon/momento/notification/domain/Notification.java deleted file mode 100644 index 738162d..0000000 --- a/src/main/java/com/hackathon/momento/notification/domain/Notification.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.hackathon.momento.notification.domain; - -import com.hackathon.momento.global.entity.BaseEntity; -import com.hackathon.momento.member.domain.Member; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Notification extends BaseEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "notification_id") - private Long id; - - @Column(nullable = false) - private String title; - - @Column(columnDefinition = "TEXT") - private String message; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - - @Builder - private Notification(String title, String message, Member member) { - this.title = title; - this.message = message; - this.member = member; - } -} diff --git a/src/main/java/com/hackathon/momento/team/application/EmailService.java b/src/main/java/com/hackathon/momento/team/application/EmailService.java new file mode 100644 index 0000000..0866dcf --- /dev/null +++ b/src/main/java/com/hackathon/momento/team/application/EmailService.java @@ -0,0 +1,43 @@ +package com.hackathon.momento.team.application; + +import jakarta.mail.MessagingException; +import jakarta.mail.internet.MimeMessage; +import java.io.UnsupportedEncodingException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class EmailService { + + private static final String FROM_EMAIL = "kduoh99@gmail.com"; + private static final String TEAM_NAME = "TeamUp"; + + private final JavaMailSender mailSender; + + public void sendMessage(String to, String body) { + try { + MimeMessage message = mailSender.createMimeMessage(); + + String subject = "[TeamUp] 요청하신 팀 빌딩이 완료되었습니다, 팀 정보를 확인해주세요."; + MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message, true); + + mimeMessageHelper.setTo(to); + mimeMessageHelper.setFrom(FROM_EMAIL, TEAM_NAME); + mimeMessageHelper.setSubject(subject); + mimeMessageHelper.setText(body, true); + + mailSender.send(message); + log.info("Email sent to: {}", to); + + } catch (MessagingException | UnsupportedEncodingException e) { + log.error("Email send failed to {}", to, e); + } + } +} diff --git a/src/main/java/com/hackathon/momento/team/application/TeamService.java b/src/main/java/com/hackathon/momento/team/application/TeamService.java index 9f261fe..4c00253 100644 --- a/src/main/java/com/hackathon/momento/team/application/TeamService.java +++ b/src/main/java/com/hackathon/momento/team/application/TeamService.java @@ -35,6 +35,7 @@ public class TeamService { private final TeamInfoRepository teamInfoRepository; private final MemberRepository memberRepository; private final RestTemplate restTemplate; + private final EmailService emailService; @Value("${openai.api.url}") private String apiURL; @@ -77,6 +78,43 @@ public void executeTeamBuilding() { List teamInfos = parseResToTeamInfo(resContent, requests); teamInfoRepository.saveAll(teamInfos); + + sendTeamCompletionEmails(teamInfos); + } + } + + private void sendTeamCompletionEmails(List teamInfos) { + for (TeamInfo teamInfo : teamInfos) { + String teamName = teamInfo.getTeamName(); + String description = teamInfo.getDescription(); + List teamMembers = teamInfo.getTeamBuildings(); + + StringBuilder emailBody = new StringBuilder(); + emailBody.append("
") + .append("

") + .append(teamName).append("

") + .append("

").append(description).append("

") + .append("

Team Members

") + .append("
    "); + + for (TeamBuilding memberBuilding : teamMembers) { + Member member = memberBuilding.getMember(); + emailBody.append( + "
  • ") + .append("Name: ").append(member.getName()).append("
    ") + .append("Email: ").append(member.getEmail()).append("
    ") + .append("Position: ").append(memberBuilding.getMyPosition()) + .append("
  • "); + } + emailBody.append("
") + .append("

") + .append("Thank you for using TeamUp") + .append("

") + .append("
"); + + for (TeamBuilding memberBuilding : teamMembers) { + emailService.sendMessage(memberBuilding.getMember().getEmail(), emailBody.toString()); + } } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8da8d6c..5525fb5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,6 +22,12 @@ spring: port: ${REDIS_PORT} host: ${REDIS_SERVER} + mail: + port: ${MAIL_PORT} + host: ${MAIL_SERVER} + username: ${MAIL_USERNAME} + password: ${MAIL_PASSWORD} + logging: level: org.hibernate.sql: debug