Skip to content
Open
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
@@ -1,13 +1,13 @@
package com.dangle.adapter.http.config

import com.dangle.adapter.http.kakao.KakaoNotificationClient
import com.dangle.adapter.http.ncp.NcpKakaoNotificationClient
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.openfeign.EnableFeignClients
import org.springframework.cloud.openfeign.FeignClientProperties

@EnableFeignClients(
clients = [
KakaoNotificationClient::class,
NcpKakaoNotificationClient::class,
]
)
@EnableConfigurationProperties(FeignClientProperties::class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.dangle.adapter.http.config

import com.dangle.adapter.http.kakao.KakaoNotificationAdapter
import com.dangle.adapter.http.kakao.KakaoNotificationClient
import com.dangle.adapter.http.ncp.NcpKakaoNotificationAdapter
import com.dangle.adapter.http.ncp.NcpKakaoNotificationClient
import com.dangle.usecase.notification.port.out.KakaoNotificationPort
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
Expand All @@ -14,8 +14,8 @@ import org.springframework.context.annotation.Import
class HttpAdapterConfig {
@Bean
fun kakaoNotificationPort(
kakaoNotificationClient: KakaoNotificationClient,
ncpKakaoNotificationClient: NcpKakaoNotificationClient,
): KakaoNotificationPort {
return KakaoNotificationAdapter(kakaoNotificationClient)
return NcpKakaoNotificationAdapter(ncpKakaoNotificationClient)
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.dangle.adapter.http.ncp

import com.dangle.adapter.http.ncp.dto.NcpKakaoNotificationRequest
import com.dangle.usecase.notification.port.out.KakaoNotificationPort

class NcpKakaoNotificationAdapter(
private val ncpKakaoNotificationClient: NcpKakaoNotificationClient,
) : KakaoNotificationPort {
override fun send(
targetPhoneNumber: String,
templateName: String,
variables: Map<String, String>,
) {
val request = NcpKakaoNotificationRequest(
plusFriendId = "TBD",
templateCode = "TBD",
messages = listOf(),
reserveTime = "TBD",
reserveTimeZone = "TBD"

)
val response = ncpKakaoNotificationClient.send(
timestamp = "TBD",
subAccountAccessKey = "TBD",
apiGatewaySignature = "TBD",
serviceId = "TBD",
request = request,
)
if (!response.isSuccess()) {
// TODO(kang). 에러로그 남기기
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.dangle.adapter.http.ncp

import com.dangle.adapter.http.ncp.dto.NcpKakaoNotificationRequest
import com.dangle.adapter.http.ncp.dto.NcpKakaoNotificationResponse
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestHeader

@FeignClient(name = "ncpKakaoNotificationFeignClient", url = "https://sens.apigw.ntruss.com/alimtalk/v2")
interface NcpKakaoNotificationClient {
@PostMapping(value = ["services/{serviceId}/messages"])
fun send(
@RequestHeader("x-ncp-apigw-timestamp") timestamp: String, // Millisecond
@RequestHeader("x-ncp-apigw-x-ncp-iam-access-key") subAccountAccessKey: String,
@RequestHeader("x-ncp-apigw-signature-v2") apiGatewaySignature: String, // HmacSHA256
Comment on lines +16 to +17
Copy link
Collaborator

Choose a reason for hiding this comment

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

accessKey는 ncp 제공일 듯 한 것 같은데, signature는 어떤 용도로 사용되나요? 내부 메세지 암호화인가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

그런 것 같네요,,
암호화가 언제 적용되는지는 아직 파악해보지 못하였어요.

image

Copy link
Member Author

Choose a reason for hiding this comment

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

아 아니었었군요,,
API 인증키를 생성하면 Key Id와 시크릿이 생성되는데요,
발급받은 시크릿을 사용하여 Signature를 생성해서 요 값을 키로 사용하는 것 같네요.

스크린샷 2023-10-22 오후 3 07 17

Copy link
Member Author

Choose a reason for hiding this comment

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

Signature 생성 방법
image

@PathVariable("serviceId") serviceId: String,
@RequestBody request: NcpKakaoNotificationRequest
): NcpKakaoNotificationResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.dangle.adapter.http.ncp.dto

data class NcpKakaoNotificationRequest(
val plusFriendId: String,
val templateCode: String,
val messages: List<Message>,
val reserveTime: String, // yyyy-MM-dd HH:mm
val reserveTimeZone: String,
) {
data class Message(
val countryCode: String,
val to: String,
val title: String,
val content: String,
val headerContent: String,
val itemHighlight: ItemHighlight,
val item: List<Item>,
val buttons: List<Button>,
val useSmsFailover: Boolean,
val failoverConfig: FailoverConfig,
)

data class ItemHighlight(
val title: String,
val description: String,
)

data class Item(
val list: List<ItemContents>,
val summary: ItemContents,
)

data class ItemContents(
val title: String,
val description: String,
)

data class Button(
val type: String,
val name: String,
val linkMobile: String,
val linkPc: String,
val schemeIos: String,
val schemeAndroid: String,
)

data class FailoverConfig(
val type: String,
val from: String,
val subject: String,
val content: String,
)
}

data class NcpKakaoNotificationResponse(
val requestId: String,
val requestTime: String,
val statusCode: String,
val statusName: String,
val messages: List<Message>,
) {
fun isSuccess(): Boolean = true

data class Message(
val messageId: String,
val countryCode: String,
val to: String,
val content: String,
val requestStatusCode: String,
val requestStatusName: String,
val requestStatusDesc: String,
val useSmsFailover: Boolean,
)
}