Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: include receiver name into mail registration #31

Merged
merged 6 commits into from
Aug 21, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import gdsc.konkuk.platformcore.application.email.exceptions.EmailAlreadyProcessedException;
import gdsc.konkuk.platformcore.application.email.exceptions.EmailErrorCode;
import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest;
import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver;
import gdsc.konkuk.platformcore.domain.email.entity.EmailTask;
import gdsc.konkuk.platformcore.domain.email.repository.EmailTaskRepository;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
Expand Down Expand Up @@ -48,7 +50,8 @@ public EmailTask update(Long emailId, EmailSendRequest request) {
task.changeEmailDetails(request.toEmailDetails());
task.changeSendAt(request.getSendAt());

Set<String> updatedReceivers = mergeReceivers(task, request.getReceivers());
Set<EmailReceiver> newReceivers = request.toEmailReceivers();
Set<EmailReceiver> updatedReceivers = mergeReceivers(task, newReceivers);
task.changeEmailReceivers(updatedReceivers);
return task;
}
Expand All @@ -71,10 +74,10 @@ private void validateEmailTaskAlreadySent(EmailTask emailTask) {
}
}

private Set<String> mergeReceivers(EmailTask emailTask, Set<String> updatedReceivers) {
List<String> receiversInPrevSet = emailTask.filterReceiversInPrevSet(updatedReceivers);
List<String> receiversInNewSet = emailTask.filterReceiversNotInPrevSet(updatedReceivers);
Set<String> mergedReceiver = new HashSet<>(receiversInPrevSet);
private Set<EmailReceiver> mergeReceivers(EmailTask emailTask, Set<EmailReceiver> updatedReceivers) {
List<EmailReceiver> receiversInPrevSet = emailTask.filterReceiversInPrevSet(updatedReceivers);
List<EmailReceiver> receiversInNewSet = emailTask.filterReceiversNotInPrevSet(updatedReceivers);
Set<EmailReceiver> mergedReceiver = new HashSet<>(receiversInPrevSet);
mergedReceiver.addAll(receiversInNewSet);
return mergedReceiver;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package gdsc.konkuk.platformcore.controller.email.dtos;

import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setter를 열어둘 필요가 있을까요? VO라는점을 생각해보는게 어때요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EmailReceiverInfo는 DTO입니다. VO인 EmailReceiver는 확인해보니 Setter를 열어두지 않았더군욥

public class EmailReceiverInfo {
@NotEmpty @Email
private String email;

@NotEmpty private String name;

@Builder
public EmailReceiverInfo(String email, String name) {
this.email = email;
this.name = name;
}

public static EmailReceiver toValueObject(EmailReceiverInfo info) {
return EmailReceiver.builder()
.email(info.getEmail())
.name(info.getName())
.build();
}

public static EmailReceiverInfo fromValueObject(EmailReceiver emailReceiver) {
return EmailReceiverInfo.builder()
.email(emailReceiver.getEmail())
.name(emailReceiver.getName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package gdsc.konkuk.platformcore.controller.email.dtos;

import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails;
import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver;
import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers;
import gdsc.konkuk.platformcore.domain.email.entity.EmailTask;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
Expand All @@ -20,21 +21,21 @@ public class EmailSendRequest {
@NotEmpty
private String content;
@NotNull
private Set<@Email String> receivers;
private Set<EmailReceiverInfo> receiverInfos;
@NotNull
private LocalDateTime sendAt;

@Builder
public EmailSendRequest(String subject, String content, Set<String> receivers, LocalDateTime sendAt) {
public EmailSendRequest(String subject, String content, Set<EmailReceiverInfo> receiverInfos, LocalDateTime sendAt) {
this.subject = subject;
this.content = content;
this.receivers = receivers;
this.receiverInfos = receiverInfos;
this.sendAt = sendAt;
}

public static EmailTask toEntity(EmailSendRequest request) {
EmailDetails details = new EmailDetails(request.getSubject(), request.getContent());
EmailReceivers receivers = new EmailReceivers(request.getReceivers());
EmailReceivers receivers = new EmailReceivers(request.toEmailReceivers());
return EmailTask.builder()
.emailDetails(details)
.receivers(receivers)
Expand All @@ -46,7 +47,10 @@ public EmailDetails toEmailDetails() {
return new EmailDetails(subject, content);
}

public EmailReceivers toEmailReceivers() {
return new EmailReceivers(receivers);
public Set<EmailReceiver> toEmailReceivers() {
return receiverInfos
.stream()
.map(EmailReceiverInfo::toValueObject)
.collect(Collectors.toSet());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@
public class EmailTaskDetailsResponse {
private final String subject;
private final String content;
private final List<String> receivers;
private final List<EmailReceiverInfo> receiverInfos;
private final LocalDateTime sendAt;

@Builder
public EmailTaskDetailsResponse(EmailDetails emailDetails, EmailReceivers emailReceivers, LocalDateTime sendAt) {
this.subject = emailDetails.getSubject();
this.content = emailDetails.getContent();
this.receivers = emailReceivers
this.receiverInfos = emailReceivers
.getReceivers()
.stream()
.map(EmailReceiverInfo::fromValueObject)
.toList();
this.sendAt = sendAt;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gdsc.konkuk.platformcore.controller.email.dtos;

import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails;
import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver;
import gdsc.konkuk.platformcore.domain.email.entity.EmailTask;
import java.time.LocalDateTime;
import lombok.Builder;
Expand All @@ -11,25 +12,26 @@ public class SimpleEmailTaskResponse {

private final Long id;
private final String subject;
private final String receiver;
private final EmailReceiverInfo receiverInfos;
private final LocalDateTime sendAt;
private final Boolean isSent;

@Builder
public SimpleEmailTaskResponse(Long id, String subject, String receiver, LocalDateTime sendAt, boolean isSent) {
public SimpleEmailTaskResponse(Long id, String subject, EmailReceiverInfo receiverInfos, LocalDateTime sendAt, boolean isSent) {
this.id = id;
this.subject = subject;
this.receiver = receiver;
this.receiverInfos = receiverInfos;
this.sendAt = sendAt;
this.isSent = isSent;
}

public static SimpleEmailTaskResponse of(EmailTask emailTask, String receiver) {
public static SimpleEmailTaskResponse of(EmailTask emailTask, EmailReceiver receiver) {
EmailDetails emailDetails = emailTask.getEmailDetails();
EmailReceiverInfo receiverInfo = EmailReceiverInfo.fromValueObject(receiver);
return SimpleEmailTaskResponse.builder()
.id(emailTask.getId())
.subject(emailDetails.getSubject())
.receiver(receiver)
.receiverInfos(receiverInfo)
.sendAt(emailTask.getSendAt())
.isSent(emailTask.isSent())
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package gdsc.konkuk.platformcore.domain.email.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Embeddable
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class EmailReceiver {
@Column(name = "receiver_email")
private String email;

@Column(name = "receiver_name")
private String name;

@Builder
public EmailReceiver(String email, String name) {
this.email = email;
this.name = name;
}

@Override
public int hashCode() {
return (this.email + this.name).hashCode();
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmailReceiver that = (EmailReceiver) o;
return email.equals(that.email) && name.equals(that.name);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gdsc.konkuk.platformcore.domain.email.entity;

import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.JoinColumn;
import java.util.HashSet;
Expand All @@ -20,10 +19,9 @@ public class EmailReceivers {

@ElementCollection
@CollectionTable(name = "email_receivers", joinColumns = @JoinColumn(name = "task_id"))
@Column(name = "receiver_email")
Set<String> receivers = new HashSet<>();
Set<EmailReceiver> receivers = new HashSet<>();

public EmailReceivers(Set<String> receivers) {
public EmailReceivers(Set<EmailReceiver> receivers) {
this.receivers.addAll(receivers);
}

Expand All @@ -44,7 +42,7 @@ public void removeAll() {
this.receivers.clear();
}

public void insertAll(Set<String> set) {
public void insertAll(Set<EmailReceiver> set) {
this.receivers.addAll(set);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void changeEmailDetails(final EmailDetails newEmailDetails) {
emailDetails = newEmailDetails;
}

public void changeEmailReceivers(final Set<String> set) {
public void changeEmailReceivers(final Set<EmailReceiver> set) {
emailReceivers.removeAll();
emailReceivers.insertAll(set);
}
Expand All @@ -63,17 +63,17 @@ public void markAsSent() {
isSent = true;
}

public List<String> filterReceiversInPrevSet(Set<String> set) {
public List<EmailReceiver> filterReceiversInPrevSet(Set<EmailReceiver> set) {
return this.getEmailReceivers().getReceivers()
.stream()
.filter(set::contains)
.toList();
}

public List<String> filterReceiversNotInPrevSet(Set<String> set) {
public List<EmailReceiver> filterReceiversNotInPrevSet(Set<EmailReceiver> set) {
return set
.stream()
.filter((e) -> !emailReceivers.getReceivers().contains(e))
.filter((e) -> !this.emailReceivers.getReceivers().contains(e))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package gdsc.konkuk.platformcore.external.email;

import static gdsc.konkuk.platformcore.global.consts.PlatformConstants.EMAIL_RECEIVER_NAME_REGEXP;

import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.MailException;
Expand All @@ -26,15 +29,27 @@ public class EmailClient {

public void sendEmailToReceivers(EmailTask email) {
EmailDetails emailDetails = email.getEmailDetails();
Set<String> receivers = email.getEmailReceivers().getReceivers();
Set<EmailReceiver> receivers = email.getEmailReceivers().getReceivers();
receivers.forEach(receiver -> sendEmail(receiver, emailDetails));
}

private void sendEmail(String to, EmailDetails emailDetails) {
public String replaceNameToken(String content, String name) {
return content.replaceAll(EMAIL_RECEIVER_NAME_REGEXP, name);
}

private MimeMessage generateMimeMessage(EmailReceiver to, EmailDetails emailDetails)
throws MessagingException {
String emailContent = replaceNameToken(emailDetails.getContent(), to.getName());
String emailDestination = to.getEmail();
String emailSubject = emailDetails.getSubject();

return convertToHTMLMimeMessage(emailDestination, emailSubject, emailContent);
}

private void sendEmail(EmailReceiver to, EmailDetails emailDetails) {
try {
log.info("Sending email to {}", to);
MimeMessage message =
convertToHTMLMimeMessage(to, emailDetails.getSubject(), emailDetails.getContent());
MimeMessage message = generateMimeMessage(to, emailDetails);
javaMailSender.send(message);
} catch (MailParseException | MessagingException e) {
throw EmailSendingException.of(EmailClientErrorCode.MAIL_PARSING_ERROR, e.getMessage());
Expand All @@ -47,9 +62,11 @@ private MimeMessage convertToHTMLMimeMessage(String to, String subject, String t
throws MessagingException {
MimeMessage message = javaMailSender.createMimeMessage();
message.setSubject(subject);

MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setTo(to);
helper.setText(text, true);

return message;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class PlatformConstants {
public static final String LOGIN_NAME = "id";
public static final String API_PREFIX = "/api/v1";

public static final String EMAIL_RECEIVER_NAME_REGEXP = "\\{이름}";

public static final String DISCORD_ERROR_TITLE = "\uD83E\uDDE8 치명적인 서버 에러 발생!";
public static final String DISCORD_ERROR_DESCRIPTION =
"\uD83C\uDD98 서버에서 치명적인 에러가 발생했습니다. 빠르게 확인해주세요. \uD83C\uDD98";
Expand Down
Loading