이유혁

Add comment

...@@ -2,7 +2,6 @@ const express = require('express'); ...@@ -2,7 +2,6 @@ const express = require('express');
2 const config = require('./API_config'); 2 const config = require('./API_config');
3 const line = require('@line/bot-sdk'); 3 const line = require('@line/bot-sdk');
4 const request = require('request'); 4 const request = require('request');
5 -
6 const app = express(); 5 const app = express();
7 6
8 //번역 api_url 7 //번역 api_url
...@@ -11,6 +10,15 @@ const translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt'; ...@@ -11,6 +10,15 @@ const translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt';
11 //언어감지 api_url 10 //언어감지 api_url
12 const languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs'; 11 const languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs';
13 12
13 +// API_config.js 의 형태는 다음과 같다.
14 +// const client_id = 'xxxx';
15 +// const client_secret = 'xxxx';
16 +
17 +// const line_channel = {
18 +// channelAccessToken: 'xxxx',
19 +// channelSecret: 'xxxx',
20 +// };
21 +
14 // Naver Auth Key 22 // Naver Auth Key
15 //새로 발급받은 naver papago api id, pw 입력 23 //새로 발급받은 naver papago api id, pw 입력
16 const client_id = config.client_id; 24 const client_id = config.client_id;
...@@ -30,15 +38,19 @@ app.get('/', (req, res) => { ...@@ -30,15 +38,19 @@ app.get('/', (req, res) => {
30 38
31 // register a webhook handler with middleware 39 // register a webhook handler with middleware
32 app.post('/webhook', line.middleware(line_channel), (req, res) => { 40 app.post('/webhook', line.middleware(line_channel), (req, res) => {
33 - // webhook post 요청에 대해 promises를 전체 수행한다. 41 + // webhook 요청에 대해 순차적으로 다음을 수행한다.
34 // 전체 수행은 순차수행이기 때문에 동기처리 필요 => async await 패턴을 사용한다 42 // 전체 수행은 순차수행이기 때문에 동기처리 필요 => async await 패턴을 사용한다
35 const promises = req.body.events.map(async (event) => { 43 const promises = req.body.events.map(async (event) => {
44 + // 메세지의 속성을 확인하고 API connector를 만든다
36 let api_connector = await api_connect(event); 45 let api_connector = await api_connect(event);
46 + // connector를 통해 언어 감지, 번역 target 언어를 설정한다
37 let options = await option_maker(api_connector, event); 47 let options = await option_maker(api_connector, event);
48 + // 설정된 source 및 target으로 번역 결과를 저장한다
38 let result = await receive_result(options, event); 49 let result = await receive_result(options, event);
50 + // 모든 작업이 끝나면 client api를 통해 reply를 진행한다.
39 client.replyMessage(event.replyToken,result); 51 client.replyMessage(event.replyToken,result);
40 }) 52 })
41 - Promise 53 + Promise // promise all은 일괄 수행이 완료될 때 then이 수행된다
42 .all(promises) 54 .all(promises)
43 .then((result) => res.json(result)) 55 .then((result) => res.json(result))
44 .catch((err) => { 56 .catch((err) => {
...@@ -47,14 +59,15 @@ app.post('/webhook', line.middleware(line_channel), (req, res) => { ...@@ -47,14 +59,15 @@ app.post('/webhook', line.middleware(line_channel), (req, res) => {
47 }); 59 });
48 }); 60 });
49 61
50 -// 이벤트 타입 검사 이후
51 // language detector api url 및 client id, secret 을 담은 connector를 반환한다. 62 // language detector api url 및 client id, secret 을 담은 connector를 반환한다.
52 const api_connect = (event) => { 63 const api_connect = (event) => {
53 return new Promise((resolve, reject) => { 64 return new Promise((resolve, reject) => {
65 + // 이벤트 타입 검사
54 if (event.type !== 'message' || event.message.type !== 'text'){ 66 if (event.type !== 'message' || event.message.type !== 'text'){
55 - //언어 감지 option 67 + // 비정상에 대한 reject 처리
56 reject(new Error('메세지 혹은, 텍스트가 아닙니다.')); 68 reject(new Error('메세지 혹은, 텍스트가 아닙니다.'));
57 } else { 69 } else {
70 + // 정상요청에 대한 connector 생성 및 resolve
58 resolve({ 71 resolve({
59 url : languagedetect_api_url, 72 url : languagedetect_api_url,
60 form : {'query': event.message.text}, 73 form : {'query': event.message.text},
...@@ -74,7 +87,6 @@ const option_maker = (api_connector, event) => { ...@@ -74,7 +87,6 @@ const option_maker = (api_connector, event) => {
74 let detect_body = JSON.parse(response.body); 87 let detect_body = JSON.parse(response.body);
75 //언어 감지가 제대로 됐는지 확인 88 //언어 감지가 제대로 됐는지 확인
76 console.log(detect_body.langCode); 89 console.log(detect_body.langCode);
77 -
78 // 3.zh-CN : 중국어 간체 90 // 3.zh-CN : 중국어 간체
79 // 4.zh-TW : 중국어 번체 91 // 4.zh-TW : 중국어 번체
80 // 5.es : 스페인어 92 // 5.es : 스페인어
...@@ -116,16 +128,22 @@ const option_maker = (api_connector, event) => { ...@@ -116,16 +128,22 @@ const option_maker = (api_connector, event) => {
116 checker = false; 128 checker = false;
117 target = 'ko'; 129 target = 'ko';
118 } 130 }
131 + // 전송된 메세지가 한국어일 경우 default target은 영어이며 설정에 따라 바뀐다.
132 + // 전송된 메세지가 한국어가 아닐 경우 모든 target language는 한국어가 된다.
119 133
120 let options = {} 134 let options = {}
135 + // checker란 언어 번역시 옵션의 존재 유뮤이다. 사용자가 영어가 아닌 다른 언어의 번역을 원할 경우
136 + // 뒤에 옵션 .xx 가 붙게 되며 checker 는 true가 된다.
121 if (checker) 137 if (checker)
122 { 138 {
123 options = { 139 options = {
124 url: translate_api_url, 140 url: translate_api_url,
141 + // checker가 true이면 메세지 끝에 옵션이 붙기 때문에 번역시 이를 무시할 필요가 있다.
125 form: {'source':detect_body.langCode, 'target': target, 'text':event.message.text.slice(0,-3)}, 142 form: {'source':detect_body.langCode, 'target': target, 'text':event.message.text.slice(0,-3)},
126 headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret} 143 headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret}
127 }; 144 };
128 } 145 }
146 + // 기타 옵션 없는 한 -> 영, 외국어 -> 한글 번역은 checker false
129 else{ 147 else{
130 options = { 148 options = {
131 url: translate_api_url, 149 url: translate_api_url,
...@@ -133,11 +151,12 @@ const option_maker = (api_connector, event) => { ...@@ -133,11 +151,12 @@ const option_maker = (api_connector, event) => {
133 headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret} 151 headers: {'X-Naver-Client-Id': client_id, 'X-Naver-Client-Secret': client_secret}
134 } 152 }
135 } 153 }
154 + // 모든 번역 준비를 마친 options 를 resolve 한다
136 resolve(options); 155 resolve(options);
137 } 156 }
138 else{ 157 else{
139 - // 예외처리 158 + // language detection에 대한 예외 reject
140 - reject(new Error("request is failed")); 159 + reject(new Error("언어 감지 실패"));
141 } 160 }
142 }) 161 })
143 }) 162 })
...@@ -148,6 +167,7 @@ const option_maker = (api_connector, event) => { ...@@ -148,6 +167,7 @@ const option_maker = (api_connector, event) => {
148 const receive_result = (options, event) => { 167 const receive_result = (options, event) => {
149 return new Promise((resolve, reject) => { 168 return new Promise((resolve, reject) => {
150 var result = { type:'text', text: ''}; 169 var result = { type:'text', text: ''};
170 + // 번역에 관련된 options 객체를 번역 API로 post요청
151 request.post(options, (error, response) => { 171 request.post(options, (error, response) => {
152 // Translate API Sucess 172 // Translate API Sucess
153 if(!error && response.statusCode == 200){ 173 if(!error && response.statusCode == 200){
...@@ -159,17 +179,16 @@ const receive_result = (options, event) => { ...@@ -159,17 +179,16 @@ const receive_result = (options, event) => {
159 resolve(result); 179 resolve(result);
160 } 180 }
161 else{ 181 else{
162 - // 예외처리 182 + // 번역 정상적으로 불가능시 reject 처리
163 - result.text = '언어를 감지할 수 없습니다.'; 183 + result.text = '번역할 수 없는 언어입니다.';
164 client.replyMessage(event.replyToken,result); 184 client.replyMessage(event.replyToken,result);
165 - reject(new Error("language was not detected")); 185 + reject(new Error("번역 실패"));
166 } 186 }
167 }) 187 })
168 }) 188 })
169 } 189 }
170 190
191 +// app running
171 app.listen(3000, function () { 192 app.listen(3000, function () {
172 console.log('Linebot listening on port 3000!'); 193 console.log('Linebot listening on port 3000!');
173 -}); 194 +});
174 -
175 -// 무조건 3글자 자르면 짧은글 씹힌다
...\ No newline at end of file ...\ No newline at end of file
......