박진수

Merge branch 'integration' into 'master'

1차 Integration

1차적으로 integration해서 테스트해봤습니다. 시험 앞두고 개발하느라 고생이 많습니다 모두
개인적으로 핸드폰으로 방송을 켜서 확인해본 결과 아주 1차적인 목표였던 번역과 번역 후 말하기 기능은 동작했습니다.

개선해야할 사항은 

* 번역한 텍스트만 `chat message` 이벤트를 emit하도록 설정. 일반 텍스트나 번역 전의 텍스트는 필요하지 않을 듯합니다.
* backend 설정 유연하게. server의 README.md에 잘못 표기된 내용이나 오타가 많습니다. 그리고 .env에서도 필요 없는 환경변수는 없애거나 혹시 모를 용도를 표기해주셨으면 합니다.
* **frontend와 backend의 oauth 로그인 설정**. 이 설정이 되어야 백엔드에서도 인증 처리를 한 뒤 청취 가능한 채널 목록을 관리할 수 있을 것 같습니다.
* backend에서 `/channels` channel list api, frontend에서 해당 api를 이용해 채널 리스트 업데이트 기능이 추가되어야할 것 같습니다.

See merge request !11
...@@ -21,3 +21,4 @@ ...@@ -21,3 +21,4 @@
21 npm-debug.log* 21 npm-debug.log*
22 yarn-debug.log* 22 yarn-debug.log*
23 yarn-error.log* 23 yarn-error.log*
24 +.eslintcache
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -40,7 +40,7 @@ khuwitch는 크게 아래의 항목들로 동작한다고 볼 수 있습니다. ...@@ -40,7 +40,7 @@ khuwitch는 크게 아래의 항목들로 동작한다고 볼 수 있습니다.
40 **frontend** 40 **frontend**
41 41
42 ```bash 42 ```bash
43 -$ KHUWITCH_PORT=8000 npm start 43 +$ PORT=8000 npm start
44 ``` 44 ```
45 45
46 **backend** 46 **backend**
......
This diff could not be displayed because it is too large.
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
8 "@testing-library/jest-dom": "^5.11.4", 8 "@testing-library/jest-dom": "^5.11.4",
9 "@testing-library/react": "^11.1.0", 9 "@testing-library/react": "^11.1.0",
10 "@testing-library/user-event": "^12.1.10", 10 "@testing-library/user-event": "^12.1.10",
11 + "aws-sdk": "^2.804.0",
11 "react": "^17.0.1", 12 "react": "^17.0.1",
12 "react-dom": "^17.0.1", 13 "react-dom": "^17.0.1",
13 "react-scripts": "4.0.1", 14 "react-scripts": "4.0.1",
15 + "socket.io-client": "^3.0.3",
14 "web-vitals": "^0.2.4" 16 "web-vitals": "^0.2.4"
15 }, 17 },
16 "scripts": { 18 "scripts": {
......
...@@ -5,6 +5,31 @@ import PersonIcon from "@material-ui/icons/Person"; ...@@ -5,6 +5,31 @@ import PersonIcon from "@material-ui/icons/Person";
5 import PlayArrowIcon from '@material-ui/icons/PlayArrow'; 5 import PlayArrowIcon from '@material-ui/icons/PlayArrow';
6 import PauseIcon from '@material-ui/icons/Pause'; 6 import PauseIcon from '@material-ui/icons/Pause';
7 import { WatchOutlined } from "@material-ui/icons"; 7 import { WatchOutlined } from "@material-ui/icons";
8 +import io from 'socket.io-client'
9 +import tts from './tts';
10 +
11 +const socket = io.connect("http://localhost:3000")
12 +socket.on("connect", event=>{
13 + // 테스트용으로 umi0410에게 입장.
14 + // 다른 거 아무거나 채널이름을 넣으면 되겠지만, 그렇게 하고싶으면 백엔드에서 인자설정을 해줘야함.
15 + socket.emit("joinRoom", 'umi0410', '진수봇')
16 +})
17 +
18 +// 말해야할 메시지가 왔을 때. 이건 따로 Component와 묶지 않아도 알아서 실행됩니다.
19 +socket.on('chat message', (name, msg)=>{
20 + console.log(msg)
21 + tts.speak(msg)
22 +})
23 +
24 +// 해당 채널을 재생하고자할 때 실행시켜주세요.
25 +const listen = (channelName)=>{
26 + socket.emit("joinRoom", channelName, "dummy name") // name이 뭔지 대연이도 잘 모름.
27 +}
28 +
29 +// 해당 채널을 재생 안하도록 할 때 실행시켜주세요.
30 +const quit = (channelName)=>{
31 + socket.emit("leaveRoom". channelName, "dummy name") // name이 뭔지 대연이도 잘 모름.
32 +}
8 33
9 export function Channel(props) { 34 export function Channel(props) {
10 const channel = props.channel; 35 const channel = props.channel;
...@@ -34,6 +59,7 @@ export class ChannelList extends React.Component { ...@@ -34,6 +59,7 @@ export class ChannelList extends React.Component {
34 59
35 // data for test 60 // data for test
36 const test = [ 61 const test = [
62 + {"name": "umi0410 진수", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv/umi0410"},
37 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, 63 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"},
38 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, 64 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"},
39 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, 65 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"},
...@@ -44,6 +70,7 @@ export class ChannelList extends React.Component { ...@@ -44,6 +70,7 @@ export class ChannelList extends React.Component {
44 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, 70 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"},
45 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"}, 71 {"name": "name1", "view": 999, "game": "game1" ,"url": "https://www.twitch.tv", "thumbnail": "https://upload.wikimedia.org/wikipedia/commons/2/26/Twitch_logo.svg"},
46 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"}, 72 {"name": "name2", "view": 123124124, "game": "game2" , "url": "https://www.twitch.tv"},
73 +
47 ] 74 ]
48 75
49 this.state = { 76 this.state = {
......
1 +import AWS from 'aws-sdk'
2 +// Polly를 사용하기 위한 자격증명을 설정한다.
3 +AWS.config.region = 'ap-northeast-2';
4 +AWS.config.credentials = new AWS.CognitoIdentityCredentials({IdentityPoolId: 'ap-northeast-2:03db97c9-a857-45f3-be6e-3cf84d6f619b'});
5 +const polly = new AWS.Polly({
6 + signatureVersion: 'v4',
7 + region: 'ap-northeast-2',
8 +});
9 +
10 +function speak(text){
11 + let params = {
12 + 'Text': text,
13 + 'OutputFormat': 'mp3',
14 + 'VoiceId': 'Seoyeon'
15 + };
16 + let tts = new AWS.Polly.Presigner(params, polly)
17 +
18 + // tts로 변환한 음성 파일을 얻는다.
19 + tts.getSynthesizeSpeechUrl(params, function(error, url) {
20 + if (error) {
21 + } else {
22 + setTimeout(()=>{
23 + console.log("실행")
24 + let audio = new Audio(url)
25 + audio.play()
26 + // .then(delete audio);
27 + }, 3000)
28 + }
29 + })
30 +}
31 +export default {
32 + "speak": speak,
33 +}
File mode changed
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 25
26 ```bash 26 ```bash
27 $cd server 27 $cd server
28 - $npm install pkg.json --save 28 + $npm install
29 $npm start 29 $npm start
30 ``` 30 ```
31 31
......
1 -// const tmi = require('tmi.js'); 1 +const tmi = require('tmi.js');
2 -// const papago = require('./openAPIs/papago_api') 2 +const papago = require('./openAPIs/papago_api')
3 -// const ttlserver = require('../socket_server') 3 +const ttlserver = require('../socket_server')
4 - 4 +
5 -// // Define configuration options 5 +// Define configuration options
6 -// var opts = { 6 +var opts = {
7 -// identity: { 7 + identity: {
8 -// username: process.env.BOT_USERNAME, 8 + username: process.env.BOT_USERNAME,
9 -// password: process.env.OAUTH_TOKEN 9 + password: process.env.OAUTH_TOKEN
10 -// }, 10 + },
11 -// channels: [ 11 + channels: [
12 -// 'bachelorchuckchuck' 12 + 'bachelorchuckchuck'
13 -// ] 13 + ]
14 -// }; 14 +};
15 - 15 +
16 -// // Create a client with our options 16 +// Create a client with our options
17 -// const client = new tmi.client(opts); 17 +const client = new tmi.client(opts);
18 - 18 +
19 -// // Register our event handlers (defined below) 19 +// Register our event handlers (defined below)
20 -// client.on('message', onMessageHandler); 20 +client.on('message', onMessageHandler);
21 -// client.on('connected', onConnectedHandler); 21 +client.on('connected', onConnectedHandler);
22 - 22 +
23 -// // Connect to Twitch: 23 +// Connect to Twitch:
24 -// client.connect(); 24 +client.connect();
25 - 25 +
26 -// // Called every time a message comes in 26 +// Called every time a message comes in
27 -// function onMessageHandler (target, context, msg, self) { 27 +function onMessageHandler (target, context, msg, self) {
28 -// if (self) { return; } // Ignore messages from the bot 28 + if (self) { return; } // Ignore messages from the bot
29 29
30 -// client.say(target, `/color `+changecolor()); 30 + client.say(target, `/color `+changecolor());
31 -// papago.detectchat(msg, client, target); 31 + papago.detectchat(msg, client, target);
32 32
33 -// if(msg == '척척학사'){ 33 + if(msg == '척척학사'){
34 -// client.say(target, `안녕하세요 척척학사의 방송입니다.`); 34 + client.say(target, `안녕하세요 척척학사의 방송입니다.`);
35 -// } 35 + }
36 36
37 -// } 37 +}
38 38
39 -// exports.addChannel = (channel) =>{ 39 +exports.addChannel = (channel) =>{
40 -// opts.channels.append(channel); 40 + opts.channels.append(channel);
41 -// } 41 +}
42 42
43 -// // Called every time the bot connects to Twitch chat 43 +// Called every time the bot connects to Twitch chat
44 -// function onConnectedHandler (addr, port) { 44 +function onConnectedHandler (addr, port) {
45 -// console.log(`* Connected to ${addr}:${port}`); 45 + console.log(`* Connected to ${addr}:${port}`);
46 -// } 46 +}
......
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
4 "description": "twitch translator chatbot & tts server dev", 4 "description": "twitch translator chatbot & tts server dev",
5 "main": "socket_server.js", 5 "main": "socket_server.js",
6 "scripts": { 6 "scripts": {
7 + "start": "node socket_server.js",
7 "test": "echo \"Error: no test specified\" && exit 1" 8 "test": "echo \"Error: no test specified\" && exit 1"
8 }, 9 },
9 "author": "Daeyeonkim97", 10 "author": "Daeyeonkim97",
10 "license": "ISC", 11 "license": "ISC",
11 "dependencies": { 12 "dependencies": {
13 + "cors": "^2.8.5",
12 "dotenv": "^8.2.0", 14 "dotenv": "^8.2.0",
13 "ejs": "^3.1.5", 15 "ejs": "^3.1.5",
14 "express": "^4.17.1", 16 "express": "^4.17.1",
......
1 const config = require('./config/config') 1 const config = require('./config/config')
2 2
3 const app = require('express')(); 3 const app = require('express')();
4 +const cors = require('cors')
5 +app.use(cors()) //express 기본 응답에 대한 cors
4 const http = require('http').Server(app); 6 const http = require('http').Server(app);
5 -const io = require('socket.io')(http); 7 +const io = require('socket.io')(http, {
8 + cors:{
9 + origin: "*",
10 + }
11 +});
6 const papago = require('./openAPIs/papago_api'); 12 const papago = require('./openAPIs/papago_api');
7 13
8 const tmi = require('tmi.js'); 14 const tmi = require('tmi.js');
......