외부 API 연동 중 제일 힘들었던 것 같다
왜냐면 공식문서 대로 따라했는데
안됏다ㅠ........

위 참고해서 apiURL 랑 secretKey 넣기.
public Map<String, String> sendMessage(String voiceMessage) {
Map<String, String> parsed = new HashMap<>();
try {
String apiURL = "APIGW INvoke URL";
String secretKey = "시크릿키";
URL url = new URL(apiURL);
String message = getReqMessage(voiceMessage);
log.info("[Chatbot] 요청 메시지 JSON: {}", message);
String encodeBase64String = makeSignature(message, secretKey);
log.info("[Chatbot] 생성된 Signature(Base64): {}", encodeBase64String);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json;UTF-8");
con.setRequestProperty("X-NCP-CHATBOT_SIGNATURE", encodeBase64String);
con.setDoOutput(true);
try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
wr.write(message.getBytes(StandardCharsets.UTF_8));
wr.flush();
}
int responseCode = con.getResponseCode();
StringBuilder sb = new StringBuilder();
if (responseCode == 200) {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
}
} else {
log.error("[Chatbot] 오류 응답 코드: {} - {}", responseCode, con.getResponseMessage());
try (BufferedReader err = new BufferedReader(
new InputStreamReader(con.getErrorStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = err.readLine()) != null) {
sb.append(line);
}
}
}
String rawResponse = sb.toString();
log.info("[Chatbot] 원본 응답: {}", rawResponse);
parsed = extractChatResponse(rawResponse);
} catch (Exception e) {
log.error("[Chatbot] 예외 발생", e);
}
log.info("[Chatbot] 최종 응답 data: {}", parsed);
return parsed;
}
public Map<String, String> extractChatResponse(String jsonResponse) {
Map<String, String> result = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(jsonResponse);
JsonNode dataNode = root.has("data")
? (root.get("data").isTextual()
? mapper.readTree(root.get("data").asText())
: root.get("data"))
: root;
String description = dataNode.path("bubbles")
.path(0)
.path("data")
.path("description")
.asText(null);
long timestamp = dataNode.path("timestamp").asLong(0);
if (description != null && timestamp > 0) {
Instant instant = Instant.ofEpochMilli(timestamp);
ZonedDateTime koreaTime = instant.atZone(ZoneId.of("Asia/Seoul"));
String formattedTime = koreaTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
result.put("description", description);
result.put("time", formattedTime);
} else {
log.warn("[Chatbot] 응답 파싱 실패 - 필수 데이터 누락");
}
} catch (Exception e) {
log.error("[Chatbot] 응답 파싱 실패", e);
}
return result;
}
private String makeSignature(String requestBody, String secretKey) throws Exception {
SecretKeySpec signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(requestBody.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(rawHmac);
}
public static String getReqMessage(String voiceMessage) {
try {
ObjectMapper mapper = new ObjectMapper();
long timestamp = new Date().getTime();
ObjectNode obj = mapper.createObjectNode();
obj.put("version", "v2");
obj.put("userId", "U458c90f8e7bddc8131heo281231heo287bddc123");
obj.put("timestamp", timestamp);
ObjectNode dataObj = mapper.createObjectNode();
dataObj.put("description", voiceMessage);
ObjectNode bubblesObj = mapper.createObjectNode();
bubblesObj.put("type", "text");
bubblesObj.set("data", dataObj);
ArrayNode bubblesArray = mapper.createArrayNode();
bubblesArray.add(bubblesObj);
obj.set("bubbles", bubblesArray);
obj.put("event", "send");
return mapper.writeValueAsString(obj);
} catch (Exception e) {
log.error("[Chatbot] 요청 JSON 생성 실패", e);
return "";
}
}
GPT와 구글링으로 완성,,
대화 시나리오 구성하기
빌드하기
배포하기
다 잊지말기!!
대화 시나리오는

예시로 있는거랑 내가 좀 추가한거
변수로 요일, 지역, 단어 다 지정할 수 있다
좀 만지작만지작 해봐야 알 수 있을 것 같다
그리고 찾아본 내용
UI는 제공하는가?
1) 클로바 톡톡, LINE 등 공식 채널 사용 시 : 응답 JSON만 반환하면, 플랫폼에서 알아서 UI로 렌더링해줌.2) 자체 웹 챗봇 사용 시 : JSON 응답만 제공됨, 해당 JSON을 받아 출력할 화면 개발 필요함.
응답 컴포넌트별 지원 내용
1) Basic
텍스트 응답만 필요한 기본 질의. (text, image, link 지원)
ex)주택 신청기간은 언제인가요? → 2025년 3월 예정입니다.
2) Composite
버튼·링크 가능. (text, image, button 지원)
ex)주택 신청기간은 언제인가요? → 단계별 버튼(공고 확인, 신청하러가기)
3) Flex
정보가 카드형 리스트로 제공. (리스트, 카드, 슬라이드 등 커스터마이징 가능)
메신저 연동 등 고급형 서비스용
반응형
'Chapter01 > Open API' 카테고리의 다른 글
| [NCP API] 개인 정보 암호화 방식 (0) | 2025.06.09 |
|---|---|
| [ NCP API ] /encrypt 예시코드, /decrypt 예시코드 (0) | 2025.06.02 |
| [ NCP API ] encrypt / decrypt, signature 생성 예시 코드 (0) | 2025.06.02 |
| [ NCP SENS ] SMS 2Factor 인증 (0) | 2025.05.22 |
| [ OpenStreetMap nominatim API ] 위도 경도로 지역명 가져오기 (2) | 2025.02.12 |