푸시 알림 전송 언어 처리
This commit is contained in:
@@ -33,17 +33,6 @@ class FcmController(private val applicationEventPublisher: ApplicationEventPubli
|
||||
type = FcmEventType.ALL,
|
||||
title = request.title,
|
||||
message = request.message,
|
||||
container = "ios",
|
||||
isAuth = request.isAuth
|
||||
)
|
||||
)
|
||||
|
||||
applicationEventPublisher.publishEvent(
|
||||
FcmEvent(
|
||||
type = FcmEventType.ALL,
|
||||
title = request.title,
|
||||
message = request.message,
|
||||
container = "aos",
|
||||
isAuth = request.isAuth
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package kr.co.vividnext.sodalive.fcm
|
||||
|
||||
import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
|
||||
import kr.co.vividnext.sodalive.i18n.Lang
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import org.springframework.scheduling.annotation.Async
|
||||
import org.springframework.stereotype.Component
|
||||
@@ -15,11 +17,14 @@ enum class FcmEventType {
|
||||
|
||||
class FcmEvent(
|
||||
val type: FcmEventType,
|
||||
val title: String,
|
||||
val message: String,
|
||||
val title: String = "",
|
||||
val message: String = "",
|
||||
val titleKey: String? = null,
|
||||
val messageKey: String? = null,
|
||||
val args: List<Any> = listOf(),
|
||||
val container: String = "",
|
||||
val recipients: List<Long> = listOf(),
|
||||
val recipientsMap: Map<String, List<List<String>>>? = null,
|
||||
val pushTokens: List<PushTokenInfo>? = null,
|
||||
val isAuth: Boolean? = null,
|
||||
val roomId: Long? = null,
|
||||
val contentId: Long? = null,
|
||||
@@ -35,7 +40,8 @@ class FcmEvent(
|
||||
class FcmSendListener(
|
||||
private val pushService: FcmService,
|
||||
private val memberRepository: MemberRepository,
|
||||
private val contentCommentRepository: AudioContentCommentRepository
|
||||
private val contentCommentRepository: AudioContentCommentRepository,
|
||||
private val messageSource: SodaMessageSource
|
||||
) {
|
||||
@Async
|
||||
@TransactionalEventListener
|
||||
@@ -43,21 +49,10 @@ class FcmSendListener(
|
||||
fun send(fcmEvent: FcmEvent) {
|
||||
when (fcmEvent.type) {
|
||||
FcmEventType.ALL -> {
|
||||
if (fcmEvent.container.isNotBlank()) {
|
||||
val pushTokens = memberRepository.getAllRecipientPushTokens(
|
||||
fcmEvent.isAuth,
|
||||
fcmEvent.container
|
||||
)
|
||||
|
||||
for (tokens in pushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = fcmEvent.container
|
||||
)
|
||||
}
|
||||
}
|
||||
val pushTokens = memberRepository.getAllRecipientPushTokens(
|
||||
fcmEvent.isAuth
|
||||
)
|
||||
sendPush(pushTokens, fcmEvent)
|
||||
}
|
||||
|
||||
FcmEventType.INDIVIDUAL -> {
|
||||
@@ -66,254 +61,117 @@ class FcmSendListener(
|
||||
recipients = fcmEvent.recipients,
|
||||
isAuth = fcmEvent.isAuth
|
||||
)
|
||||
|
||||
val iosPushTokens = pushTokens["ios"]
|
||||
val aosPushToken = pushTokens["aos"]
|
||||
|
||||
if (iosPushTokens != null) {
|
||||
for (tokens in iosPushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "ios",
|
||||
contentId = fcmEvent.contentId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (aosPushToken != null) {
|
||||
for (tokens in aosPushToken) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "aos",
|
||||
contentId = fcmEvent.contentId
|
||||
)
|
||||
}
|
||||
}
|
||||
sendPush(pushTokens, fcmEvent)
|
||||
}
|
||||
}
|
||||
|
||||
FcmEventType.CREATE_LIVE -> {
|
||||
if (fcmEvent.container.isNotBlank()) {
|
||||
val pushTokens = memberRepository.getCreateLiveRoomNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false,
|
||||
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false,
|
||||
container = fcmEvent.container
|
||||
)
|
||||
|
||||
for (tokens in pushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = fcmEvent.container,
|
||||
roomId = fcmEvent.roomId
|
||||
)
|
||||
}
|
||||
}
|
||||
val pushTokens = memberRepository.getCreateLiveRoomNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false,
|
||||
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false
|
||||
)
|
||||
sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId)
|
||||
}
|
||||
|
||||
FcmEventType.START_LIVE -> {
|
||||
if (fcmEvent.container.isNotBlank()) {
|
||||
val pushTokens = memberRepository.getStartLiveRoomNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
roomId = fcmEvent.roomId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false,
|
||||
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false,
|
||||
container = fcmEvent.container
|
||||
)
|
||||
|
||||
for (tokens in pushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = fcmEvent.container,
|
||||
roomId = fcmEvent.roomId
|
||||
)
|
||||
}
|
||||
}
|
||||
val pushTokens = memberRepository.getStartLiveRoomNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
roomId = fcmEvent.roomId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false,
|
||||
isAvailableJoinCreator = fcmEvent.isAvailableJoinCreator ?: false
|
||||
)
|
||||
sendPush(pushTokens, fcmEvent, roomId = fcmEvent.roomId)
|
||||
}
|
||||
|
||||
FcmEventType.CANCEL_LIVE -> {
|
||||
if (fcmEvent.recipientsMap != null) {
|
||||
val iosPushTokens = fcmEvent.recipientsMap["ios"]
|
||||
val aosPushToken = fcmEvent.recipientsMap["aos"]
|
||||
if (iosPushTokens != null) {
|
||||
for (tokens in iosPushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "ios"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (aosPushToken != null) {
|
||||
for (tokens in aosPushToken) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "aos"
|
||||
)
|
||||
}
|
||||
}
|
||||
if (fcmEvent.pushTokens != null) {
|
||||
sendPush(fcmEvent.pushTokens, fcmEvent)
|
||||
}
|
||||
}
|
||||
|
||||
FcmEventType.UPLOAD_CONTENT -> {
|
||||
if (fcmEvent.container.isNotBlank()) {
|
||||
val pushTokens = memberRepository.getUploadContentNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false,
|
||||
container = fcmEvent.container
|
||||
)
|
||||
|
||||
for (tokens in pushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = fcmEvent.container,
|
||||
contentId = fcmEvent.contentId
|
||||
)
|
||||
}
|
||||
}
|
||||
val pushTokens = memberRepository.getUploadContentNotificationRecipientPushTokens(
|
||||
creatorId = fcmEvent.creatorId!!,
|
||||
isAuth = fcmEvent.isAuth ?: false
|
||||
)
|
||||
sendPush(pushTokens, fcmEvent, contentId = fcmEvent.contentId)
|
||||
}
|
||||
|
||||
FcmEventType.SEND_MESSAGE -> {
|
||||
val response = memberRepository.getMessageRecipientPushToken(messageId = fcmEvent.messageId!!)
|
||||
|
||||
if (response != null) {
|
||||
pushService.send(
|
||||
tokens = listOf(response.pushToken),
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = response.container,
|
||||
messageId = fcmEvent.messageId
|
||||
)
|
||||
val pushToken = memberRepository.getMessageRecipientPushToken(messageId = fcmEvent.messageId!!)
|
||||
if (pushToken != null) {
|
||||
sendPush(listOf(pushToken), fcmEvent, messageId = fcmEvent.messageId)
|
||||
}
|
||||
}
|
||||
|
||||
FcmEventType.CHANGE_NOTICE -> {
|
||||
if (fcmEvent.creatorId != null) {
|
||||
val pushTokenList = memberRepository.getChangeNoticeRecipientPushTokens(fcmEvent.creatorId)
|
||||
|
||||
val iosPushTokens = pushTokenList["ios"]
|
||||
val aosPushToken = pushTokenList["aos"]
|
||||
|
||||
if (iosPushTokens != null) {
|
||||
for (tokens in iosPushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "ios",
|
||||
creatorId = fcmEvent.creatorId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (aosPushToken != null) {
|
||||
for (tokens in aosPushToken) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "aos",
|
||||
creatorId = fcmEvent.creatorId
|
||||
)
|
||||
}
|
||||
}
|
||||
val pushTokens = memberRepository.getChangeNoticeRecipientPushTokens(fcmEvent.creatorId)
|
||||
sendPush(pushTokens, fcmEvent, creatorId = fcmEvent.creatorId)
|
||||
}
|
||||
}
|
||||
|
||||
FcmEventType.CREATE_CONTENT_COMMENT -> {
|
||||
if (fcmEvent.myMemberId != null && fcmEvent.contentId != null) {
|
||||
val response = contentCommentRepository.findPushTokenByContentIdAndCommentParentIdMyMemberId(
|
||||
val pushTokens = contentCommentRepository.findPushTokenByContentIdAndCommentParentIdMyMemberId(
|
||||
contentId = fcmEvent.contentId,
|
||||
commentParentId = fcmEvent.commentParentId,
|
||||
myMemberId = fcmEvent.myMemberId
|
||||
)
|
||||
|
||||
val iosPushTokens = response
|
||||
.asSequence()
|
||||
.distinct()
|
||||
.filter { it.pushToken.isNotBlank() }
|
||||
.filter { it.container == "ios" }
|
||||
.map { it.pushToken }
|
||||
.toList()
|
||||
|
||||
val aosPushTokens = response
|
||||
.asSequence()
|
||||
.distinct()
|
||||
.filter { it.pushToken.isNotBlank() }
|
||||
.filter { it.container == "aos" }
|
||||
.map { it.pushToken }
|
||||
.toList()
|
||||
|
||||
if (iosPushTokens.isNotEmpty()) {
|
||||
pushService.send(
|
||||
tokens = iosPushTokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "ios",
|
||||
contentId = fcmEvent.contentId
|
||||
)
|
||||
}
|
||||
|
||||
if (aosPushTokens.isNotEmpty()) {
|
||||
pushService.send(
|
||||
tokens = aosPushTokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "aos",
|
||||
contentId = fcmEvent.contentId
|
||||
)
|
||||
}
|
||||
sendPush(pushTokens, fcmEvent, contentId = fcmEvent.contentId)
|
||||
}
|
||||
}
|
||||
|
||||
FcmEventType.IN_PROGRESS_AUDITION -> {
|
||||
if (fcmEvent.auditionId != null && fcmEvent.auditionId > 0) {
|
||||
val pushTokenList = memberRepository.getAuditionNoticeRecipientPushTokens(
|
||||
val pushTokens = memberRepository.getAuditionNoticeRecipientPushTokens(
|
||||
isAuth = fcmEvent.isAuth ?: false
|
||||
)
|
||||
|
||||
val iosPushTokens = pushTokenList["ios"]
|
||||
val aosPushToken = pushTokenList["aos"]
|
||||
|
||||
if (iosPushTokens != null) {
|
||||
for (tokens in iosPushTokens) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "ios",
|
||||
auditionId = fcmEvent.auditionId
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (aosPushToken != null) {
|
||||
for (tokens in aosPushToken) {
|
||||
pushService.send(
|
||||
tokens = tokens,
|
||||
title = fcmEvent.title,
|
||||
message = fcmEvent.message,
|
||||
container = "aos",
|
||||
auditionId = fcmEvent.auditionId
|
||||
)
|
||||
}
|
||||
}
|
||||
sendPush(pushTokens, fcmEvent, auditionId = fcmEvent.auditionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendPush(
|
||||
pushTokens: List<PushTokenInfo>,
|
||||
fcmEvent: FcmEvent,
|
||||
roomId: Long? = null,
|
||||
contentId: Long? = null,
|
||||
messageId: Long? = null,
|
||||
creatorId: Long? = null,
|
||||
auditionId: Long? = null
|
||||
) {
|
||||
val tokensByLang = pushTokens.groupBy { it.languageCode }
|
||||
|
||||
for ((langCode, tokens) in tokensByLang) {
|
||||
val lang = Lang.fromAcceptLanguage(langCode)
|
||||
val title = translate(fcmEvent.titleKey, fcmEvent.title, lang, fcmEvent.args)
|
||||
val message = translate(fcmEvent.messageKey, fcmEvent.message, lang, fcmEvent.args)
|
||||
|
||||
val tokensByOS = tokens.groupBy { it.deviceType }
|
||||
for ((os, osTokens) in tokensByOS) {
|
||||
osTokens.map { it.token }.distinct().chunked(500).forEach { batch ->
|
||||
pushService.send(
|
||||
tokens = batch,
|
||||
title = title,
|
||||
message = message,
|
||||
container = os,
|
||||
roomId = roomId ?: fcmEvent.roomId,
|
||||
contentId = contentId ?: fcmEvent.contentId,
|
||||
messageId = messageId ?: fcmEvent.messageId,
|
||||
creatorId = creatorId ?: fcmEvent.creatorId,
|
||||
auditionId = auditionId ?: fcmEvent.auditionId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translate(key: String?, default: String, lang: Lang, args: List<Any>): String {
|
||||
if (key == null) return default
|
||||
val template = messageSource.getMessage(key, lang) ?: return default
|
||||
return String.format(template, *args.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package kr.co.vividnext.sodalive.fcm
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
|
||||
data class GetMessageRecipientPushTokenResponse @QueryProjection constructor(
|
||||
val pushToken: String,
|
||||
val container: String
|
||||
)
|
||||
@@ -10,7 +10,8 @@ import javax.persistence.ManyToOne
|
||||
@Entity
|
||||
data class PushToken(
|
||||
var token: String,
|
||||
var deviceType: String
|
||||
var deviceType: String,
|
||||
var languageCode: String? = null
|
||||
) : BaseEntity() {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "member_id", nullable = true)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package kr.co.vividnext.sodalive.fcm
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
|
||||
data class PushTokenInfo @QueryProjection constructor(
|
||||
val token: String,
|
||||
val deviceType: String,
|
||||
val languageCode: String
|
||||
)
|
||||
@@ -1,5 +1,6 @@
|
||||
package kr.co.vividnext.sodalive.fcm
|
||||
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Service
|
||||
@@ -8,7 +9,8 @@ import org.springframework.transaction.annotation.Transactional
|
||||
@Service
|
||||
class PushTokenService(
|
||||
private val repository: PushTokenRepository,
|
||||
private val memberRepository: MemberRepository
|
||||
private val memberRepository: MemberRepository,
|
||||
private val langContext: LangContext
|
||||
) {
|
||||
@Transactional
|
||||
fun registerToken(memberId: Long, token: String, deviceType: String) {
|
||||
@@ -20,8 +22,9 @@ class PushTokenService(
|
||||
existing.member = member
|
||||
existing.token = token
|
||||
existing.deviceType = deviceType
|
||||
existing.languageCode = langContext.lang.code
|
||||
} else {
|
||||
val newToken = PushToken(token, deviceType)
|
||||
val newToken = PushToken(token, deviceType, langContext.lang.code)
|
||||
newToken.member = member
|
||||
repository.save(newToken)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user