Skip to content

Commit

Permalink
Merge pull request #99 from soma-baekgu/feature/BG-380-email-ses
Browse files Browse the repository at this point in the history
[BG-380]: 이메일 전송 클라이언트 SES로 교체 (2h / 2h)
  • Loading branch information
GGHDMS authored Aug 26, 2024
2 parents 5fe597c + c65c0d7 commit 42a0f43
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 65 deletions.

This file was deleted.

3 changes: 0 additions & 3 deletions infra/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,11 @@ dependencies {
implementation(project(":domain"))
implementation(project(":common"))
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.2")
implementation("org.springframework.boot:spring-boot-starter-mail")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.mysql:mysql-connector-j:8.4.0")
implementation("org.springframework.kafka:spring-kafka:3.1.4")
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("org.springframework.boot:spring-boot-starter-web")
// implementation("com.fasterxml.jackson.core:jackson-databind:2.13.3")
implementation("org.reflections:reflections:0.10.2")

implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta")
Expand Down

This file was deleted.

This file was deleted.

4 changes: 4 additions & 0 deletions notification/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("com.google.firebase:firebase-admin:6.8.1")
implementation("org.springframework.boot:spring-boot-starter-mail")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("software.amazon.awssdk:ses:2.27.8")
implementation("org.apache.httpcomponents:httpclient:4.5.13")

testImplementation(kotlin("test"))
testImplementation("com.redis.testcontainers:testcontainers-redis-junit:1.6.4")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.backgu.amaker.notification
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.runApplication
import org.springframework.context.annotation.ComponentScan
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories
import org.springframework.scheduling.annotation.EnableAsync
Expand All @@ -13,7 +12,6 @@ import org.springframework.scheduling.annotation.EnableAsync
@EntityScan(basePackages = ["com.backgu.amaker.infra"])
@EnableJpaRepositories(basePackages = ["com.backgu.amaker.infra.jpa.user", "com.backgu.amaker.infra.jpa.workspace"])
@EnableRedisRepositories(basePackages = ["com.backgu.amaker.infra.redis"])
@ComponentScan("com.backgu.amaker.notification", "com.backgu.amaker.infra.mail")
class NotificationApplication

fun main(args: Array<String>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.backgu.amaker.notification.email.config

import com.backgu.amaker.notification.email.service.EmailSender
import com.backgu.amaker.notification.email.ses.config.AWSSESConfig
import com.backgu.amaker.notification.email.ses.service.SESEmailService
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import software.amazon.awssdk.services.ses.SesClient

@Configuration
class EMailSenderConfig {
@Bean
fun mailSender(
sesClient: SesClient,
sesConfig: AWSSESConfig,
): EmailSender = SESEmailService(sesClient, sesConfig)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.backgu.amaker.infra.mail.config
package com.backgu.amaker.notification.email.gmail.config

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.backgu.amaker.infra.mail.config
package com.backgu.amaker.notification.email.gmail.config

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package com.backgu.amaker.infra.mail.infra
package com.backgu.amaker.notification.email.gmail.infra

import com.backgu.amaker.application.notification.mail.service.EmailSender
import com.backgu.amaker.notification.email.service.EmailSender
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.mail.internet.MimeMessage
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.stereotype.Component

private val logger = KotlinLogging.logger {}

@Component
class HtmlEmailSender(
val mailSender: JavaMailSender,
) : EmailSender {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.backgu.amaker.infra.mail.infra
package com.backgu.amaker.notification.email.gmail.infra

import com.backgu.amaker.application.notification.mail.service.EmailTemplateBuilder
import com.backgu.amaker.notification.email.service.EmailTemplateBuilder
import io.github.oshai.kotlinlogging.KotlinLogging
import org.springframework.stereotype.Component
import org.thymeleaf.TemplateEngine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.backgu.amaker.application.notification.mail.service
package com.backgu.amaker.notification.email.service

interface EmailSender {
fun sendEmail(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.backgu.amaker.application.notification.mail.service
package com.backgu.amaker.notification.email.service

interface EmailTemplateBuilder {
fun buildEmailContent(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.backgu.amaker.notification.email.templated
package com.backgu.amaker.notification.email.service

import com.backgu.amaker.application.notification.mail.service.EmailSender
import com.backgu.amaker.application.notification.mail.service.EmailTemplateBuilder
import com.backgu.amaker.domain.notifiacation.method.TemplateEmailNotificationMethod
import com.backgu.amaker.domain.user.User
import org.springframework.stereotype.Service
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.backgu.amaker.notification.email.ses.config

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.ses.SesClient

@Configuration
@ConfigurationProperties(prefix = "amazon.ses")
class AWSSESConfig {
lateinit var accessKey: String
lateinit var secretKey: String
lateinit var region: String
lateinit var sender: String

@Bean
fun sesClient(): SesClient =
SesClient
.builder()
.region(Region.of(region))
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey)))
.build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.backgu.amaker.notification.email.ses.service

import com.backgu.amaker.notification.email.service.EmailSender
import com.backgu.amaker.notification.email.ses.config.AWSSESConfig
import io.github.oshai.kotlinlogging.KotlinLogging
import software.amazon.awssdk.services.ses.SesClient
import software.amazon.awssdk.services.ses.model.Body
import software.amazon.awssdk.services.ses.model.Content
import software.amazon.awssdk.services.ses.model.Destination
import software.amazon.awssdk.services.ses.model.Message
import software.amazon.awssdk.services.ses.model.SendEmailRequest
import software.amazon.awssdk.services.ses.model.SesException

private val logger = KotlinLogging.logger {}

class SESEmailService(
private val sesClient: SesClient,
private val sesConfig: AWSSESConfig,
) : EmailSender {
override fun sendEmail(
emailAddress: String,
title: String,
body: String,
) {
val destination: Destination =
Destination
.builder()
.toAddresses(emailAddress)
.build()

val subjectContent: Content =
Content
.builder()
.data(title)
.charset("UTF-8")
.build()

val bodyContent: Content =
Content
.builder()
.data(body)
.charset("UTF-8")
.build()

val body: Body =
Body
.builder()
.html(bodyContent)
.build()

val message: Message =
Message
.builder()
.subject(subjectContent)
.body(body)
.build()

val request: SendEmailRequest =
SendEmailRequest
.builder()
.destination(destination)
.message(message)
.source(sesConfig.sender)
.build()

try {
sesClient.sendEmail(request)
} catch (e: SesException) {
logger.error(e) { "Failed to send email to $emailAddress with title $title and body $body" }
throw e
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.backgu.amaker.domain.notifiacation.Notification
import com.backgu.amaker.domain.notifiacation.UserFulfilledNotification
import com.backgu.amaker.domain.notifiacation.method.NotificationMethod
import com.backgu.amaker.domain.notifiacation.method.TemplateEmailNotificationMethod
import com.backgu.amaker.notification.email.templated.TemplateEmailHandler
import com.backgu.amaker.notification.email.service.TemplateEmailHandler
import org.springframework.stereotype.Component

@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.backgu.amaker.domain.notifiacation.Notification
import com.backgu.amaker.domain.notifiacation.UserNotification
import com.backgu.amaker.domain.notifiacation.method.NotificationMethod
import com.backgu.amaker.domain.notifiacation.method.TemplateEmailNotificationMethod
import com.backgu.amaker.notification.email.templated.TemplateEmailHandler
import com.backgu.amaker.notification.email.service.TemplateEmailHandler
import org.springframework.stereotype.Component

@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.backgu.amaker.domain.notifiacation.Notification
import com.backgu.amaker.domain.notifiacation.WorkspaceNotification
import com.backgu.amaker.domain.notifiacation.method.NotificationMethod
import com.backgu.amaker.domain.notifiacation.method.TemplateEmailNotificationMethod
import com.backgu.amaker.notification.email.templated.TemplateEmailHandler
import com.backgu.amaker.notification.email.service.TemplateEmailHandler
import org.springframework.stereotype.Component

@Component
Expand Down
7 changes: 7 additions & 0 deletions notification/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ management:
exposure:
include: health,info,metrics,prometheus

amazon:
ses:
sender: ${EMAIL_SENDER}
access-key: ${AWS_SES_ACCESS}
secret-key: ${AWS_SES_SECRET}
region: ${AWS_REGION}

fcm:
file: hi.json
base-url: https://fcm.googleapis.com/v1/projects/a-maker-2b48b
Expand Down

0 comments on commit 42a0f43

Please sign in to comment.