feat(chat-character): 캐릭터 등록시 파파고 언어 감지 API를 호출하여 languageCode를 기록하는 기능 추가

This commit is contained in:
2025-11-26 11:40:58 +09:00
parent e0dcbd16fc
commit 899f2865b3
3 changed files with 53 additions and 0 deletions

View File

@@ -13,8 +13,11 @@ import kr.co.vividnext.sodalive.chat.character.CharacterType
import kr.co.vividnext.sodalive.chat.character.service.ChatCharacterService
import kr.co.vividnext.sodalive.common.ApiResponse
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.utils.generateFileName
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.ApplicationEventPublisher
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
@@ -40,6 +43,7 @@ class AdminChatCharacterController(
private val adminService: AdminChatCharacterService,
private val s3Uploader: S3Uploader,
private val originalWorkService: AdminOriginalWorkService,
private val applicationEventPublisher: ApplicationEventPublisher,
@Value("\${weraser.api-key}")
private val apiKey: String,
@@ -165,6 +169,18 @@ class AdminChatCharacterController(
originalWorkService.assignOneCharacter(request.originalWorkId, chatCharacter.id!!)
}
// 5. 언어 코드가 지정되지 않은 경우, 파파고 언어 감지 API를 통해 비동기로 언어를 식별한다.
// 언어 감지에 사용할 내용은 chatCharacter.description 만 사용한다.
if (chatCharacter.languageCode.isNullOrBlank() && chatCharacter.description.isNotBlank()) {
applicationEventPublisher.publishEvent(
LanguageDetectEvent(
id = chatCharacter.id!!,
query = chatCharacter.description,
targetType = LanguageDetectTargetType.CHARACTER
)
)
}
ApiResponse.ok(null)
}

View File

@@ -22,6 +22,8 @@ class ChatCharacter(
// 캐릭터 한 줄 소개
var description: String,
var languageCode: String? = null,
// AI 시스템 프롬프트
@Column(columnDefinition = "TEXT", nullable = false)
var systemPrompt: String,

View File

@@ -1,6 +1,7 @@
package kr.co.vividnext.sodalive.content
import kr.co.vividnext.sodalive.chat.character.comment.CharacterCommentRepository
import kr.co.vividnext.sodalive.chat.character.repository.ChatCharacterRepository
import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
import kr.co.vividnext.sodalive.explorer.profile.CreatorCheersRepository
import org.slf4j.LoggerFactory
@@ -23,6 +24,7 @@ import org.springframework.web.client.RestTemplate
enum class LanguageDetectTargetType {
CONTENT,
COMMENT,
CHARACTER,
CHARACTER_COMMENT,
CREATOR_CHEERS
}
@@ -41,6 +43,7 @@ data class PapagoLanguageDetectResponse(
class LanguageDetectListener(
private val audioContentRepository: AudioContentRepository,
private val audioContentCommentRepository: AudioContentCommentRepository,
private val chatCharacterRepository: ChatCharacterRepository,
private val characterCommentRepository: CharacterCommentRepository,
private val creatorCheersRepository: CreatorCheersRepository,
@@ -69,11 +72,43 @@ class LanguageDetectListener(
when (event.targetType) {
LanguageDetectTargetType.CONTENT -> handleContentLanguageDetect(event)
LanguageDetectTargetType.COMMENT -> handleCommentLanguageDetect(event)
LanguageDetectTargetType.CHARACTER -> handleCharacterLanguageDetect(event)
LanguageDetectTargetType.CHARACTER_COMMENT -> handleCharacterCommentLanguageDetect(event)
LanguageDetectTargetType.CREATOR_CHEERS -> handleCreatorCheersLanguageDetect(event)
}
}
private fun handleCharacterLanguageDetect(event: LanguageDetectEvent) {
val characterId = event.id
val character = chatCharacterRepository.findById(characterId).orElse(null)
if (character == null) {
log.warn("[PapagoLanguageDetect] ChatCharacter not found. characterId={}", characterId)
return
}
// 이미 언어 코드가 설정된 경우 호출하지 않음
if (!character.languageCode.isNullOrBlank()) {
log.debug(
"[PapagoLanguageDetect] languageCode already set. Skip language detection. characterId={}, languageCode={}",
characterId,
character.languageCode
)
return
}
val langCode = requestPapagoLanguageCode(event.query, characterId) ?: return
character.languageCode = langCode
chatCharacterRepository.save(character)
log.info(
"[PapagoLanguageDetect] languageCode updated from Papago. characterId={}, langCode={}",
characterId,
langCode
)
}
private fun handleContentLanguageDetect(event: LanguageDetectEvent) {
val contentId = event.id