전언석
1 +var express = require('express');
2 +const request = require('request');
3 +const TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
4 +const TOKEN = ''
5 +const fs = require('fs');
6 +const path = require('path');
7 +const HTTPS = require('https');
8 +const domain = "2019102226.osschatbot2022.ml"
9 +const sslport = 23023;
10 +
11 +
12 +
13 +const bodyParser = require('body-parser');
14 +var app = express();
15 +app.use(bodyParser.json());
16 +app.post('/hook', function (req, res) {
17 +
18 + var eventObj = req.body.events[0];
19 + var source = eventObj.source;
20 + var message = eventObj.message;
21 +
22 + // request log
23 + console.log('======================', new Date(), '======================');
24 + // mwsql
25 + var mysql = require('mysql');
26 + var db = mysql.createConnection({
27 + host: 'chatbot.c7fzgftc3yrm.us-east-1.rds.amazonaws.com',
28 + user: 'chatbot',
29 + password: '',
30 + database: 'chatbot',
31 + port: '3306'
32 + });
33 +
34 + db.connect();
35 +
36 + db.query('SELECT * FROM data', function (error, results, fields) {
37 + if (error) {
38 + console.log(error);
39 + }
40 + var arr = new Array();
41 + var input_ingredients_list = message.text.split(" ");
42 + for (var i = 0; i < results.length; i++) {
43 + var ingredients_list = results[i].ingredients.split(", ");
44 + if (ingredients_list.filter(x => input_ingredients_list.includes(x)).length === input_ingredients_list.length) {
45 + arr.push(i);
46 + }
47 + }
48 + if (arr.length != 0) {
49 + var num = arr[Math.floor(Math.random() * arr.length)];
50 + request.post(
51 + {
52 + url: TARGET_URL,
53 + headers: {
54 + 'Authorization': `Bearer ${TOKEN}`
55 + },
56 + json: {
57 + "replyToken": eventObj.replyToken,
58 + "messages": [
59 + {
60 + "type": "text",
61 + "text": `메뉴는 "${results[[num]].menu}" 입니다.`
62 + },
63 + {
64 + "type": "text",
65 + "text": `필요한 재료는\n\n"${results[[num]].ingredients}"\n\n입니다.`
66 + },
67 + {
68 + "type": "text",
69 + "text": `레시피\n\n${results[[num]].recipe}`
70 + }
71 + ]
72 + }
73 + }, (error, response, body) => {
74 + console.log(body)
75 + });
76 + }
77 + else {
78 + request.post(
79 + {
80 + url: TARGET_URL,
81 + headers: {
82 + 'Authorization': `Bearer ${TOKEN}`
83 + },
84 + json: {
85 + "replyToken": eventObj.replyToken,
86 + "messages": [
87 + {
88 + "type": "text",
89 + "text": `재료를 다시 입력해주세요.`
90 + }
91 + ]
92 + }
93 + }, (error, response, body) => {
94 + console.log(body)
95 + });
96 + }
97 + });
98 +
99 + db.end();
100 + res.sendStatus(200);
101 +});
102 +
103 +try {
104 + const option = {
105 + ca: fs.readFileSync('/etc/letsencrypt/live/' + domain + '/fullchain.pem'),
106 + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(),
107 + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(),
108 + };
109 +
110 + HTTPS.createServer(option, app).listen(sslport, () => {
111 + console.log(`[HTTPS] Server is started on port ${sslport}`);
112 + });
113 +} catch (error) {
114 + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
115 + console.log(error);
116 +}
117 +
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
12 <li><a href="#설명">설명</a></li> 12 <li><a href="#설명">설명</a></li>
13 <li><a href="#사용기술">사용기술</a></li> 13 <li><a href="#사용기술">사용기술</a></li>
14 <li><a href="#사용법">사용법</a></li> 14 <li><a href="#사용법">사용법</a></li>
15 - <li><a href="#구조">구조</a></li>
16 <li><a href="#진행정도">진행정도</a></li> 15 <li><a href="#진행정도">진행정도</a></li>
17 <li><a href="#만든사람">만든사람</a></li> 16 <li><a href="#만든사람">만든사람</a></li>
18 </ol> 17 </ol>
...@@ -30,6 +29,7 @@ ...@@ -30,6 +29,7 @@
30 * Express 29 * Express
31 * web crawling 30 * web crawling
32 * MySQL 31 * MySQL
32 +<img src="/images/chatbot_structure.jpg">
33 33
34 --- 34 ---
35 ### 사용법 35 ### 사용법
...@@ -39,13 +39,60 @@ ...@@ -39,13 +39,60 @@
39 <img src="/images/add_channel_info.png" width="450px" height="300px"> 39 <img src="/images/add_channel_info.png" width="450px" height="300px">
40 <br> 40 <br>
41 * 개발자 41 * 개발자
42 - 42 +<p>1. Clone repository</p>
43 - 43 +<p>터미널을 열고 다음을 입력</p>
44 - 44 +```git clone http://khuhub.khu.ac.kr/2019102197/Ingredient-to-Dish-ChatBot.git
45 ---- 45 +```
46 -### 구조 46 +<br>
47 -<p></p> 47 +<p>2. Node.js download</p>
48 - 48 +<p>터미널을 열고 다음을 입력</p>
49 +```npm install
50 +```
51 +<br>
52 +<p>3. AWS RDS 사용법</p>
53 +<p>AWS RDS 선택</p>
54 +<p>데이터베이스 생성</p>
55 +<p>-엔진 옵션 Amazon Aurora -> MySQL</p>
56 +<p>-사용자 이름, 암호 생성 후 기억</p>
57 +<p>-퍼블릭 액세스 아니요 -> 예</p>
58 +<p>파라미터 그룹 선택 -> 파라미터 그룹 생성</p>
59 +<p>생성된 파리미터 그룹 선택 -> 파라미터 편집</p>
60 +<p>-char 검색 -> 모든 파라미터 값 utf8로 변경</p>
61 +<p>-collation 검색 -> 모든 파라미터 값 utf8로 변경</p>
62 +<p>RDS 인스턴스 수정에서 DB 파라미터 그룹 방금 생성한 파라미터 그룹으로 바꾸기></p>
63 +<p>EC2 보안 그룹 ID 복사</p>
64 +<p>RDS의 VPC 보안 그룹 들어가서 인바운드 규칙 수정</p>
65 +<p>규칙 추가 후 유형 MYSQL/Aurora로 변경</p>
66 +<p>소스에 보안 그룹 ID 붙여넣기</p>
67 +<p>규칙 추가 하나 더 한 후 유형 MYSQL/Aurora로 변경</p>
68 +<p>소스 유형에 내IP 선택</p>
69 +<p>규칙 저장 후 MYSQL workbench 실행 후</p>
70 +<p>새 DATABASE 생성</p>
71 +<p>주소는 RDS의 엔드포인트를 복사 붙여넣기 해줌</p>
72 +<br>
73 +<p>4. csv 파일 연결</p>
74 +<p>MySQL Workbench에서 새로운 MySQL Connections 생성</p>
75 +<p>RDS 설정에서 생성한 Hostname, 사용자 이름과 비밀번호를 입력</p>
76 +<br>
77 +<p>5. 토큰, 도메인 등등 값 수정</p>
78 +<p>reply.js에서 토큰, 도메인 값을 자신의 것으로 수정</p>
79 +<p>RDS와 MySQL 설정할 때 만든 값 입력</p>
80 +```nodejs
81 +var db = mysql.createConnection({
82 + host: '값 입력',
83 + user: '값 입력',
84 + password: '값 입력',
85 + database: '값 입력',
86 + port: '3306'
87 +});
88 +```
89 +<p>etc. web crawling 코드 설정</p>
90 +<p>터미널을 열고 다음 명령어 입력</p>
91 +```pip3 install requests
92 +pip3 install pymysql
93 +pip3 install beautifulsoup4
94 +```
95 +<br>
49 --- 96 ---
50 ### 진행정도 97 ### 진행정도
51 - [x] 챗봇을 올릴 aws 서비스 생성 98 - [x] 챗봇을 올릴 aws 서비스 생성
......
1 -var xhr = new XMLHttpRequest();
2 -var url = 'http://apis.data.go.kr/1390802/AgriFood/FdCkry/getKoreanFoodFdCkryList'; /*URL*/
3 -var queryParams = '?' + encodeURIComponent('serviceKey') + '='+'R7bFhjvvAMmxJxzcrL8NWkYHVa227zfpwvpwgXxcixNdMY0EbdbsbCboj3zXEsXniKNHyqu2dEllJCRk1LsdxA%3D%3D'; /*Service Key*/
4 -queryParams += '&' + encodeURIComponent('service_Type') + '=' + encodeURIComponent('xml'); /**/
5 -queryParams += '&' + encodeURIComponent('Page_No') + '=' + encodeURIComponent('1'); /**/
6 -queryParams += '&' + encodeURIComponent('Page_Size') + '=' + encodeURIComponent('20'); /**/
7 -queryParams += '&' + encodeURIComponent('food_Name') + '=' + encodeURIComponent('밥'); /**/
8 -queryParams += '&' + encodeURIComponent('ckry_Name') + '=' + encodeURIComponent('조리'); /**/
9 -xhr.open('GET', url + queryParams);
10 -xhr.onreadystatechange = function () {
11 - if (this.readyState == 4) {
12 - alert('Status: '+this.status+'nHeaders: '+JSON.stringify(this.getAllResponseHeaders())+'nBody: '+this.responseText);
13 - }
14 -};
15 -
16 -xhr.send('');
...\ No newline at end of file ...\ No newline at end of file
...@@ -3,14 +3,14 @@ import requests ...@@ -3,14 +3,14 @@ import requests
3 from bs4 import BeautifulSoup 3 from bs4 import BeautifulSoup
4 import pymysql 4 import pymysql
5 5
6 -#pip3 install requests, pip3 install pymyaql, pip3 install beautifulsoup4를 하고 진행, pip3대신 pip 사용가능 6 +#pip3 install requests, pip3 install pymysql, pip3 install beautifulsoup4를 하고 진행, pip3대신 pip 사용가능
7 #사이트가 크롤링을 공격으로 인식하는 것을 방지하기 위해 중간중간에 sleep함수를 사용 7 #사이트가 크롤링을 공격으로 인식하는 것을 방지하기 위해 중간중간에 sleep함수를 사용
8 8
9 9
10 conn = pymysql.connect(host="localhost", user="root",password='abcde12345abcde',db='db_recipe', charset='utf8') 10 conn = pymysql.connect(host="localhost", user="root",password='abcde12345abcde',db='db_recipe', charset='utf8')
11 curs = conn.cursor(pymysql.cursors.DictCursor) 11 curs = conn.cursor(pymysql.cursors.DictCursor)
12 12
13 -for pagenum in range(1,35): #크롤링 할 상위 페이지 개수. 약 40개정도의 레시피 링크가 한 페이지에 이어져 있음 13 +for pagenum in range(1,2): #크롤링 할 상위 페이지 개수. 약 40개정도의 레시피 링크가 한 페이지에 이어져 있음
14 print(pagenum) 14 print(pagenum)
15 page = requests.get('https://www.10000recipe.com/recipe/list.html?order=reco&page='+str(pagenum)) 15 page = requests.get('https://www.10000recipe.com/recipe/list.html?order=reco&page='+str(pagenum))
16 16
......
This diff could not be displayed because it is too large.