From 619ceeea248054c0e21f3107dd3714703ba9554a Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 25 Nov 2025 16:19:08 +0900 Subject: [PATCH] =?UTF-8?q?feat(character-comment):=20=EC=BA=90=EB=A6=AD?= =?UTF-8?q?=ED=84=B0=20=EB=8C=93=EA=B8=80=20=EB=93=B1=EB=A1=9D=20=EC=8B=9C?= =?UTF-8?q?=20=EC=96=B8=EC=96=B4=20=EC=BD=94=EB=93=9C=EA=B0=80=20null?= =?UTF-8?q?=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=20=ED=8C=8C=ED=8C=8C=EA=B3=A0=20?= =?UTF-8?q?=EC=96=B8=EC=96=B4=20=EA=B0=90=EC=A7=80=20API=EB=A5=BC=20?= =?UTF-8?q?=ED=98=B8=EC=B6=9C=ED=95=98=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../comment/CharacterCommentService.kt | 30 ++++++++++++- .../sodalive/content/LanguageDetectEvent.kt | 42 ++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/comment/CharacterCommentService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/comment/CharacterCommentService.kt index 012aa7a..bf5e49a 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/comment/CharacterCommentService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/chat/character/comment/CharacterCommentService.kt @@ -2,7 +2,10 @@ package kr.co.vividnext.sodalive.chat.character.comment import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.content.LanguageDetectEvent +import kr.co.vividnext.sodalive.content.LanguageDetectTargetType import kr.co.vividnext.sodalive.member.Member +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -12,7 +15,8 @@ import java.time.ZoneId class CharacterCommentService( private val chatCharacterRepository: ChatCharacterRepository, private val commentRepository: CharacterCommentRepository, - private val reportRepository: CharacterCommentReportRepository + private val reportRepository: CharacterCommentReportRepository, + private val applicationEventPublisher: ApplicationEventPublisher ) { private fun profileUrl(imageHost: String, profileImage: String?): String { @@ -66,6 +70,18 @@ class CharacterCommentService( entity.chatCharacter = character entity.member = member commentRepository.save(entity) + + // 언어 코드가 지정되지 않은 경우, 파파고 언어 감지 API를 통해 비동기로 언어를 식별한다. + if (languageCode.isNullOrBlank()) { + applicationEventPublisher.publishEvent( + LanguageDetectEvent( + commentId = entity.id!!, + query = text, + targetType = LanguageDetectTargetType.CHARACTER_COMMENT + ) + ) + } + return entity.id!! } @@ -89,6 +105,18 @@ class CharacterCommentService( entity.member = member entity.parent = parent commentRepository.save(entity) + + // 언어 코드가 지정되지 않은 경우, 파파고 언어 감지 API를 통해 비동기로 언어를 식별한다. + if (languageCode.isNullOrBlank()) { + applicationEventPublisher.publishEvent( + LanguageDetectEvent( + commentId = entity.id!!, + query = text, + targetType = LanguageDetectTargetType.CHARACTER_COMMENT + ) + ) + } + return entity.id!! } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/content/LanguageDetectEvent.kt b/src/main/kotlin/kr/co/vividnext/sodalive/content/LanguageDetectEvent.kt index 4321b00..7ba9a75 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/content/LanguageDetectEvent.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/content/LanguageDetectEvent.kt @@ -1,5 +1,6 @@ package kr.co.vividnext.sodalive.content +import kr.co.vividnext.sodalive.chat.character.comment.CharacterCommentRepository import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Value @@ -20,7 +21,8 @@ import org.springframework.web.client.RestTemplate */ enum class LanguageDetectTargetType { CONTENT, - COMMENT + COMMENT, + CHARACTER_COMMENT } class LanguageDetectEvent( @@ -38,6 +40,7 @@ data class PapagoLanguageDetectResponse( class LanguageDetectListener( private val audioContentRepository: AudioContentRepository, private val audioContentCommentRepository: AudioContentCommentRepository, + private val characterCommentRepository: CharacterCommentRepository, @Value("\${cloud.naver.papago-client-id}") private val papagoClientId: String, @@ -64,6 +67,7 @@ class LanguageDetectListener( when (event.targetType) { LanguageDetectTargetType.CONTENT -> handleContentLanguageDetect(event) LanguageDetectTargetType.COMMENT -> handleCommentLanguageDetect(event) + LanguageDetectTargetType.CHARACTER_COMMENT -> handleCharacterCommentLanguageDetect(event) } } @@ -139,6 +143,42 @@ class LanguageDetectListener( ) } + private fun handleCharacterCommentLanguageDetect(event: LanguageDetectEvent) { + val commentId = event.commentId + if (commentId == null) { + log.warn("[PapagoLanguageDetect] commentId is null for CHARACTER_COMMENT target. event={}", event) + return + } + + val comment = characterCommentRepository.findById(commentId).orElse(null) + if (comment == null) { + log.warn("[PapagoLanguageDetect] CharacterComment not found. commentId={}", commentId) + return + } + + // 이미 언어 코드가 설정된 경우 호출하지 않음 + if (!comment.languageCode.isNullOrBlank()) { + log.debug( + "[PapagoLanguageDetect] languageCode already set. Skip language detection. " + + "characterCommentId={}, languageCode={}", + commentId, + comment.languageCode + ) + return + } + + val langCode = requestPapagoLanguageCode(event.query, commentId) ?: return + + comment.languageCode = langCode + characterCommentRepository.save(comment) + + log.info( + "[PapagoLanguageDetect] languageCode updated from Papago. characterCommentId={}, langCode={}", + commentId, + langCode + ) + } + private fun requestPapagoLanguageCode(query: String, targetIdForLog: Long): String? { return try { val headers = HttpHeaders().apply {