feat(chat): 채팅방 세션 조회 API 구현
This commit is contained in:
parent
4d1f84cc5c
commit
830e41dfa3
|
@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.common.SodaException
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||||
import org.springframework.web.bind.annotation.GetMapping
|
import org.springframework.web.bind.annotation.GetMapping
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
|
@ -60,4 +61,21 @@ class ChatRoomController(
|
||||||
ApiResponse.ok(response)
|
ApiResponse.ok(response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 세션 상태 조회 API
|
||||||
|
* - 채팅방 참여 여부 검증
|
||||||
|
* - 외부 API로 세션 상태 조회 후 active면 true, 아니면 false 반환
|
||||||
|
*/
|
||||||
|
@GetMapping("/{chatRoomId}/session")
|
||||||
|
fun getChatSessionStatus(
|
||||||
|
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||||
|
@PathVariable chatRoomId: Long
|
||||||
|
) = run {
|
||||||
|
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
|
||||||
|
if (member.auth == null) throw SodaException("본인인증을 하셔야 합니다.")
|
||||||
|
|
||||||
|
val isActive = chatRoomService.isMyRoomSessionActive(member, chatRoomId)
|
||||||
|
ApiResponse.ok(isActive)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,18 +34,20 @@ data class ChatRoomListQueryDto(
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 외부 API 채팅 세션 응답 DTO
|
* 외부 API 채팅 세션 생성 응답 DTO
|
||||||
*/
|
*/
|
||||||
data class ExternalChatSessionResponse(
|
data class ExternalChatSessionCreateResponse(
|
||||||
val success: Boolean,
|
val success: Boolean,
|
||||||
val message: String?,
|
val message: String?,
|
||||||
val data: ExternalChatSessionData?
|
val data: ExternalChatSessionCreateData?
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 외부 API 채팅 세션 데이터 DTO
|
* 외부 API 채팅 세션 생성 데이터 DTO
|
||||||
|
* 공통: sessionId, status
|
||||||
|
* 생성 전용: userId, characterId, character, createdAt
|
||||||
*/
|
*/
|
||||||
data class ExternalChatSessionData(
|
data class ExternalChatSessionCreateData(
|
||||||
val sessionId: String,
|
val sessionId: String,
|
||||||
val userId: String,
|
val userId: String,
|
||||||
val characterId: String,
|
val characterId: String,
|
||||||
|
@ -54,6 +56,24 @@ data class ExternalChatSessionData(
|
||||||
val createdAt: String
|
val createdAt: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 외부 API 채팅 세션 조회 응답 DTO
|
||||||
|
*/
|
||||||
|
data class ExternalChatSessionGetResponse(
|
||||||
|
val success: Boolean,
|
||||||
|
val message: String?,
|
||||||
|
val data: ExternalChatSessionGetData?
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 외부 API 채팅 세션 조회 데이터 DTO
|
||||||
|
* 세션 조회에서 사용하는 공통 필드만 포함
|
||||||
|
*/
|
||||||
|
data class ExternalChatSessionGetData(
|
||||||
|
val sessionId: String,
|
||||||
|
val status: String
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 외부 API 캐릭터 데이터 DTO
|
* 외부 API 캐릭터 데이터 DTO
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,7 +8,8 @@ import kr.co.vividnext.sodalive.chat.room.ParticipantType
|
||||||
import kr.co.vividnext.sodalive.chat.room.dto.ChatRoomListItemDto
|
import kr.co.vividnext.sodalive.chat.room.dto.ChatRoomListItemDto
|
||||||
import kr.co.vividnext.sodalive.chat.room.dto.ChatRoomListQueryDto
|
import kr.co.vividnext.sodalive.chat.room.dto.ChatRoomListQueryDto
|
||||||
import kr.co.vividnext.sodalive.chat.room.dto.CreateChatRoomResponse
|
import kr.co.vividnext.sodalive.chat.room.dto.CreateChatRoomResponse
|
||||||
import kr.co.vividnext.sodalive.chat.room.dto.ExternalChatSessionResponse
|
import kr.co.vividnext.sodalive.chat.room.dto.ExternalChatSessionCreateResponse
|
||||||
|
import kr.co.vividnext.sodalive.chat.room.dto.ExternalChatSessionGetResponse
|
||||||
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatMessageRepository
|
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatMessageRepository
|
||||||
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatParticipantRepository
|
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatParticipantRepository
|
||||||
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatRoomRepository
|
import kr.co.vividnext.sodalive.chat.room.repository.CharacterChatRoomRepository
|
||||||
|
@ -150,7 +151,10 @@ class ChatRoomService(
|
||||||
|
|
||||||
// 응답 파싱
|
// 응답 파싱
|
||||||
val objectMapper = ObjectMapper()
|
val objectMapper = ObjectMapper()
|
||||||
val apiResponse = objectMapper.readValue(response.body, ExternalChatSessionResponse::class.java)
|
val apiResponse = objectMapper.readValue(
|
||||||
|
response.body,
|
||||||
|
ExternalChatSessionCreateResponse::class.java
|
||||||
|
)
|
||||||
|
|
||||||
// success가 false이면 throw
|
// success가 false이면 throw
|
||||||
if (!apiResponse.success) {
|
if (!apiResponse.success) {
|
||||||
|
@ -195,4 +199,55 @@ class ChatRoomService(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
fun isMyRoomSessionActive(member: Member, chatRoomId: Long): Boolean {
|
||||||
|
val room = chatRoomRepository.findById(chatRoomId).orElseThrow {
|
||||||
|
SodaException("채팅방을 찾을 수 없습니다.")
|
||||||
|
}
|
||||||
|
val participant = participantRepository.findByChatRoomAndMemberAndIsActiveTrue(room, member)
|
||||||
|
if (participant == null) {
|
||||||
|
throw SodaException("잘못된 접근입니다")
|
||||||
|
}
|
||||||
|
return fetchSessionActive(room.sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchSessionActive(sessionId: String): Boolean {
|
||||||
|
try {
|
||||||
|
val factory = SimpleClientHttpRequestFactory()
|
||||||
|
factory.setConnectTimeout(20000) // 20초
|
||||||
|
factory.setReadTimeout(20000) // 20초
|
||||||
|
|
||||||
|
val restTemplate = RestTemplate(factory)
|
||||||
|
|
||||||
|
val headers = HttpHeaders()
|
||||||
|
headers.set("x-api-key", apiKey)
|
||||||
|
|
||||||
|
val httpEntity = HttpEntity(null, headers)
|
||||||
|
|
||||||
|
val response = restTemplate.exchange(
|
||||||
|
"$apiUrl/api/session/$sessionId",
|
||||||
|
HttpMethod.GET,
|
||||||
|
httpEntity,
|
||||||
|
String::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
val objectMapper = ObjectMapper()
|
||||||
|
val apiResponse = objectMapper.readValue(
|
||||||
|
response.body,
|
||||||
|
ExternalChatSessionGetResponse::class.java
|
||||||
|
)
|
||||||
|
|
||||||
|
// success가 false이면 throw
|
||||||
|
if (!apiResponse.success) {
|
||||||
|
throw SodaException("오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
|
||||||
|
val status = apiResponse.data?.status
|
||||||
|
return status == "active"
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
throw SodaException("오류가 발생했습니다. 다시 시도해 주세요.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue