서민정

Update Client && Update README.md

### 오픈소스sw개발 개인 프로젝트
## CHATBOT WITH CRAWLING
README referred to [Github](https://github.com/othneildrew/Best-README-Template)
<!-- PROJECT LOGO -->
<br />
<p align="center">
<h3 align="center">SEARCH AND CHAT</h3>
<p align="center">
웹 페이지로 구현된 챗봇과 대화 및 '@'를 이용하여 최신 영상, 정확도 높은 영상, 소식을 카드로 제공합니다.
"http://khuhub.khu.ac.kr/2017103084/oss-chatbot"
<a href="http://khuhub.khu.ac.kr/2017103084/oss-chatbot/">View Demo</a>
·
<a href="http://khuhub.khu.ac.kr/2017103084/oss-chatbot/issues">Report Bug</a>
·
<a href="http://khuhub.khu.ac.kr/2017103084/oss-chatbot/merge_requests">Request Feature</a>
</p>
</p>
<!-- TABLE OF CONTENTS -->
## Table of Contents
* [About the Project](#about-the-project)
* [Built With](#built-with)
* [Getting Started](#getting-started)
* [Prerequisites](#prerequisites)
* [Installation](#installation)
* [Usage](#usage)
* [Roadmap](#roadmap)
* [Contributing](#contributing)
* [License](#license)
* [Contact](#contact)
* [Acknowledgements](#acknowledgements)
<!-- ABOUT THE PROJECT -->
## About The Project
[![Product Name Screen Shot](./projectScreenShot.PNG)
카카오톡, 라인 등에서 제공하는 챗봇 어플리케이션과 같이 웹에서도 작동할 수 있는 챗봇을 만들어, 웹 사용자들과 대화할 수 있는 봇을 만들고 싶어 이 프로젝트를 진행하게 되었습니다. 간단한 대화와 더불어 좋아하는 가수, 또는 배우 등의 이름과 함께 검색어를 입력하면 봇이 대신 정보를 가져와주는 편의성을 더하였습니다.
### Built With
* [Nodejs](https://nodejs.org/en/)
* [React](https://ko.reactjs.org/)
* [Google Cloud API](https://cloud.google.com/apis)
* [Dialogflow API](https://dialogflow.cloud.google.com/)
<!-- GETTING STARTED -->
## Getting Started
로컬 컴퓨터에서 실행시킬 수 있는 방법입니다.
### Prerequisites
먼저, 이 프로젝트를 실행시키기 위해 필요한 요구사항입니다.
* Node
[Official Node.js Website](https://nodejs.org/)에서 Node.js를 설치합니다.
또한 `npm` 의 설치도 필요합니다.
### Installation
1. 이 리포지토리를 Clone 합니다.
```sh
git clone http://khuhub.khu.ac.kr/2017103084/oss-chatbot/
```
2. root 폴더와 client 폴더에서 아래 명령을 실행합니다.
```sh
npm install
```
3. [Google Developers](https://console.developers.google.com/project)에서 프로젝트를 생성한 뒤, API 키를 발급 받습니다. 이 때, 프로젝트 명(ID)과 API 키의 json 파일이 필요합니다.
4. [Dialogflow](https://dialogflow.cloud.google.com/)에서 에이전트를 생성합니다. 이 때, GOOGLE PROJECT 탭의 Project ID는 앞서 (3)에서 생성한 프로젝트의 ID를 선택합니다.
5. root 폴더에 .env 파일을 생성한 뒤, 아래 내용을 채워 넣습니다.
```
googleProjectID = (3)에서 생성한 구글 프로젝트 ID
dialogFlowSessionID = bot-session #원하는 것으로 입력.
dialogFlowSessionLanguageCode = Dialogflow 에이전트 생성 시 설정한 언어 코드 (ex. 한글일 경우에는 "ko" 입니다.)
googleClientEmail = 구글 프로젝트 생성 시 제공되는 이메일 (ex. [프로젝트 명]@[프로젝트명 2].iam.gserviceaccount.com)
```
6. **중요** 로컬에서 실행하는 경우에는 root의 package.json 중 "@google-cloud/storage": "^5.0.1" 를 지웁니다. 이 패키지는 herokuapp에서 GOOGLE_APPLICATION_CREDENTIALS를 활용하기 위해 설치되어있는 패키지입니다.
7. 모두 완료 되었다면, 아래 명령어를 입력하여 클라이언트와 서버를 모두 실행시킬 수 있습니다.
```
npm run dev
```
<!-- USAGE EXAMPLES -->
## Usage
해당 프로젝트의 실제 동작 화면은 [SEARCH-AND-CHAT](https://search-and-chat.herokuapp.com/)에서 확인하실 수 있습니다.
React 의 특성 상 뒤로가기 및 Reload 시 오류가 발생할 수 있습니다. 이 때는 아래 URL로 재접속하시면 원활히 사용하실 수 있습니다. 또한 heroku 로 빌드되어 사용이 없는 경우에는 첫 접속 시 로딩 시간이 걸릴 수 있습니다. 조금만 기다려주시면 프로젝트가 실행될 것입니다 😊
* URL : <https://search-and-chat.herokuapp.com/>
<!-- CONTRIBUTING -->
## Contributing
이 프로젝트를 더욱 발전시키고 싶으신 분들은 아래와 같은 절차를 따라주세요!
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the Branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request
<!-- CONTACT -->
## Contact
프로젝트에 문제가 있거나 궁금하신 사항은 아래 메일로 연락주세요.
* Email : <mathmjseo@khu.ac.kr>
-readme 수정하기
-로그인 시 페이지렌더링 안됨 ..... 수정하기
......
......@@ -8,18 +8,13 @@ import Card from "./Sections/Card";
import CheckString from './Check';
import { text } from 'body-parser';
let userKeyword = "";
let userName = "유저";
let autoSearch = 0;
if(sessionStorage.length){
userKeyword = sessionStorage.getItem("Now_userKeyword");
userName = sessionStorage.getItem("Now_userName");
autoSearch = 1;
sessionStorage.clear();
}
function Chatbot() {
function Chatbot(props) {
console.log("실행")
var userName = props.userName;
var userKeyword = props.userKeyword;
var autoSearch = props.autoSearch;
console.log("이름",userName);
console.log("키워드",userKeyword);
......@@ -32,6 +27,22 @@ function Chatbot() {
}, [])
if(autoSearch){
useEffect(() => {
console.log("I am in autoSearch!!");
setTimeout(function(){
eventQuery('008_AutoSearch');
}, 500);
setTimeout(function(){
textQuery(`@${userKeyword}_최신`);
textQuery(`@${userKeyword}_정확도`);
textQuery(`@${userKeyword}_소식`);
}, 1000);
}, [])
}
const textQuery = async (text) => {
// First Need to take care of the message I sent
let conversation = {
......@@ -147,20 +158,14 @@ function Chatbot() {
}
if(autoSearch === 1){
setTimeout(function(){
eventQuery('008_AutoSearch');
}, 500);
// if(autoSearch === 1){
setTimeout(function(){
textQuery(`@${userKeyword}_최신`);
textQuery(`@${userKeyword}_정확도`);
textQuery(`@${userKeyword}_소식`);
}, 1000);
autoSearch = 0;
console.log("I am in autoSearch!!");
}
// autoSearch = 0;
// console.log("I am in autoSearch!!");
// }
const keyPressHanlder = (e) => {
......
......@@ -3,16 +3,29 @@ import { Typography, Icon } from 'antd';
import Chatbot from '../Chatbot/Chatbot';
import { withRouter } from "react-router-dom";
const { Title } = Typography;
let userKeyword = "";
let userName = "유저";
let autoSearch = 0;
console.log("챗페이지 밖");
function chatpage() {
console.log("챗페이지 안")
if(sessionStorage.length === 2){
console.log("세션스토리지 안")
userKeyword = sessionStorage.getItem("Now_userKeyword");
userName = sessionStorage.getItem("Now_userName");
sessionStorage.clear();
autoSearch = 1;
}
return (
<div>
<div style={{ display: 'flex', justifyContent: 'center', marginTop: '1rem' }}>
<Title level={2} >CHATBOT&nbsp;<Icon type="robot" /></Title>
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Chatbot />
<Chatbot userName = {userName} userKeyword = {userKeyword} autoSearch = {autoSearch}/>
</div>
</div>
)
......
......@@ -6,10 +6,13 @@ import Axios from 'axios';
const { Title } = Typography;
console.log("start");
let url = "/";
const userInfo = async (info) => {
async function userInfo(){
const email = document.getElementById('email').value;
const pw = document.getElementById('password').value;
if(email && pw){
const userVariables = {
email,
......@@ -18,6 +21,7 @@ const userInfo = async (info) => {
const response = await Axios.post('/api/login/userInfo', userVariables);
if(response.data !== 'FAIL'){
url = "/chat";
// loginForm.action = `/chat?${response.data}`;
// loginForm.submit();
var keyword = response.data.keyword;
......@@ -25,14 +29,16 @@ const userInfo = async (info) => {
sessionStorage.setItem("Now_userKeyword", keyword);
sessionStorage.setItem("Now_userName", name);
window.history.replaceState('login','','/chat');
window.history.go();
// window.history.replaceState('login','','/chat');
// window.history.go();
// window.location.href = "/chat";
} else{
url = "/";
alert("입력하신 정보와 일치하는 회원이 존재하지 않습니다 😥");
}
}
else{
url = "/";
alert("이메일과 패스워드를 입력해주세요!");
}
}
......@@ -67,9 +73,11 @@ function loginpage() {
<Form.Item>
<div>
<Button type="primary" className="login-form-button" style={{ minWidth: '100%' }} onClick={userInfo}>
Log in
</Button>
<Link to= {`${url}`} onClick= {userInfo} name = "loginLink">
<Button type="primary" className="login-form-button" style={{ minWidth: '100%' }}>
Log in
</Button>
</Link>
</div>
<Link to ="/register">가입하기</Link> Or <Link to = "/chat">비회원으로 사용하기</Link>
</Form.Item>
......
1. dialogflow로 기본 기능 구현
2. React로 프론트엔드 구현
3. routing으로 @가수명 입력하면 해당 라우팅(크롤링) 함수로 들어가게 구현
4. 크롤링 구현 (네이버TV 최신 영상 3개 json으로 가져오기)
5. json파일 카드로 넘겨주기
---
검색결과가 없을 때 -> 다시 dialogflow 라우터로 넘겨줘서 무슨 말인지 이해하지 못했어요
관련 영상이 3가지 미만일 때 -> 없다고 판단함.
---
node 서버: localhost: 5000
프론트엔드/ localhost: 3000
---- 정리
리덕스 참고: https://velopert.com/3528
dialogflow
화자의 의도 intent ,사용자가 말하는 것과 dialogflow가 수행해야할 작업간의 매핑을 나타내는 것.
fallback intent : 사용자의 대화가 어떤 intent 와도 매칭되지 않을 때 선택되어지는 intent
화자의 속성 entity
ex. 내일 오후 2시 되나요? 에서 '내일', '오후 2시'를 파라미터로 뽑아내는 것.
문맥 context
내일 오후 2시 되나요? 에서 무엇을 위한 내일 오후 2시인가를 파악하기 위해서 그 전에 대화가 되었던 '수리'라는 것을 기억하는 것을 의미함
uuid 제대로 이해하고 다시 작성하기
-----
001 - welcome
002 - 인사
003 - @'가수명'
-> 해당 가수명으로 크롤링을 했을 때 null이 3개이상 나오면 가수명이 없다고 판단함.
-> 만약 가수가 아니더라도 크롤링 시 해당되는 내용이 3개 이상 나오면 해당 내용을 리턴함.
-----