이전 html,css 시간에 파파고 페이지를 클론코딩 했었는데 이번 시간엔 파파고 깡통 페이지에 PAPAGO API를 호출하여 번역과 언어감지 기능을 추가해보겠습니다. 코드는 제공되지 않으며, 일부 절차는 스킵될수있습니다.
준비물 : node 설치하기!
노드를 설치하는게 아니라 이미 설치된 노드의 npm 패키지를 설치하는것이다.
우리는 이제 JS를 활용해 동적으로 웹페이지의 기능을 구현할것이다. 더 이상 vscode의 liveserver가 아닌 node를 이용해 localhost:3000으로 내 파파고 페이지를 접속해보자!
빈 프로젝트를 생성하고 npm i node를 입력하면된다.


이런 저런 입력할 칸이 뜨는데 할 사람은 해도되는데 그냥 프로젝트에 대한 정보를 적는것이다. 필자는 엔터 광클함.아무튼 package.json이 생기면 성공

npm i superagent
npm i express
Express: Node.js 기반 웹 애플리케이션 서버 프레임워크로, 라우팅, 미들웨어, HTTP 요청/응답 처리를 효율적으로 지원합니다. 어렵죠? 그냥 저희 패키지내에서 '/detect' 라는 경로로 호출하면 받아주는 문을 열어주는느낌이라고 생각하세요!
SuperAgent: HTTP 요청을 간단히 작성할 수 있는 라이브러리로, GET, POST 등 클라이언트 요청을 Promise 또는 콜백 방식으로 처리합니다. -> 이것은 파파고 api한테 요청을 보내기위한거라고 생각하세요!
강사님이 요구하신 사항인데, 파파고를 사용해보면 거의 실시간으로 번역 및 언어감지가 되는데, 우리는 api를 돈내고 사용을 하는 입장에서, 한 글자 입력할 때 마다 api가 호출되면 한정된 리소스가 금방 바닥이 나겠죠?! 그래서 저희는 입력이 더이상 들어오지않고 2초가 지난후에 동작하게 구현해보았습니다. 같이 코드를 보시죠!

const [sourceSelect, targetSelect] = document.getElementsByTagName('select');
const [sourceTextArea, targetTextArea] = document.getElementsByTagName('textarea');

let targetLang = 'en';
targetSelect.addEventListener('change', (event) => targetLang = event.target.value);
이 코드는 위에 저 빨간 부분 셀렉트 박스에 이벤트 리스너로 해당 셀렉트박스 값을 가져오게 만들었습니다.
detectLanguage,translate는 이후 api.js 에서 만들건데 언어감지, 번역 api를 요청하는 함수입니다.
//app.js
let timer;
sourceTextArea.addEventListener('input', (event) => {
if (timer) clearTimeout(timer);
timer = setTimeout(async () => {
const text = event.target.value;
console.log(text);
const detectedResult = await detectLanguage('/detect', text);
targetLang = changeLanguage(detectedResult, targetLang);
const { detectedLanguage, targetLanguage, translatedText } = await translateLanguage('/translate', detectedResult, targetLang, text);
// 결과값 바인딩
sourceSelect.value = detectedLanguage;
targetSelect.value = targetLanguage;
targetTextArea.value = translatedText;
}, 1500);
});
if (timer) clearTimeout(timer); 디바운싱이라고도 부르는데, 이 코드가 없으면 한 글자 입력할때마다 각각 2초에 타이머가 가동됨. 기존에 타이머가 존재하면 타이머를 모두 삭제해주는 기능.//index.js
import express, { json } from 'express';
import HTTP from 'superagent';
const app = express();
app.use(express.static('public'))
app.use(json())
// 코드 일부분 발췌
app.get('/', (_, response) => {
response.sendFile('index.html');
});
app.post('/detect', (request, response) => {
const url = 'https://naveropenapi.apigw.ntruss.com/langs/v1/dect';
HTTP.post(url)
.send(request.body)
.set('Content-Type', 'application/json')
.set('X-NCP-APIGW-API-KEY-ID', clientId)
.set('X-NCP-APIGW-API-KEY', clientSecret)
.end((error, result) => {
if (result.statusCode === 200) {
response.send(result.body);
} else {
console.error(error);
}
});
});
// 번역 요청 처리 API
app.post('/translate', (request, response) => {
const url = 'https://naveropenapi.apigw.ntruss.com/nmt/v1/translation';
HTTP.post(url)
.send(request.body)
.set('Content-Type', 'application/json')
.set('X-NCP-APIGW-API-KEY-ID', clientId)
.set('X-NCP-APIGW-API-KEY', clientSecret)
.end((error, result) => {
if (result.statusCode === 200) {
// 파파고 서버로부터 응답받은 결과 데이터
const responseDataFromPapago = result.body;
// 화면 출력에 필요한 값만 추출
const { srcLangType: detectedLanguage, tarLangType: targetLanguage, translatedText } = responseDataFromPapago.message.result;
const responseData = {
detectedLanguage,
targetLanguage,
translatedText
}
response.send(responseData);
} else {
console.error(error);
}
});
});
사실 app.js에서 바로 fetch를 사용해도 된다. 하지만 너무 코드가 길어지고, 나중에 관리하기도 힘들어서 따로 빼는방식을 추천해주셨다.
//api.js
export const detectLanguage = async (url, text) => {
let sourceLanguage;
const body = { query: text };
await fetch(url, optionsFrom('POST', body))
.then(response => response.json())
.then(data => {
sourceLanguage = data.langCode;
});
return sourceLanguage;
}
// 언어 번역 요청 기능을 수행하는 함수
export const translateLanguage = async (url, detectedLanguage, targetLanguage, text) => {
const body = {
source: detectedLanguage,
target: targetLanguage,
text, // text: text와 같음
}
const result = await fetch(url, optionsFrom('POST', body))
.then(response => response.json())
.then(data => data)
.catch(error => console.error(error));
return result;
}
detectLanguage: 주어진 텍스트를 기반으로 언어를 감지하는 API 요청 함수로, 입력한 언어의 코드값을 return 합니다. 이 값을 셀렉트박스 <options>에 value로 넣어뒀다면, 그 값을 셀렉트박스에 넣기만하면 매칭이 된다.
translateLanguage: 감지된 언어에서 목표 언어로 텍스트를 번역하는 API 요청 함수로, 번역 결과를 반환합니다.
두 함수 모두 fetch를 사용하며, HTTP 요청 옵션은 optionsFrom 함수로 생성됩니다.
간략하게 요약하자면, 사용자가 입력한 값을 2초후에 api.js에 모둘화한 함수를 호출하고, api.js에 정의된 함수는 index.js로 요청을 보낸다.
index.js는 실제 파파고 서버와 HTTP 통신을 한 이후에 결과값을 웹 페이지에 랜더링한다.