Skip to content
Merged
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
Expand Up @@ -28,11 +28,12 @@ class ChatRestController(
채팅 전송 API 입니다. 해당 API 호출 시 메시지가 전송되고, 채팅 웹소켓에 연결된 유저들에게 메시지가 전송됩니다.
메시지의 길이는 최대 200글자입니다.

type : ['CHAT', 'BOT']
type : ['CHAT', 'BOT_RESPONSE', 'BOT_REQUEST']

메시지가 '/' 로 시작하면 챗봇 답변을 응답합니다.
일반 채팅은 웹소켓으로 메시지를 전송하고, 챗봇은 웹소켓 메시지를 전송하지 않습니다.
따라서 일반 채팅은 웹소켓으로 받은 메시지로 활용하고, 챗봇에게 받은 답변은 해당 API의 응답 결과를 활용해주세요.

""")
fun sendMessage(@Valid @RequestBody chatMessage: ChatMessageSendDTO): ApiResponse<ChatMessageReceiveDTO> {
val receiveDTO = chatMongoService.saveAndPublish(chatMessage)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package busanVibe.busan.domain.chat.enums

enum class MessageType {
CHAT, BOT
CHAT, BOT_REQUEST, BOT_RESPONSE
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import busanVibe.busan.global.apiPayload.code.status.ErrorStatus
import busanVibe.busan.global.apiPayload.exception.GeneralException
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.domain.Pageable
import org.springframework.data.redis.listener.ChannelTopic
import org.springframework.stereotype.Service
Expand All @@ -24,7 +25,9 @@ class ChatMongoService(
private val redisPublisher: RedisPublisher,
private val topic: ChannelTopic,
private val userRepository: UserRepository,
private val openAiService: OpenAiService
private val openAiService: OpenAiService,
@Value("\${image.chat-bot}")
private val chatBotImage: String
) {

val log: Logger = LoggerFactory.getLogger(ChatMongoService::class.java)
Expand All @@ -46,9 +49,9 @@ class ChatMongoService(
val message = chatMessage.message.trim()

// 받은 메세지로 타입 구분
// '/'로 시작하면 챗봇(BOT)
// 일반 메시지는 CHAT, 챗봇 요청은 BOT_REQUEST
val type: MessageType = if(message[0] == '/'){
MessageType.BOT
MessageType.BOT_REQUEST
}else{
MessageType.CHAT
}
Expand All @@ -64,16 +67,32 @@ class ChatMongoService(
time = now
)

// 일반 채팅일 경우 채팅 기록 저장
// 사용자가 보낸 메시지 저장
chatMongoRepository.save(chat)

// 유저들에게 웹소켓으로 전달할 메시지의 DTO 생성
// 유저들에게 웹소켓으로 전달할 메시지의 DTO 생성 - CHAT
val receiveDto = buildReceiveDto(type, currentUser, chat, now)

// 일반 채팅일 경우에만 유저들에게 웹소켓 메시지 보냄
if(type == MessageType.CHAT) {
if(receiveDto.type == MessageType.CHAT) {
redisPublisher.publish(topic, receiveDto)
}

// OpenAI 챗봇 요청
if (receiveDto.type == MessageType.BOT_RESPONSE) {
// openai 요청
openAiService.chatToOpenAI(chat.message)
// 챗봇 대답 저장
chatMongoRepository.save(
ChatMessage(
type = MessageType.BOT_RESPONSE,
userId = currentUser.id,
message = receiveDto.message,
time = chat.time
)
)
}

return receiveDto
}

Expand All @@ -97,11 +116,11 @@ class ChatMongoService(
val message = openAiService.chatToOpenAI(chat.message)
ChatMessageReceiveDTO(
name = "챗봇",
imageUrl = null,
imageUrl = chatBotImage,
message = message,
time = timestamp,
type = type,
userId = -1
type = MessageType.BOT_RESPONSE,
userId = currentUser.id
)
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/busanVibe/busan/domain/common/BaseEntity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import lombok.Getter
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId

@EntityListeners(AuditingEntityListener::class)
@MappedSuperclass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import busanVibe.busan.global.apiPayload.code.status.ErrorStatus
import busanVibe.busan.global.apiPayload.exception.GeneralException
import busanVibe.busan.global.apiPayload.exception.handler.ExceptionHandler
import busanVibe.busan.global.config.security.JwtTokenProvider
import io.lettuce.core.KillArgs.Builder.user
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.beans.factory.annotation.Value
Expand All @@ -35,7 +34,10 @@ class UserCommandService(
private val userRepository: UserRepository,
private val userConverter: UserConverter,
private val jwtTokenProvider: JwtTokenProvider,
private val passwordEncoder: PasswordEncoder
private val passwordEncoder: PasswordEncoder,
@Value("\${image.guest}")
private val guestImage: String

) {

@Value("\${spring.kakao.client-id}")
Expand All @@ -49,8 +51,8 @@ class UserCommandService(
fun guestLogin(): UserLoginResponseDTO.LoginDto {

val email = UUID.randomUUID().toString().substring(0,7) + "@busanvibe.com"
val nickname = UUID.randomUUID().toString().substring(0, 7)
val profileImageUrl: String? = null
val nickname = "guest" + UUID.randomUUID().toString().substring(0, 4)
val profileImageUrl: String? = guestImage

return isNewUser(email, nickname, profileImageUrl, LoginType.GUEST)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package busanVibe.busan.global.config.mongo

import org.springframework.core.convert.converter.Converter
import org.springframework.data.convert.ReadingConverter
import org.springframework.stereotype.Component
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.Date

@Component
@ReadingConverter
class DateToLocalDateTimeKstConverter: Converter<Date, LocalDateTime> {

override fun convert(source: Date): LocalDateTime =
source.toInstant().atZone(ZoneId.of("Asia/Seoul")).toLocalDateTime()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package busanVibe.busan.global.config.mongo

import org.springframework.core.convert.converter.Converter
import org.springframework.data.convert.WritingConverter
import org.springframework.stereotype.Component
import java.sql.Timestamp
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.Date

@Component
@WritingConverter
class LocalDateTimeToDateKstConverter: Converter<LocalDateTime, Date> {

override fun convert(source: LocalDateTime): Date =
Date.from(source.atZone(ZoneId.of("Asia/Seoul")).toInstant())

}
12 changes: 12 additions & 0 deletions src/main/kotlin/busanVibe/busan/global/config/mongo/MongoConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.springframework.boot.autoconfigure.mongo.MongoProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.convert.MongoCustomConversions
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories

@Configuration
Expand All @@ -24,4 +25,15 @@ class MongoConfig(
return MongoTemplate(mongoClient(), mongoProperties.database)
}

@Bean
fun customConversions(
localDateTimeConverter: LocalDateTimeToDateKstConverter,
dateToLocalDateTimeConverter: DateToLocalDateTimeKstConverter,
) = MongoCustomConversions (
listOf(
localDateTimeConverter,
dateToLocalDateTimeConverter
)
)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package busanVibe.busan.global.config.mongo

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.convert.converter.Converter
import org.springframework.data.mongodb.config.AbstractMongoClientConfiguration
import org.springframework.data.mongodb.core.convert.MongoCustomConversions
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.Date

//@Configuration
//class MongoTimeConfig: AbstractMongoClientConfiguration() {
//
// @Bean
// override fun customConversions(): MongoCustomConversions {
// return MongoCustomConversions(
// listOf(
// Converter<LocalDateTime, Date> { Date.from(it.atZone(ZoneId.of("Asia/Seoul")).toInstant()) },
// Converter<Date, LocalDateTime> { it.toInstant().atZone(ZoneId.of("Asia/Seoul")).toLocalDateTime() }
// )
// )
// }
//
// override fun getDatabaseName(): String {
// TODO("Not yet implemented")
// }
//}
5 changes: 3 additions & 2 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ openai:
tourAPI:
key: ${TOUR_API_KEY}



image:
chat-bot: ${IMAGE_CHATBOT}
guest: ${IMAGE_GUEST}