Spring/[P] AI 챗봇 기반 맞춤형 레시피 서비스

[SpringBoot/ChatGPT] ChatGPT API (5) DB 기반 질문 요청

alsruds 2024. 2. 28. 01:30

 

사용자의 DB 내 음식 재료를 기반으로 레시피를 추천받아 봅시다 ~

 

 


 

[ DB 기반 메세지 전송하기 ]

 

0. 일반 대화 메세지 전송 & 응답 반환

2024.02.26 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/ChatGPT] ChatGPT API (3) 일반 대화 - 메세지 전송

 

[SpringBoot/ChatGPT] ChatGPT API (3) 일반 대화 - 메세지 전송

SpringBoot 를 이용하는 백엔드 서버에서 ChatGPT 로 메세지를 전송해 봅시다 ~ 1. Configuration : ChatGPT 설정 정보 + 데이터 전송 시 필요한 데이터 세팅 2. Controller : 프론트 서버 요청 동작 처리 3. Service :

alsrudalsrudalsrud.tistory.com

2024.02.27 - [Spring/[Project] AI 챗봇 기반 맞춤형 레시피 서비스] - [SpringBoot/ChatGPT] ChatGPT API (4) 일반 대화 - 메세지 반환

 

[SpringBoot/ChatGPT] ChatGPT API (4) 일반 대화 - 메세지 반환

백엔드에서 ChatGPT 가 보낸 응답 메세지를 받아 프론트엔드로 전송해 봅시다~ 1. Service : ChatGPT 응답 메세지 반환받기 2. DTO : ChatGPT → 백 & 백 → 프론트 서버로 전송할 메세지 데이터 세팅 [ Service ]

alsrudalsrudalsrud.tistory.com

 

1. Controller

@Slf4j
@RestController
@RequestMapping("/ai-chat")
@RequiredArgsConstructor
@Tag(name = "AI Recipe Chatbot", description = "레시피 추천 챗봇 관련 API")
public class ChatGptController {
    private final ChatGptService chatGPTService;

    ...

    // 사용자 냉장고 재료 기반 레시피 요청
    @GetMapping("/refri")
    @Operation(summary = "사용자 냉장고 재료 기반 레시피 조회 API", description = "사용자의 냉장고 속 재료를 기반으로 레시피를 추천해주는 API 입니다")
    public ApiResponse<UserChatGptResponseDTO.UserGptResponseDTO> getRefriRecipeResponse() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String memberId = authentication.getName();
        try {
            String response = chatGPTService.askRefriQuestion(memberId).getChoices().get(0).getMessage().getContent();
            return ApiResponse.onSuccess(ChatGptConverter.toUserGptResponseDTO(response));
        } catch (GeneralException e) {
            return ApiResponse.onSuccess(ChatGptConverter.toUserGptResponseDTO("재료를 찾을 수 없습니다"));
        }
    }
}

 

· 인증 토큰 분석으로 사용자 정보 가져오기

· 저장되어 있는 재료가 없을 시 에러 메세지 반환

 

2. Service

public interface ChatGptService {

    ...
    // 사용자 재료 기반 레시피
    ChatGptResponseDTO askRefriQuestion(String memberId);
}
@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class ChatGptServiceImpl implements ChatGptService {

    private final MemberRepository memberRepository;
    private final IngredientRepository ingredientRepository;
    private static RestTemplate restTemplate = new RestTemplate();

    @Value("${chatgpt.api-key}")
    private String apiKey;

    // ChatGPT 에 요청할 때 포함해야 하는 값 세팅하기
    @Transactional
    public HttpEntity<ChatGptRequestDTO> buildHttpEntity(ChatGptRequestDTO requestDTO) {
        ...
    }

    // ChatGPT API 응답 반환 받기
    @Transactional
    public ChatGptResponseDTO getResponse(HttpEntity<ChatGptRequestDTO> chatGptRequestDTOHttpEntity) {
        ...
    }

    // ChatGPT API 요청하기 - 일반 대화
    @Override
    public ChatGptResponseDTO askQuestion(String question) {
        ...
    }

    // ChatGPT API 요청하기 - 냉장고 재료 기반
    @Override
    public ChatGptResponseDTO askRefriQuestion(String memberId) {

        // 사용자 재료 조회
        List<Ingredient> myIngredientList = ingredientRepository.findNamesByMember_PersonalId(memberId);
        if (myIngredientList.isEmpty()) {
            throw new GeneralException(ErrorStatus.INGREDIENT_NOT_FOUND);
        }
        String myIngredient = myIngredientList.stream()
                .map(Ingredient::getName)
                .collect(Collectors.joining(", "));

        // 질문 넘겨주기
        String question = myIngredient + "주어진 재료를 활용하여 만들 수 있는 레시피(조리 방법)를 알려줘";
        return askQuestion(question);
    }
}

 

· DB 에서 가져온 데이터를 포함한 질문 생성 후 일반 대화처럼 넘겨주기

 

3. Repository

public interface IngredientRepository extends JpaRepository<Ingredient, Long> {

    // 사용자가 가지고 있는 재료 이름 조회
    List<Ingredient> findNamesByMember_PersonalId(String memberId);
}

 

 

테스트 성공 화면