CLOVA Chatbot
- 챗봇 제작 API 서비스
- 사용자의 질문 의도를 이해하여 고객 대응 등 다양한 서비스에 활용할 수 있는 Chatbot 제작 지원
Web, App에서의 챗봇 구현 방법 : Custom 연동 방법
- CLOVA Chatbot 빌더를 이용해서 대화 작성
- 대화 모델 빌드하고 배포 (10~20분 정도 소요)
- CLOVA Chatbot Custom 연동을 설정
- API Gateway 호출 URL 생성하고 Secret Key 발급 ( API 코드에서 사용 )
- API Gateway 호출 URL 통해서 애플리케이션에서 호출 ( 스프링 프로젝트와 연동)
CLOVA Chatbot 구현 과정
- 도메인 생성 (도메인 이름 / 도메인 코드 / 자연어처리 : 한국어 / 서비스타입 : Standard / 대화로그 임시 저장 : 저장하지 않음)
- 빌더 실행하기
- 대화 생성
- 학습 질문 입력
- 챗봇 답변 입력
- 챗봇 빌드
- 챗봇 테스트
- 서비스 배포 ( APIGW 연동 설정 )
- 스프링에서 작업
[ chatbot 예제 1 ]
(1) 폼에서 질문 메시지 입력 받고 결과 출력
(2) 채팅창
APIController
더보기
@Autowired
private ChatbotService chatService;
// 챗봇 : 질문 메시지 전송하고 결과 받아서 출력
// static : 객체를 생성해서 호출하는 것이 아닌, 클래스 이름으로 호출
/*@RequestMapping("/chatbot")
public void chatbot() {
String result = chatService.main("맡은 역할은");
System.out.println(result);
}*/
@RequestMapping("/chatbotForm")
public String chatbotForm() {
return "chatForm";
}
// 채팅창
@RequestMapping("/chatbotForm2")
public String chatbotForm2() {
return "chatForm2";
}
APIRestController
더보기
@Autowired
private ChatbotService chatService;
@RequestMapping("/chatbotCall")
public String chatbotCall(@RequestParam("message") String message ) {
String result = chatService.main(message);
return result;
}
ChatbotService
더보기
package com.ai.ex.service;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.stereotype.Service;
import com.ai.ex.model.ObjectVO;
@Service
public class ChatbotService {
public String main(String voiceMessage) {
//public static String main(String voiceMessage) {
String apiURL = "";
String secretKey = "";
String chatbotMessage = ""; // 응답 메시지
try {
//String apiURL = "https://ex9av8bv0e.apigw.ntruss.com/custom_chatbot/prod/";
URL url = new URL(apiURL);
String message = getReqMessage(voiceMessage);
System.out.println("##" + message);
String encodeBase64String = makeSignature(message, secretKey);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-Type", "application/json;UTF-8");
con.setRequestProperty("X-NCP-CHATBOT_SIGNATURE", encodeBase64String);
// post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.write(message.getBytes("UTF-8"));
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // Normal call
System.out.println(con.getResponseMessage());
BufferedReader in = new BufferedReader(
new InputStreamReader(
con.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
chatbotMessage = decodedString;
}
//chatbotMessage = decodedString;
in.close();
// 응답 메시지 출력
System.out.println(chatbotMessage);
chatbotMessage = jsonToString(chatbotMessage);
} else { // Error occurred
chatbotMessage = con.getResponseMessage();
}
} catch (Exception e) {
System.out.println(e);
}
return chatbotMessage; // 응답 메시지 반환
}
public static String makeSignature(String message, String secretKey) {
String encodeBase64String = "";
try {
byte[] secrete_key_bytes = secretKey.getBytes("UTF-8");
SecretKeySpec signingKey = new SecretKeySpec(secrete_key_bytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
// encodeBase64String = Base64.encodeToString(rawHmac, Base64.NO_WRAP);
encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
return encodeBase64String;
} catch (Exception e){
System.out.println(e);
}
return encodeBase64String;
}
public static String getReqMessage(String voiceMessage) {
String requestBody = "";
try {
JSONObject obj = new JSONObject();
long timestamp = new Date().getTime();
System.out.println("##"+timestamp);
obj.put("version", "v2");
obj.put("userId", "U47b00b58c90f8e47428af8b7bddc1231heo2");
//=> userId is a unique code for each chat user, not a fixed value, recommend use UUID. use different id for each user could help you to split chat history for users.
obj.put("timestamp", timestamp);
JSONObject bubbles_obj = new JSONObject();
bubbles_obj.put("type", "text");
JSONObject data_obj = new JSONObject();
data_obj.put("description", voiceMessage);
bubbles_obj.put("type", "text");
bubbles_obj.put("data", data_obj);
JSONArray bubbles_array = new JSONArray();
bubbles_array.put(bubbles_obj);
obj.put("bubbles", bubbles_array);
/*obj.put("event", "send");*/
// 웰컴 메시지 출력
if(voiceMessage == "") {
obj.put("event", "open"); // 웰컴 메시지
} else {
obj.put("event", "send");
}
requestBody = obj.toString();
} catch (Exception e){
System.out.println("## Exception : " + e);
}
return requestBody;
}
// 서버로부터 받은 결과 JSON 데이터 추출해서 반환
public String jsonToString(String jsonResultStr) {
String result = "";
JSONObject jsonObj = new JSONObject(jsonResultStr);
JSONArray bubblesArray = (JSONArray) jsonObj.get("bubbles");
JSONObject obj0 = (JSONObject) bubblesArray.get(0);
JSONObject dataObj = (JSONObject) obj0.get("data");
result = (String) dataObj.get("description");
return result;
}
}
chatbot.js
더보기
/**
* chatbot.js
*/
$(function(){
$('#chatForm').on('submit', function(event){
event.preventDefault();
$.ajax({
url:"chatbotCall",
type:"post",
data:{message: $('#message').val()},
success:function(result){
$('#chatBox').text(result); // 저장된 '음성 파일명' 출력
},
error:function(e){
alert("오류가 발생했습니다." + e)
}
});
/* 입력란 비우기 */
$('#message').val('');
});
});
chatbot2.js
더보기
/**
* chatbot2.js
*/
$(function(){
// 웰컴 메시지를 받기 위해서 message 입력받기 전에
// 빈 값으로 서버에 전송하고
// 웰컴 메시지를 받기 위해 $.axaj()를 별도의 함수로 분리해서 호출
callAjax(); // 빈 값으로 서버 전송 -> open 이벤트 호출 -> 웰컴 메시지 출력하기 위해 함수 호출
$('#chatForm').on('submit', function(event){
event.preventDefault();
// 입력란에 메시지 입력하지 않은 채로 [전송] 버튼 클릭 시 경고창 출력 & 웰컴메시지 출력되지 않도록 함
if($('#message').val()=="") {
alert("질문을 입력하세요");
return false;
}
/* chatBox에 보낸 메시지 추가*/
if($('#message').val() != ""){
$('#chatBox').append('<div class="msgBox send"><span id="in"><span>' +
$('#message').val() + '</span></span></div><br>');
}
callAjax(); // 기존에 ajax가 있던 자리에 따로 분리해준 callAjax() 함수 호출
/* 입력란 비우기 */
$('#message').val('');
}); // submit 끝
// $.ajax()를 별도의 함수로 분리
function callAjax() {
$.ajax({
url:"chatbotCall",
type:"post",
data:{message: $('#message').val()},
success:function(result){
/* chatBox에 받은 메시지 추가 */
$('#chatBox').append('<div class="msgBox receive"><span id="in"><span>챗봇</span><br><span>' +
result +'</span></span></div><br><br>');
// 스크롤해서 올리기
$("#chatBox").scrollTop($("#chatBox").prop("scrollHeight"));
},
error:function(e){
alert("오류가 발생했습니다." + e)
}
});
}
});
chatForm.jsp
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>chatbot</title>
<script src="<c:url value='/js/jquery-3.6.0.min.js'/>"></script>
<script src="<c:url value='/js/chatbot.js'/>"></script>
</head>
<body>
<h3>chatbot</h3>
<form id="chatForm" enctype="multipart/form-data">
<input type="text" id="message" name="message" size="30" placeholder="질문을 입력하세요">
<input type="submit" value="전송">
</form>
<br><br>
<!-- 응답 메시지 출력 -->
<div id="chatBox"></div>
<br><br>
<a href="/">index 페이지로 이동</a>
</body>
</html>
chatForm2.jsp
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>chatbot2</title>
<script src="<c:url value='/js/jquery-3.6.0.min.js'/>"></script>
<script src="<c:url value='/js/chatbot2.js'/>"></script>
<link rel="stylesheet" type="text/css" href="<c:url value='/css/chatbot.css'/>">
</head>
<body>
<div id="wrap">
<!-- Header -->
<div id="chatHeader">
<span>chatbot</span>
<button id="btnClose">X</button>
</div>
<!-- 채팅 내용 출력 -->
<!-- 응답 메시지 출력 -->
<div id="chatBox"></div>
<form id="chatForm" enctype="multipart/form-data">
<input type="text" id="message" name="message" size="30" placeholder="질문을 입력하세요">
<input type="submit" value="전송">
</form>
<br><br>
<br><br>
<a href="/">index 페이지로 이동</a>
</div>
</body>
</html>
chatbot.css
더보기
@charset "UTF-8";
#wrap { margin:0 auto; width: 500px; height: 800px; }
#chatHeader {padding: 10px 15px; border-bottom: 1px solid #95a6b4;}
#btnClose {border: none; background: none; float: right;}
#chatBox {height: 600px; width: 500px; overflow-y:scroll; padding:10px 15px; background:#9bbbd4;}
#message {width: 440px;}
#btnSubmit {float: right; background:#eeeeee; height: 28px; padding-right:0;}
.msgBox span {padding:3px 5px; word-break:break-all; display:block;
max-width:300px; margin-bottom: 10px; border-radius: 10px;}
.msgBox.send span {background:#fef01b; float:right; }
.msgBox #in {width:480px; background:#9bbbd4;}
.msgBox.receive span {background:#ffffff; float:left; }
index.jsp
더보기
<a href="chatbotForm">챗봇</a><br><br>
<a href="chatbotForm2">챗봇2 : 채팅창</a><br><br>
[ chatbot 예제 2 : 예제 1에 질문 및 답변 음성 인식 기능 추가 ]
- 질문을 녹음해서 mp3 파일로 저장 -> mp3 파일을 텍스트로 변환 : STT 서비스 사용
- 변환된 텍스트를 질문으로 챗봇 서버로 전송해서 답변 받아서 텍스트 및 음성으로 출력 : TTS 서비스 사용
공통 메시지 추가 ( 답변 입력 및 저장 / 대화 모델 빌드 )
APIController
더보기
// 채팅창 + 음성 질문
@RequestMapping("/chatbotForm3")
public String chatbotForm3() {
return "chatForm3";
}
APIRestController
더보기
@RequestMapping("/chatbotTTS")
public String chatbotTTS(@RequestParam("message") String message ) {
String result = ttsService.chatbotTextToSpeech(message);
return result; // voiceFileName; // 저장된 음성 파일명 반환
}
STTService
더보기
package com.ai.ex.service;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import org.json.JSONObject;
import org.springframework.stereotype.Service;
@Service
public class STTService {
public String clovaSpeechToText(String filePathName) {
String clientId = ""; // Application Client ID";
String clientSecret = ""; // Application Client Secret";
String result = "";
try {
String imgFile = filePathName;
File voiceFile = new File(imgFile);
String language = "Kor"; // 언어 코드 ( Kor, Jpn, Eng, Chn )
String apiURL = "https://naveropenapi.apigw.ntruss.com/recog/v1/stt?lang=" + language;
URL url = new URL(apiURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
conn.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
OutputStream outputStream = conn.getOutputStream();
FileInputStream inputStream = new FileInputStream(voiceFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
BufferedReader br = null;
int responseCode = conn.getResponseCode();
if(responseCode == 200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else { // 오류 발생
System.out.println("error!!!!!!! responseCode= " + responseCode);
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
String inputLine;
if(br != null) {
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
result = jsonToString(response.toString()); // JSON 문자열에서 텍스트 추출
resultToFileSave(result); //파일로 저장
} else {
System.out.println("error !!!");
}
} catch (Exception e) {
System.out.println(e);
}
return result;
}
public String clovaSpeechToText2(String filePathName, String language) {
String clientId = "6to327c88d"; // Application Client ID";
String clientSecret = "HqfsYXHJrk5mWcv3hgJQq3qk94YebLJ0knjw5M1k"; // Application Client Secret";
String result = "";
try {
String imgFile = filePathName;
File voiceFile = new File(imgFile);
//String language = "Kor"; // 언어 코드 ( Kor, Jpn, Eng, Chn )
String apiURL = "https://naveropenapi.apigw.ntruss.com/recog/v1/stt?lang=" + language;
URL url = new URL(apiURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Content-Type", "application/octet-stream");
conn.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
conn.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
OutputStream outputStream = conn.getOutputStream();
FileInputStream inputStream = new FileInputStream(voiceFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
BufferedReader br = null;
int responseCode = conn.getResponseCode();
if(responseCode == 200) { // 정상 호출
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else { // 오류 발생
System.out.println("error!!!!!!! responseCode= " + responseCode);
br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
}
String inputLine;
if(br != null) {
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
result = jsonToString(response.toString()); // JSON 문자열에서 텍스트 추출
resultToFileSave(result); //파일로 저장
} else {
System.out.println("error !!!");
}
} catch (Exception e) {
System.out.println(e);
}
return result;
}
// API 서버로부터 받은 JSON 형태의 결과 데이터를 전달받아서 text 추출
public String jsonToString(String jsonResultStr) {
String resultText = "";
try {
//org.json.JSONObject; 사용한 경우
JSONObject jsonObj = new JSONObject(jsonResultStr);
resultText = (String) jsonObj.getString("text");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultText;
}
// 음성 파일에서 추출한 텍스트를 txt 파일로 저장
public void resultToFileSave(String result) {
try {
String fileName = Long.valueOf(new Date().getTime()).toString();
String filePathName = "C:/upload/" + "stt_" + fileName + ".txt";
FileWriter fw = new FileWriter(filePathName);
fw.write(result);
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
TTSService
더보기
package com.ai.ex.service;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import org.springframework.stereotype.Service;
@Service
public class TTSService {
public void clovaTextToSpeech() {
String clientId = "";//애플리케이션 클라이언트 아이디값";
String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
try {
String text = URLEncoder.encode("만나서 반갑습니다.", "UTF-8"); // 13자
String apiURL = "https://naveropenapi.apigw.ntruss.com/tts-premium/v1/tts";
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
// post request
String postParams = "speaker=meimei&volume=0&speed=0&pitch=0&format=mp3&text=" + text;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // 정상 호출
InputStream is = con.getInputStream();
int read = 0;
byte[] bytes = new byte[1024];
// 랜덤한 이름으로 mp3 파일 생성
String tempname = Long.valueOf(new Date().getTime()).toString();
//File f = new File(tempname + ".mp3");
File f = new File("C:/upload/" + tempname + ".mp3");
f.createNewFile();
OutputStream outputStream = new FileOutputStream(f);
while ((read =is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
is.close();
} else { // 오류 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
}
} catch (Exception e) {
System.out.println(e);
}
}
// 파일 경로 및 언어 전달 받음
// 저장된 파일 명 반환
public String clovaTextToSpeech2(String filePathName, String language) {
String clientId = "";//애플리케이션 클라이언트 아이디값";
String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
String voiceFileName = "";
try {
// 전달 받은 파일에서 텍스트를 추출하기 위한 함수 fileRead() 사용
// 함수에게 전달하고 텍스트 받음
String fileContents = fileRead(filePathName);
String text = URLEncoder.encode(fileContents, "UTF-8"); //
String apiURL = "https://naveropenapi.apigw.ntruss.com/tts-premium/v1/tts";
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
// post request
String postParams = "speaker=" + language + "&volume=0&speed=0&pitch=0&format=mp3&text=" + text;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // 정상 호출
InputStream is = con.getInputStream();
int read = 0;
byte[] bytes = new byte[1024];
// 랜덤한 이름으로 mp3 파일 생성
String tempname = Long.valueOf(new Date().getTime()).toString();
//File f = new File(tempname + ".mp3");
voiceFileName = "tts_" + tempname + ".mp3";
File f = new File("C:/upload/" + voiceFileName);
f.createNewFile();
OutputStream outputStream = new FileOutputStream(f);
while ((read =is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
is.close();
} else { // 오류 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
}
} catch (Exception e) {
System.out.println(e);
}
return voiceFileName; // 저장된 음성 파일명 반환
}
// 챗봇으로 부터 받은 텍스트 답변을 음성으로 변환
public String chatbotTextToSpeech(String message) {
String clientId = "";//애플리케이션 클라이언트 아이디값";
String clientSecret = "";//애플리케이션 클라이언트 시크릿값";
String voiceFileName = "";
try {
String text = URLEncoder.encode(message, "UTF-8"); //
String apiURL = "https://naveropenapi.apigw.ntruss.com/tts-premium/v1/tts";
URL url = new URL(apiURL);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("X-NCP-APIGW-API-KEY-ID", clientId);
con.setRequestProperty("X-NCP-APIGW-API-KEY", clientSecret);
// post request
String postParams = "speaker=nara&volume=0&speed=0&pitch=0&format=mp3&text=" + text;
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(postParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
BufferedReader br;
if(responseCode==200) { // 정상 호출
InputStream is = con.getInputStream();
int read = 0;
byte[] bytes = new byte[1024];
// 랜덤한 이름으로 mp3 파일 생성
String tempname = Long.valueOf(new Date().getTime()).toString();
//File f = new File(tempname + ".mp3");
voiceFileName = "tts_" + tempname + ".mp3";
File f = new File("C:/upload/" + voiceFileName);
f.createNewFile();
OutputStream outputStream = new FileOutputStream(f);
while ((read =is.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
is.close();
} else { // 오류 발생
br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = br.readLine()) != null) {
response.append(inputLine);
}
br.close();
System.out.println(response.toString());
}
} catch (Exception e) {
System.out.println(e);
}
return voiceFileName; // 저장된 음성 파일명 반환
}
// 파일 경로를 전달받아서 파일 내 텍스트 추출해서 반환 함수
public String fileRead(String filePathName) {
String result = "";
try {
File file = new File(filePathName);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
String line = "";
while((line = br.readLine()) != null){
result += line;
}
br.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(result); // 출력해서 확인
return result;
}
}
chatbot3.js
더보기
/**
* chatbot3.js
*/
$(function(){
// 웰컴 메시지를 받기 위해서 message 입력받기 전에
// 빈 값으로 서버에 전송하고 웰컴 메시지를 받기 위해
// $.ajax()를 별도의 함수로 분리해서 호출
callAjax(); //메시지 입력하지 않고 호출해서 빈값 전송 -> open event -> 웰컴 메시지 출력
/////////////////////////////////////////////////////////
// 음성으로 질문하기
//(1) 녹음 기능
const record = document.getElementById("record");
const stop = document.getElementById("stop");
const soundClips = document.getElementById("sound-clips");
const audioCtx = new(window.AudioContext || window.webkitAudioContext)(); // 오디오 컨텍스트 정의
if (navigator.mediaDevices) {
var constraints = {
audio: true
}
let chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
const mediaRecorder = new MediaRecorder(stream);
record.onclick = () => {
mediaRecorder.start();
record.style.background = "red";
record.style.color = "black";
}
stop.onclick = () => {//정지 버튼 클릭 시
mediaRecorder.stop();//녹음 정지
record.style.background = "";
record.style.color = "";
}
mediaRecorder.onstop = e => {
const clipName = "voiceMsg";
//태그 3개 생성
const clipContainer = document.createElement('article');
const audio = document.createElement('audio');
const a = document.createElement('a');
clipContainer.appendChild(a);
soundClips.appendChild(clipContainer);
//chunks에 저장된 녹음 데이터를 audio 양식으로 설정
//audio.controls = true;
const blob = new Blob(chunks, {
'type': 'audio/mp3 codecs=opus'
}) ;
chunks = [];
const audioURL = URL.createObjectURL(blob);
// audio.src = audioURL;
//blob:http://localhost:8011/6377d19d-2ca8-49b1-a37f-068d602ceb60
a.href=audioURL;
a.download = clipName;
//a.innerHTML = "DOWN"
a.click(); // 다운로드 폴더에 저장하도록 클릭 이벤트 발생
fileUpload(blob, clipName);
}//mediaRecorder.onstop
//녹음 시작시킨 상태가 되면 chunks에 녹음 데이터를 저장하라
mediaRecorder.ondataavailable = e => {
chunks.push(e.data)
}
})
.catch(err => {
console.log('The following error occurred: ' + err)
})
}
// (2) 서버에 파일 업로드
function fileUpload(blob, clipName){
var formData = new FormData();
formData.append('uploadFile', blob, clipName+".mp3");
//녹음된 mp3파일 전송하고 반환된 텍스트(result)를 챗봇 서버에 전달
$.ajax({
type:"post",
enctype: 'multipart/form-data',
url: "clovaSTT", //통신할 url
data: formData, //전송할 데이타 : 파일명 :voiceMsg.mp3
processData: false,
contentType: false,
success: function(result) {
$('#chatBox').append('<div class="msgBox send"><span id="in"><span>' +
result + '</span></span></div><br>');
// 챗봇에게 전달
$('#message').val(result);
callAjax();
$('#message').val('');
},
error: function(e) {
alert("에러가 발생했습니다 : " + e);
}
});
}
/////////////////////////////////////////////////////////
// 챗봇에게 질문하고 응답받기 - 텍스트 응답
// message 입력하고 전송 버튼 눌렀을 때
$('#chatForm').on('submit', function(event){
event.preventDefault();
// 입력란에 메시지 입력하지 않은 채로 [전송] 버튼 누른 경우 (웰컴 메시지 출력되지 않도록 함 & 클릭 시 경고창 출력)
if ($('#message').val() == ""){
alert("질문을 입력하세요");
return false;
}
/* chatBox에 보낸 메시지 추가 */
if($('#message').val() != ""){
$('#chatBox').append('<div class="msgBox send"><span id="in"><span>' +
$('#message').val() + '</span></span></div><br>');
}
callAjax(); // 입력된 값 전송 (기존에 ajax가 있던 자리에 따로 분리해문 callAjax() 함수 호출)
/* 입력란 비우기*/
$('#message').val('');
}); // submit 끝
// $.ajax()를 별도의 함수로 분리
function callAjax(){
$.ajax({
url:"chatbotCall",
type:"post",
data:{message: $('#message').val()},
success:function(result){
/* chatBox에 받은 메시지 추가 */
$('#chatBox').append('<div class="msgBox receive"><span id="in"><span>챗봇</span><br><span>' +
result +'</span></span></div><br><br>');
// 스크롤해서 올리기
$("#chatBox").scrollTop($("#chatBox").prop("scrollHeight"));
// 챗봇으로 부터 받은 텍스트 답변을 음성으로 변환하기 위해 TTS 호출
callAjaxTTS(result);
},
error:function(){
alert("오류가 발생했습니다.")
}
});
}
function callAjaxTTS(result){
$.ajax({
type:"post",
url:"chatbotTTS",
data:{message : result},
dataType :'text',
success:function (result){ //음성 파일 이름 받음
/* chatBox에 받은 음성 메시지 플레이 */
$('audio').prop("src", '/voice/'+ result)[0].play();
$('audio').hide();
},
error:function(data){
alert("에러 발생");
}
});
}
});
chatForm3.jsp
더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>챗봇</title>
<script src="<c:url value='/js/jquery-3.6.0.min.js'/>"></script>
<script src="<c:url value='/js/chatbot3.js'/>"></script>
<link rel="stylesheet" type="text/css" href="<c:url value='/css/chatbot.css'/>">
</head>
<body>
<div id="wrap">
<!-- Header -->
<div id="chatHeader">
<span>챗봇</span>
<button id="btnClose">X</button>
</div>
<!-- 채팅 내용 출력 -->
<!-- 응답 메시지 출력 -->
<div id="chatBox"></div><br>
<div>
<!-- 질문 메시지 입력 폼 -->
<form id="chatForm">
<input type="text" id="message" name="message" size="30" placeholder="질문을 입력하세요">
<input type="submit" value="전송">
</form>
</div><br>
<div>
<!-- 음성 녹음 -->
음성 메시지 : <button id="record">녹음</button>
<button id="stop">정지</button>
<div id="sound-clips"></div><br>
</div>
<div>
<audio preload="auto" controls></audio>
</div>
<br><br>
<a href="/">index 페이지로 이동</a>
</div>
</body>
</html>
index.jsp
더보기
<a href="chatbotForm3">챗봇3 : 채팅창 + 음성으로 질문</a><br><br>
필요에 따라 STT / TTS 코드 추가 ( https://olli2.tistory.com/234 )
음성 인식 : CLOVA Speech Recognition (CSR) / CLOVA Voice - Premium
CLOVA Speech Recognition (CSR) : 음성 인식 사람의 목소리를 텍스트로 변환 | 음성을 텍스트로 변환 : STT(Speech-To-Text) 언어 선택 가능 Application에서 CLOVA Speech Recognition (CSR) 서비스 추가하여 사..
olli2.tistory.com
'API > NAVER CLOVA' 카테고리의 다른 글
SENS (Simple & Easy Notification Service) (0) | 2022.03.05 |
---|---|
음성 인식 : CLOVA Speech Recognition (CSR) / CLOVA Voice - Premium (0) | 2022.01.26 |
Object Detection (객체 탐지) (0) | 2022.01.26 |
Pose Estimation (포즈 인식) (0) | 2022.01.25 |
CLOVA OCR (Optical Character Recognition) (0) | 2022.01.25 |