33import com .example .demo .domain .gemini .dto .GeminiRequest ;
44import com .example .demo .domain .gemini .dto .GeminiResponse ;
55import com .example .demo .domain .gemini .exception .GeminiErrorCode ;
6+ import com .example .demo .domain .nerfilter .dto .AiResponse ;
7+ import com .example .demo .domain .nerfilter .dto .TextRequest ;
8+ import com .example .demo .domain .nerfilter .service .AiAnalysisService ;
69import com .example .demo .domain .ranking .service .RankingService ;
710import com .example .demo .shared .exception .CustomException ;
811import com .fasterxml .jackson .core .JsonProcessingException ;
@@ -31,20 +34,38 @@ public class GeminiService {
3134 private final ObjectMapper objectMapper ;
3235 private final RankingService rankingService ;
3336
37+ private final AiAnalysisService aiAnalysisService ;
38+
3439 public Map <String , Object > askGemini (String userContent ) {
40+ TextRequest textRequest = new TextRequest (userContent , true );
41+ AiResponse aiResponse = aiAnalysisService .getAnalysis (textRequest );
42+
43+ String filteredContent = aiResponse .getFilteredText ();
44+ if (filteredContent == null || filteredContent .isBlank ()) {
45+ throw new CustomException (GeminiErrorCode .GEMINI_NO_CONTENT );
46+ }
47+
48+
3549 String cleanKey = apiKey .trim ();
3650
3751 String url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + cleanKey ;
3852
39- String systemPrompt = "유저의 고민을 듣고 다정하게 위로해줘." +
40- "너무 ai 같지 않게 사람답게 말하고, 유저를 절대 비난해서는 안돼." +
41- "무조건적인 공감과 지지를 보내줘. 핵심 키워드 3개 정도를 욕설 제외하고 뽑아줘. 갯수에 제한 받기 보다는, 정말 중요하다 생각되는 키워드를 뽑아."
42- + "반드시 JSON 형식으로만 대답해. 형식: {\" keyword\" : [\" 단어1\" , \" 단어2\" , \" 단어3\" ], \" answer\" : \" 내용\" }" ;
53+ String systemPrompt = "너는 유저의 고민을 듣고 위로해주는 상담사야. " +
54+ "먼저 유저의 입력이 위로가 필요한 상황인지 판단해. " +
55+ "거부해야 할 입력: 숫자만 나열, 명백한 테스트 메시지(예: 'test', '테스트', '123'), 봇/스팸 같은 입력, 의미없는 단어 무한 반복. " +
56+ "위로해줘야 할 입력: 고민/감정 표현, 한글 자음모음을 막 친 것(빡치거나 힘들어서 그럴 수 있음), 욕설이나 분노 표현, 짧은 한숨이나 감정 표현. " +
57+ "만약 위로가 필요한 상황이라면: 다정하게 위로해주고, 너무 AI 같지 않게 사람답게 말해. " +
58+ "유저를 절대 비난하지 말고, 무조건적인 공감과 지지를 보내줘. " +
59+ "키보드를 막 친 것 같으면 '많이 힘드셨나봐요' 같은 공감을 표현해줘. " +
60+ "핵심 키워드를 욕설 제외하고 3개 정도 뽑아줘. 감정 키워드도 괜찮아. 갯수에 제한받기보다는 정말 중요한 키워드만 뽑아. " +
61+ "반드시 JSON 형식으로만 대답해. " +
62+ "위로할 때: {\" isValid\" : true, \" keyword\" : [\" 단어1\" , \" 단어2\" ], \" answer\" : \" 위로 내용\" } " +
63+ "거부할 때: {\" isValid\" : false, \" keyword\" : [], \" answer\" : \" \" }" ;
4364
4465 HttpHeaders headers = new HttpHeaders ();
4566 headers .setContentType (MediaType .APPLICATION_JSON );
4667
47- GeminiRequest request = GeminiRequest .of (systemPrompt , userContent );
68+ GeminiRequest request = GeminiRequest .of (systemPrompt , filteredContent );
4869 HttpEntity <GeminiRequest > entity = new HttpEntity <>(request , headers );
4970
5071 try {
@@ -59,6 +80,13 @@ public Map<String, Object> askGemini(String userContent) {
5980 String cleanedJson = rawContent .replaceAll ("(?s)```json|```" , "" ).trim ();
6081 Map <String , Object > result = objectMapper .readValue (cleanedJson , Map .class );
6182
83+ // 무의미한 입력인지 확인
84+ Object isValidObj = result .get ("isValid" );
85+ boolean isValid = isValidObj instanceof Boolean ? (Boolean ) isValidObj : true ;
86+ if (!isValid ) {
87+ throw new CustomException (GeminiErrorCode .GEMINI_INVALID_INPUT );
88+ }
89+
6290 Object keywordObj = result .get ("keyword" );
6391 if (keywordObj instanceof List ) {
6492 List <String > keywords = (List <String >) keywordObj ;
@@ -72,11 +100,16 @@ public Map<String, Object> askGemini(String userContent) {
72100 }
73101 }
74102
103+ // isValid 필드 제거 후 반환
104+ result .remove ("isValid" );
75105 return result ;
76106 } catch (JsonProcessingException e ) {
77107 throw new CustomException (GeminiErrorCode .GEMINI_PARSE_ERROR );
78108 }
79109
110+ } catch (CustomException e ) {
111+ // CustomException은 그대로 던지기
112+ throw e ;
80113 } catch (HttpClientErrorException .NotFound e ) {
81114 System .err .println ("### 404 에러 상세: " + e .getResponseBodyAsString ());
82115 throw new CustomException (GeminiErrorCode .GEMINI_API_ERROR );
0 commit comments