혼자/주저리주저리

papago 흐름 설명해보기

닉네임생각즁 2023. 11. 28. 23:53

전체적인 흐름 이해하는게 어려웠다,,

반 친구들한테 설명 듣고 특강때 한번 더 듣고하면서 대애애애충 흐름은 이해했는데 혼자 만들어보라고 하면 절대절대 못할 듯ㅠㅠ 기억 다 날아가기전에 혼자서도 흐름 설명할 수 있는지 적어보려고한다

 

내가 이해한대로 쓰는거라 당연히 정답 아닐 수도,,,,아닐 가능성이 큼,,,,,,,,,,,,,,

 

 

app.js

/**
 * source ~ : 번역할 텍스트, 번역할 언어의 타입(ko, ja..)
 * target ~ : 번역 결과 텍스트, 번역될 언어의 타입(ko, ja..)
 */

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

let targetLanguage = 'en'; // 번역하고 싶은 언어의 타입, 초기값을 en(English)

// 번역될 언어의 타입 변경 이벤트
// English면 en, 한국어면 ko
targetSelect.addEventListener('change', (event) => targetLanguage = event.target.value);

let timer;
sourceTextArea.addEventListener('input', (event) => {
    if(timer) clearTimeout(timer);

    timer = setTimeout(() => {
        const text = event.target.value;

        const body = JSON.stringify({ query: text });
        
        // server.js로 비동기 요청 전송
        const xhr = new XMLHttpRequest();
        const xhr2 = new XMLHttpRequest();

        xhr.onload = () => {
            if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                const responseData = xhr.responseText;
                const result = JSON.parse(responseData);
                
                const url = '/translate';
                
                const sourceLanguage = result.langCode;
                console.log(sourceLanguage);
                
                const body = JSON.stringify({
                    source: sourceLanguage,
                    target: targetLanguage,
                    text
                });
                
                xhr2.open('POST', url); // 똑같이 이름 xhr 로 해줘도 상관 없음
                xhr2.onload = () => {
                    if (xhr2.readyState === xhr2.DONE && xhr2.status === 200) {
                        console.log('called');
                        console.log(xhr2.response);
                    }
                }

                xhr2.setRequestHeader('Content-Type', 'application/json');
                xhr2.send(body);
            }
        }

        const url = '/detectLangs';
        xhr.open('POST', url);
        
        xhr.setRequestHeader('Content-Type', 'application/json');

        xhr.send(body);

    }, 2000);

});

 

server.js

const express = require('express')
const app = express()

const client_id = '자신의 key값';
const client_secret = '자신의 secret값';


// public이라는 이름의 폴더에 정적 리소스 보관 후 응답하도록 미들웨어 추가
app.use(express.static('public'));

// 역직렬화용 미들웨어 추가
app.use(express.json());

app.get('/', (req, res) => res.sendFile('index.html'));

// localhost:3000/detectLangs로 요청 시 동작할 핸들러
app.post('/detectLangs', function (req, res) {
   const url = 'https://openapi.naver.com/v1/papago/detectLangs';
   const request = require('request');

   const options = {
       url,
       form: req.body,
       headers: {
        'Content-Type': 'application/json',
        'X-Naver-Client-Id':client_id, 
        'X-Naver-Client-Secret': client_secret
      }
    };

   request.post(options, function (error, response, body) {
     if (!error && response.statusCode == 200) {
      res.send(body); // 응답 결과를 app.js로 전달하는 코드
     } else {
       res.status(response.statusCode).end();
       console.log('error = ' + response.statusCode);
     }
   });
 });

// localhost:3000/translate로 요청 시 동작할 핸들러
app.post('/translate', (req, res) => {
  //  const query = '안녕하세요?';
   const url = 'https://openapi.naver.com/v1/papago/n2mt';
   
   const request = require('request');
   const options = {
       url, // url: url과 같음
      //  form: {'source':'ko', 'target':'en', 'text':query},
      form: req.body,
      headers: {
        'Content-Type': 'application/json',
        'X-Naver-Client-Id':client_id, 
        'X-Naver-Client-Secret': client_secret
      }
    };
    // 실제로 POST 요청 전송 부분
   request.post(options, (error, response, body) => {

     if (!error && response.statusCode == 200) {
      console.log(body);
      res.send(body); // 응답 결과를 app.js로 전달하는 코드
     } else {
       res.status(response.statusCode).end();
       console.log('error = ' + response.statusCode);
     }
   });
 });

// 서버 인스턴스를 3000번 포트에서 대기하도록 명시
const port = 3000;
app.listen(port, () => console.log(`http://127.0.0.1:${port}/ app listening on port ${3000}`));

 

전체 흐름

index.html : 번역하고 싶은 단어/문장 입력 → app.js : 입력받은 단어/문장 확인되면 데이터 객체를 문자열로 바꿔주고 server.js에 넘김 → server.js : 언어 감지하고 결과를 app.js로 넘겨줌 → app.js : 감지한 언어, 번역할 언어, 번역할 단어/문장을 모아 이 데이터 객체를 문자열로 바꿔주고 sever.js에 넘김 → server.js : 번역한 결과를 app.js로 넘겨줌

 

코드 정리

 

📌

app.js

targetSelect.addEventListener('change', (event) => targetLanguage = event.target.value);

 

 > 번역할 언어에 대한 선택 변화가 있을때마다 이벤트 발생해서 값을 targetLanguage에 넣음

 

index.html (targetSelect 관련 부분)

<select class="w-full h-full p-2 text-xl border-none outline-none resize-none form-select dark:bg-slate-800 dark:text-slate-200" 
	style="width: auto" id="select-box" aria-label="Default select example">
	<option>번역할 언어</option>
	<option value="ko">한국어</option>
	<option value="en" selected>English</option>
	<option value="ja">日本語</option>
</select>

 

 

📌

app.js

let timer;
sourceTextArea.addEventListener('input', (event) => {
    if(timer) clearTimeout(timer);

    timer = setTimeout(() => {

		-----------------------------
        
    }, 2000);

});

 > 번역할 단어/문장 입력(input)될 때 발생하는 이벤트, 입력이 다 끝나고 모아서 번역해주기 위해 clearTimeout() 해주는데 자세한건 DAY7 걍의 내용에,, 

 

index.html (sourceTestArea 관련 부분)

<div class="block h-full p-2 text-base">
	<textarea class="w-full h-full p-2 text-lg outline-none resize-none textarea placeholder:text-black dark:bg-slate-800 dark:text-white dark:placeholder:text-white"
		placeholder="번역할 텍스트를 입력하세요" id="translate-box" autofocus></textarea>
</div>

 

 

📌 app.js

        const text = event.target.value;
        const body = JSON.stringify({ query: text });
        
        // server.js로 비동기 요청 전송
        const xhr = new XMLHttpRequest();
        const xhr2 = new XMLHttpRequest();

        xhr.onload = () => {
        
            ------------------------------
            
            }
        }

        const url = '/detectLangs';
        xhr.open('POST', url);
        
        xhr.setRequestHeader('Content-Type', 'application/json');

        xhr.send(body);

 > onload()는 데이터가 넘어오면 실행되는 부분이라 잠깐 넘기고,, (첨에 잘 모를때는 이게 중간에 있어서 흐름이 더 헷갈렸는데 이걸 마지막으로 순서 옮겨도 제대로 되는지 궁금함 나중에 해봐야겠음)

 > sourceTextArea.addEventListener 라서 event.target.value은 번역하기 위해 쓴 단어/문장을 말하며 이걸 text 변수에 저장한다.

 > { query : "안녕하세요" } 라는 데이터 객체를 서버로 넘길 때는 문자열로 변환해줘야하기 때문에 JSON.stringfy() 를 해주는거고 { "query" : "안녕하세요" } 로 변한 모습이 body에 담긴다

 > 데이터를 넘길 url 지정하고 헤더 정보 설정하고(?) body를 send 통해서 server.js로 넘긴다

 

 

📌 server.js

// 역직렬화용 미들웨어 추가
app.use(express.json());


// localhost:3000/detectLangs로 요청 시 동작할 핸들러
app.post('/detectLangs', function (req, res) {
   const url = 'https://openapi.naver.com/v1/papago/detectLangs';
   const request = require('request');

   const options = {
       url,
       form: req.body,
       headers: {
        'Content-Type': 'application/json',
        'X-Naver-Client-Id':client_id, 
        'X-Naver-Client-Secret': client_secret
      }
    };

   request.post(options, function (error, response, body) {
     if (!error && response.statusCode == 200) {
      res.send(body); // 응답 결과를 app.js로 전달하는 코드
     } else {
       res.status(response.statusCode).end();
       console.log('error = ' + response.statusCode);
     }
   });
 });

 > /detectLangs url로 post 요청을 보냈기 때문에 이 코드가 실행됨
 > req. body = { "query" : "안녕하세요" } 

 > 수행해서 언어 감지한 결과를 app.js로 넘김

 

 

📌 app.js

        xhr.onload = () => {
            if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                const responseData = xhr.responseText; // {langCode: ko}
                const result = JSON.parse(responseData);
                
                const url = '/translate';
                
                let sourceLanguage = result.langCode;
                console.log(sourceLanguage);
                
                const body = JSON.stringify({
                    source: sourceLanguage,
                    target: targetLanguage,
                    text
                });
                
                xhr2.open('POST', url);
                xhr2.onload = () => {
                    
                    ---------------------
                        
                    }
                }

                xhr2.setRequestHeader('Content-Type', 'application/json');
                xhr2.send(body);
            }
        }

 > server.js에서 수행하고 돌아왔으니 onload() 부분 실행하게 됨

 > responseText -> {"langCode" : "ko"} 

 > /translate 서버로 보냄

 > 번역 보내는 정보에 있는 마지막 text도 text : text 이런식이어야 하지 않나 했는데 같은 이름이면 한번만 써도 된다고 함!

 

 

📌server.js

// localhost:3000/translate로 요청 시 동작할 핸들러
app.post('/translate', (req, res) => {
  //  const query = '안녕하세요?';
   const url = 'https://openapi.naver.com/v1/papago/n2mt';
   
   const request = require('request');
   const options = {
       url, // url: url과 같음
      //  form: {'source':'ko', 'target':'en', 'text':query},
      form: req.body,
      headers: {
        'Content-Type': 'application/json',
        'X-Naver-Client-Id':client_id, 
        'X-Naver-Client-Secret': client_secret
      }
    };
    // 실제로 POST 요청 전송 부분
   request.post(options, (error, response, body) => {

     if (!error && response.statusCode == 200) {
      console.log(body);
      res.send(body); // 응답 결과를 app.js로 전달하는 코드
     } else {
       res.status(response.statusCode).end();
       console.log('error = ' + response.statusCode);
     }
   });
 });

 > 수행해서 변역한 결과를 app.js로 넘김

 

 

📌app.js

                xhr2.onload = () => {
                    if (xhr2.readyState === xhr2.DONE && xhr2.status === 200) {
                        const responseData = JSON.parse(xhr2.response); // {translatedText: 'hello', srcLanguage:'ko', tarLanguage: 'en'}
                        console.log(responseData);

                        sourceLanguage = responseData.message.result.srcLangType;
                        targetTextArea.value = responseData.message.result.translatedText;
                                                
                    }
                }

 

 > server.js에서 수행하고 돌아왔으니 onload() 부분 실행하게 됨

 

끝!

 

**

sourceLanguage = responseData.message.result.srcLangType;
targetTextArea.value = responseData.message.result.translatedText;

이거를 간단하게 바꾸려면?

 

 

 

오늘도 느낀건데 개발 잘하는 사람들 머리는 뭔가 다른거 같다,,나도 그렇게 될 수 있는 날이 오길 바란다