redbean096@khu.ac.kr

pull origin master

...@@ -15,11 +15,11 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil ...@@ -15,11 +15,11 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil
15 > 작심삼일 알고리즘 문제풀이 도우미 서비스<br/> 15 > 작심삼일 알고리즘 문제풀이 도우미 서비스<br/>
16 > 16 >
17 > > 알고리즘 문제 풀이 스터디를 꾸준히 할 수 있게 돕는 웹 서비스입니다. 17 > > 알고리즘 문제 풀이 스터디를 꾸준히 할 수 있게 돕는 웹 서비스입니다.
18 -> > <br> [링크](http://ossfinal.com)에서 직접 사용해 보세요! 18 +> > <br> [링크](http://www.ossjaksimsamil.ml:3000)에서 직접 사용해 보세요!
19 19
20 -![그림1](https://user-images.githubusercontent.com/16442978/85690047-236d1d00-b70e-11ea-8d2b-480593c0daf3.png) 20 +![KakaoTalk_20201209_203849946](/uploads/e3e7aea64c555c9542fef7ee2426cd68/KakaoTalk_20201209_203849946.png)
21 21
22 -![그림2](https://user-images.githubusercontent.com/16442978/85690058-2536e080-b70e-11ea-98cd-45fdf04084ce.png) 22 +![KakaoTalk_20201209_203825860](/uploads/809796e9fe3274b7f3643629c9d3b0e9/KakaoTalk_20201209_203825860.png)
23 23
24 # 기존 프로젝트의 기능 24 # 기존 프로젝트의 기능
25 25
...@@ -40,7 +40,7 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil ...@@ -40,7 +40,7 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil
40 - 개선된 문제 추천 (사용자 실력 맞춤형) 40 - 개선된 문제 추천 (사용자 실력 맞춤형)
41 41
42 # 기존의 마더 프로젝트에 새롭게 추가한 기능 42 # 기존의 마더 프로젝트에 새롭게 추가한 기능
43 - -카카오 api를 이용한 문제추천 알림 43 + -line 챗봇을 이용한 문제추천 알림
44 44
45 45
46 ## Usages 46 ## Usages
...@@ -62,7 +62,7 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil ...@@ -62,7 +62,7 @@ http://khuhub.khu.ac.kr/MotherProject/Jaksimsamil
62 1. Clone 62 1. Clone
63 63
64 ``` 64 ```
65 -git clone http://khuhub.khu.ac.kr/2020-2_open_source_sw_development_Han/JaksimSamil_Develop.git 65 +git clone http://khuhub.khu.ac.kr/2020-2_open_source_sw_development_Han/Jaksimsamil.git
66 ``` 66 ```
67 67
68 2. Install MongoDB(Ubuntu) 68 2. Install MongoDB(Ubuntu)
...@@ -89,7 +89,6 @@ touch .env ...@@ -89,7 +89,6 @@ touch .env
89 SERVER_PORT= ### 89 SERVER_PORT= ###
90 MONGO_URL= ### 90 MONGO_URL= ###
91 JWT_SECRET= ### 91 JWT_SECRET= ###
92 -KAKAO_JS_KEY = ###
93 ``` 92 ```
94 93
95 4. Start Node Server 94 4. Start Node Server
......
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
...@@ -3,25 +3,33 @@ ...@@ -3,25 +3,33 @@
3 "version": "0.1.0", 3 "version": "0.1.0",
4 "private": true, 4 "private": true,
5 "dependencies": { 5 "dependencies": {
6 +
7 + "@material-ui/core": "^4.11.2",
8 + "@testing-library/jest-dom": "^5.11.6",
9 + "@testing-library/react": "^11.2.2",
10 + "@testing-library/user-event": "^12.5.0",
11 + "axios": "^0.21.0",
12 + "immer": "^8.0.0",
6 "@material-ui/core": "^4.10.2", 13 "@material-ui/core": "^4.10.2",
7 "@testing-library/jest-dom": "^4.2.4", 14 "@testing-library/jest-dom": "^4.2.4",
8 "@testing-library/react": "^9.3.2", 15 "@testing-library/react": "^9.3.2",
9 "@testing-library/user-event": "^7.1.2", 16 "@testing-library/user-event": "^7.1.2",
10 "axios": "^0.19.2", 17 "axios": "^0.19.2",
18 + "eslint": "^7.14.0",
11 "immer": "^7.0.5", 19 "immer": "^7.0.5",
12 "include-media": "^1.4.9", 20 "include-media": "^1.4.9",
13 - "moment": "^2.27.0", 21 + "moment": "^2.29.1",
14 "open-color": "^1.7.0", 22 "open-color": "^1.7.0",
15 - "react": "^16.13.1", 23 + "react": "^17.0.1",
16 - "react-dom": "^16.13.1", 24 + "react-dom": "^17.0.1",
17 - "react-redux": "^7.2.0", 25 + "react-redux": "^7.2.2",
18 "react-router-dom": "^5.2.0", 26 "react-router-dom": "^5.2.0",
19 - "react-scripts": "3.4.1", 27 + "react-scripts": "4.0.1",
20 "redux": "^4.0.5", 28 "redux": "^4.0.5",
21 "redux-actions": "^2.6.5", 29 "redux-actions": "^2.6.5",
22 "redux-devtools-extension": "^2.13.8", 30 "redux-devtools-extension": "^2.13.8",
23 "redux-saga": "^1.1.3", 31 "redux-saga": "^1.1.3",
24 - "styled-components": "^5.1.1" 32 + "styled-components": "^5.2.1"
25 }, 33 },
26 "scripts": { 34 "scripts": {
27 "start": "react-scripts start", 35 "start": "react-scripts start",
...@@ -30,7 +38,10 @@ ...@@ -30,7 +38,10 @@
30 "eject": "react-scripts eject" 38 "eject": "react-scripts eject"
31 }, 39 },
32 "eslintConfig": { 40 "eslintConfig": {
33 - "extends": "react-app" 41 + "extends": "react-app",
42 + "rules": {
43 + "jsx-a11y/anchor-is-valid": "off"
44 + }
34 }, 45 },
35 "browserslist": { 46 "browserslist": {
36 "production": [ 47 "production": [
...@@ -44,6 +55,5 @@ ...@@ -44,6 +55,5 @@
44 "last 1 safari version" 55 "last 1 safari version"
45 ] 56 ]
46 }, 57 },
47 - "proxy": "http://localhost:4000", 58 + "proxy": "http://localhost:4000"
48 - "secure" : false
49 } 59 }
......
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
25 Learn how to configure a non-root public URL by running `npm run build`. 25 Learn how to configure a non-root public URL by running `npm run build`.
26 --> 26 -->
27 <title>React App</title> 27 <title>React App</title>
28 + <script src ="https://developers.kakao.com/sdk/js/kakao.min.js"></script>
29 + <script type = "text/javascript">
30 + Kakao.init("9454fd9d91effc97b064c201f04586d2");
31 + </script>
28 </head> 32 </head>
29 <body> 33 <body>
30 <noscript>You need to enable JavaScript to run this app.</noscript> 34 <noscript>You need to enable JavaScript to run this app.</noscript>
......
...@@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles'; ...@@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles';
3 import Paper from '@material-ui/core/Paper'; 3 import Paper from '@material-ui/core/Paper';
4 import Grid from '@material-ui/core/Grid'; 4 import Grid from '@material-ui/core/Grid';
5 import palette from '../../lib/styles/palette'; 5 import palette from '../../lib/styles/palette';
6 -import AuthForm from '../auth/AuthForm'; 6 +
7 const useStyles = makeStyles((theme) => ({ 7 const useStyles = makeStyles((theme) => ({
8 root: { 8 root: {
9 flexGrow: 1, 9 flexGrow: 1,
......
1 +import React from 'react';
2 +
3 +const LineQR = () => {
4 + return (
5 + <div>
6 + <img
7 + src="https://qr-official.line.me/sid/L/132nudgz.png"
8 + width="130"
9 + />
10 + </div>
11 + );
12 +};
13 +
14 +export default LineQR
...@@ -8,6 +8,7 @@ import Paper from '@material-ui/core/Paper'; ...@@ -8,6 +8,7 @@ import Paper from '@material-ui/core/Paper';
8 import Grid from '@material-ui/core/Grid'; 8 import Grid from '@material-ui/core/Grid';
9 import CircularProgress from '@material-ui/core/CircularProgress'; 9 import CircularProgress from '@material-ui/core/CircularProgress';
10 import styled from 'styled-components'; 10 import styled from 'styled-components';
11 +import LineQR from './LineQR'
11 12
12 const useStyles = makeStyles((theme) => ({ 13 const useStyles = makeStyles((theme) => ({
13 root: { 14 root: {
...@@ -80,6 +81,14 @@ const SettingForm = ({ ...@@ -80,6 +81,14 @@ const SettingForm = ({
80 /> 81 />
81 </Paper> 82 </Paper>
82 </Grid> 83 </Grid>
84 +
85 + <Grid container item xs={6}>
86 + <Paper className={classes.paper} elevation={3}>
87 + <h1>QR코드를 찍어주세요</h1>
88 + <LineQR></LineQR>
89 + </Paper>
90 + </Grid>
91 +
83 </Grid> 92 </Grid>
84 </div> 93 </div>
85 ); 94 );
......
...@@ -75,7 +75,7 @@ const SettingContainer = ({ history }) => { ...@@ -75,7 +75,7 @@ const SettingContainer = ({ history }) => {
75 } 75 }
76 }, [dispatch, user, history]); 76 }, [dispatch, user, history]);
77 useEffect(() => { 77 useEffect(() => {
78 - if (loading['profile/SYNC_BJID'] == true) { 78 + if (loading['profile/SYNC_BJID']) {
79 setLoading(true); 79 setLoading(true);
80 } else { 80 } else {
81 setLoading(false); 81 setLoading(false);
......
...@@ -12,15 +12,15 @@ ...@@ -12,15 +12,15 @@
12 ``` 12 ```
13 npm install 13 npm install
14 npm update 14 npm update
15 -node index.js 15 +npm start
16 ``` 16 ```
17 17
18 ## Example 18 ## Example
19 19
20 ``` 20 ```
21 -POST http://facerain.dcom.club/profile/getprofile 21 +POST http://www.ossjaksimsamil.ml:3000/profile/getprofile
22 { 22 {
23 - username: 'syw5141', 23 + username : 'redbean096'
24 } 24 }
25 ``` 25 ```
26 26
...@@ -40,3 +40,6 @@ POST http://facerain.dcom.club/profile/getprofile ...@@ -40,3 +40,6 @@ POST http://facerain.dcom.club/profile/getprofile
40 | auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT Token | 40 | auth | 로그아웃 | POST | api/auth/logout | [바로가기](/src/api/auth/README.md) | JWT Token |
41 | auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None | 41 | auth | 회원가입 | POST | api/auth/register | [바로가기](/src/api/auth/README.md) | None |
42 | auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None | 42 | auth | 로그인 확인 | GET | api/auth/check | [바로가기](/src/api/auth/README.md) | None |
43 +| line | 라인 ID 등록 | POST | api/line/linestart | |Line channel access token|
44 +| line | 라인 문제 메시지 발송 | POST | api/line/linestart | |Line channel access token|
45 +
......
1 const Koa = require("koa"); 1 const Koa = require("koa");
2 const Router = require("koa-router"); 2 const Router = require("koa-router");
3 const bodyParser = require("koa-bodyparser"); 3 const bodyParser = require("koa-bodyparser");
4 +
4 const mongoose = require("mongoose"); 5 const mongoose = require("mongoose");
5 const fs = require("fs"); 6 const fs = require("fs");
7 +const path = require('path');
8 +const HTTPS = require('https');
9 +
6 const morgan = require("koa-morgan"); 10 const morgan = require("koa-morgan");
7 const jwtMiddleware = require("./src/lib/jwtMiddleware"); 11 const jwtMiddleware = require("./src/lib/jwtMiddleware");
12 +
8 const api = require("./src/api"); 13 const api = require("./src/api");
9 14
15 +const cors = require('@koa/cors'); // for fix CORS Error
16 +
10 require("dotenv").config(); 17 require("dotenv").config();
11 18
12 const app = new Koa(); 19 const app = new Koa();
...@@ -15,10 +22,12 @@ const accessLogStream = fs.createWriteStream(__dirname + "/access.log", { ...@@ -15,10 +22,12 @@ const accessLogStream = fs.createWriteStream(__dirname + "/access.log", {
15 flags: "a", 22 flags: "a",
16 }); 23 });
17 require("dotenv").config(); 24 require("dotenv").config();
25 +app.use(cors());
18 app.use(bodyParser()); 26 app.use(bodyParser());
19 app.use(jwtMiddleware); 27 app.use(jwtMiddleware);
20 app.use(morgan("combined", { stream: accessLogStream })); 28 app.use(morgan("combined", { stream: accessLogStream }));
21 -const { SERVER_PORT, MONGO_URL } = process.env; 29 +
30 +const { SERVER_PORT, MONGO_URL, SSLPORT, DOMAIN } = process.env;
22 31
23 router.use("/api", api.routes()); 32 router.use("/api", api.routes());
24 app.use(router.routes()).use(router.allowedMethods()); 33 app.use(router.routes()).use(router.allowedMethods());
...@@ -28,6 +37,7 @@ mongoose ...@@ -28,6 +37,7 @@ mongoose
28 useNewUrlParser: true, 37 useNewUrlParser: true,
29 useFindAndModify: false, 38 useFindAndModify: false,
30 useUnifiedTopology: true, 39 useUnifiedTopology: true,
40 + useCreateIndex : true
31 }) 41 })
32 .then(() => { 42 .then(() => {
33 console.log("Connected to MongoDB"); 43 console.log("Connected to MongoDB");
...@@ -39,3 +49,19 @@ mongoose ...@@ -39,3 +49,19 @@ mongoose
39 app.listen(SERVER_PORT, () => { 49 app.listen(SERVER_PORT, () => {
40 console.log("Server is running on port", process.env.SERVER_PORT); 50 console.log("Server is running on port", process.env.SERVER_PORT);
41 }); 51 });
52 +
53 +//for Line Channel
54 +try {
55 + const option = {
56 + ca: fs.readFileSync('/etc/letsencrypt/live/' + DOMAIN +'/fullchain.pem'),
57 + key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + DOMAIN +'/privkey.pem'), 'utf8').toString(),
58 + cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + DOMAIN +'/cert.pem'), 'utf8').toString(),
59 + };
60 +
61 + HTTPS.createServer(option, app.callback()).listen(SSLPORT, () => {
62 + console.log(`[HTTPS] Server is started on port ${SSLPORT}`);
63 + });
64 +} catch (error) {
65 + console.log('[HTTPS] HTTPS 오류가 발생하였습니다. HTTPS 서버는 실행되지 않습니다.');
66 + console.log(error);
67 +}
......
...@@ -146,6 +146,14 @@ ...@@ -146,6 +146,14 @@
146 "to-fast-properties": "^2.0.0" 146 "to-fast-properties": "^2.0.0"
147 } 147 }
148 }, 148 },
149 + "@koa/cors": {
150 + "version": "3.1.0",
151 + "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-3.1.0.tgz",
152 + "integrity": "sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q==",
153 + "requires": {
154 + "vary": "^1.1.2"
155 + }
156 + },
149 "@sindresorhus/is": { 157 "@sindresorhus/is": {
150 "version": "0.14.0", 158 "version": "0.14.0",
151 "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", 159 "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
...@@ -826,6 +834,15 @@ ...@@ -826,6 +834,15 @@
826 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 834 "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
827 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 835 "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
828 }, 836 },
837 + "cors": {
838 + "version": "2.8.5",
839 + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
840 + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
841 + "requires": {
842 + "object-assign": "^4",
843 + "vary": "^1"
844 + }
845 + },
829 "cron-parser": { 846 "cron-parser": {
830 "version": "2.15.0", 847 "version": "2.15.0",
831 "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.15.0.tgz", 848 "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.15.0.tgz",
......
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
4 "main": "index.js", 4 "main": "index.js",
5 "license": "MIT", 5 "license": "MIT",
6 "dependencies": { 6 "dependencies": {
7 + "@koa/cors": "^3.1.0",
7 "axios": "^0.19.2", 8 "axios": "^0.19.2",
8 "bcrypt": "^4.0.1", 9 "bcrypt": "^4.0.1",
9 "body-parser": "^1.19.0", 10 "body-parser": "^1.19.0",
10 "cheerio": "^1.0.0-rc.3", 11 "cheerio": "^1.0.0-rc.3",
11 "cookie-parser": "^1.4.5", 12 "cookie-parser": "^1.4.5",
13 + "cors": "^2.8.5",
12 "dotenv": "^8.2.0", 14 "dotenv": "^8.2.0",
13 "eslint-config-prettier": "^6.11.0", 15 "eslint-config-prettier": "^6.11.0",
14 "fs": "^0.0.1-security", 16 "fs": "^0.0.1-security",
......
...@@ -14,7 +14,7 @@ exports.register = async (ctx) => { ...@@ -14,7 +14,7 @@ exports.register = async (ctx) => {
14 password: Joi.string().required(), 14 password: Joi.string().required(),
15 }); 15 });
16 16
17 - const result = Joi.validate(ctx.request.body, schema); 17 + const result = schema.validate(ctx.request.body);
18 if (result.error) { 18 if (result.error) {
19 ctx.status = 400; 19 ctx.status = 400;
20 ctx.body = result.error; 20 ctx.body = result.error;
......
1 const Router = require("koa-router"); 1 const Router = require("koa-router");
2 const auth = new Router(); 2 const auth = new Router();
3 const authCtrl = require("./auth.ctrl"); 3 const authCtrl = require("./auth.ctrl");
4 +
4 auth.post("/login", authCtrl.login); 5 auth.post("/login", authCtrl.login);
5 auth.post("/logout", authCtrl.logout); 6 auth.post("/logout", authCtrl.logout);
6 auth.post("/register", authCtrl.register); 7 auth.post("/register", authCtrl.register);
......
...@@ -6,11 +6,13 @@ const friend = require("./friend"); ...@@ -6,11 +6,13 @@ const friend = require("./friend");
6 const notify = require("./notify"); 6 const notify = require("./notify");
7 const user = require("./user"); 7 const user = require("./user");
8 const profile = require("./profile"); 8 const profile = require("./profile");
9 +const line = require("./line")
9 10
10 api.use("/auth", auth.routes()); 11 api.use("/auth", auth.routes());
11 api.use("/friend", friend.routes()); 12 api.use("/friend", friend.routes());
12 api.use("/notify", notify.routes()); 13 api.use("/notify", notify.routes());
13 api.use("/user", user.routes()); 14 api.use("/user", user.routes());
14 api.use("/profile", profile.routes()); 15 api.use("/profile", profile.routes());
16 +api.use("/line", line.routes());
15 17
16 -module.exports = api; 18 +module.exports = api;
...\ No newline at end of file ...\ No newline at end of file
......
1 +const Router = require("koa-router");
2 +const line = new Router();
3 +const lineCtrl = require("./line.ctrl");
4 +
5 +line.post("/hook", lineCtrl.linestart);
6 +
7 +module.exports = line;
1 +const request = require('request');
2 +const TARGET_URL = 'https://api.line.me/v2/bot/message/reply'
3 +
4 +require("dotenv").config();
5 +const TOKEN = process.env.LINE_CHANNEL_KEY;
6 +
7 +const Profile = require("../../models/profile");
8 +const problem_set = require("../../data/problem_set");
9 +const compareBJ = require("../../util/compareBJ");
10 +
11 +/*
12 + username : default = ""
13 +*/
14 +let username = "";
15 +
16 +/*
17 +POST api/line/hook
18 +{
19 + for line reply : recommend and set
20 +}
21 + */
22 +exports.linestart = async(ctx) => {
23 + var eventObj = ctx.request.body.events[0];
24 +
25 + // request log
26 + console.log('======================', new Date() ,'======================');
27 + console.log('[request]', ctx.request.body);
28 + console.log('[request source] ', eventObj.source);
29 + console.log('[request message]', eventObj.message);
30 + console.log('[username]', username);
31 +
32 + //first . set User
33 + if(username == "") {
34 + username = eventObj.message.text;
35 +
36 + const result = await isExist(username);
37 + if (!result) {
38 + username = "";
39 +
40 + request.post(
41 + {
42 + url: TARGET_URL,
43 + headers: {
44 + 'Authorization': `Bearer ${TOKEN}`
45 + },
46 + json: {
47 + "replyToken":eventObj.replyToken,
48 + "messages":[
49 + {
50 + "type":"text",
51 + "text": "작심삼일 사이트의 ID값이 올바르지 않습니다. 다시 입력해주세요."
52 + }
53 + ]
54 + }
55 + },(body) => {
56 + console.log(body)
57 + });
58 + } else {
59 + request.post({
60 + url: TARGET_URL,
61 + headers: {
62 + 'Authorization': `Bearer ${TOKEN}`
63 + },
64 + json: {
65 + "replyToken":eventObj.replyToken,
66 + "messages":[
67 + {
68 + "type":"text",
69 + "text": eventObj.message.text + " : 정상 등록 되었습니다."
70 + }
71 + ]
72 + }
73 + },(body) => {
74 + console.log(body)
75 + });
76 +
77 + }
78 + };
79 +
80 + //second. can reset username
81 + if(eventObj.message.text == "reset ID") {
82 + username = "";
83 + request.post(
84 + {
85 + url: TARGET_URL,
86 + headers: {
87 + 'Authorization': `Bearer ${TOKEN}`
88 + },
89 + json: {
90 + "replyToken": eventObj.replyToken,
91 + "messages":[
92 + {
93 + "type":"text",
94 + "text": "작심삼일 사이트의 ID가 초기화 되었습니다."
95 + }
96 + ]
97 + }
98 + },(body) => {
99 + console.log(body)
100 + });
101 + }
102 +
103 + //main : recommend Problem
104 + if(eventObj.message.text == "문제") {
105 + console.log("문제를 추천합니다.");
106 + let recommendData = await lineRecommend(username);
107 + recommendBJ(eventObj.replyToken, recommendData);
108 +
109 + console.log(recommendData);
110 + }
111 +
112 +}
113 +
114 +//for recommend message
115 +function recommendBJ(replyToken, recommendData) {
116 + var recommendProblem = "오늘의 추천문제는 " + recommendData.problem_title + "입니다.";
117 + var problemURL = "https://www.boj.kr/" + recommendData.problem_number;
118 + request.post(
119 + {
120 + url: TARGET_URL,
121 + headers: {
122 + 'Authorization': `Bearer ${TOKEN}`
123 + },
124 + json: {
125 + "replyToken":replyToken,
126 + "messages":[
127 + {
128 + "type":"text",
129 + "text": recommendProblem
130 + },
131 + {
132 + "type":"text",
133 + "text": problemURL
134 + }
135 + ]
136 + }
137 + },(body) => {
138 + console.log(body)
139 + });
140 +}
141 +
142 +async function lineRecommend (username) {
143 +
144 + const profile = await Profile.findByUsername(username);
145 + if (!profile) {
146 + console.log("401");
147 + return;
148 + }
149 +
150 + const unsolved_data = await compareBJ.compareBJ(
151 + profile.getBJdata(),
152 + problem_set.problem_set
153 + );
154 +
155 + const recommendData = await compareBJ.randomItem(unsolved_data);
156 +
157 + if (!recommendData) {
158 + console.log("402");
159 + return;
160 + }
161 +
162 + return recommendData;
163 +
164 +};
165 +
166 +async function isExist(username) {
167 + const profile = await Profile.findByUsername(username);
168 +
169 + if (!profile) {
170 + return false;
171 + }
172 +
173 + return true;
174 +}
1 const Router = require("koa-router"); 1 const Router = require("koa-router");
2 const profile = new Router(); 2 const profile = new Router();
3 const profileCtrl = require("./profile.ctrl"); 3 const profileCtrl = require("./profile.ctrl");
4 +
4 profile.post("/solved:id"); 5 profile.post("/solved:id");
5 profile.get("/solvednum:id"); 6 profile.get("/solvednum:id");
6 profile.post("/recommend", profileCtrl.recommend); 7 profile.post("/recommend", profileCtrl.recommend);
7 profile.patch("/syncBJ", profileCtrl.syncBJ); 8 profile.patch("/syncBJ", profileCtrl.syncBJ);
8 profile.post("/setprofile", profileCtrl.setProfile); 9 profile.post("/setprofile", profileCtrl.setProfile);
9 profile.post("/getprofile", profileCtrl.getProfile); 10 profile.post("/getprofile", profileCtrl.getProfile);
11 +
10 module.exports = profile; 12 module.exports = profile;
......
...@@ -51,7 +51,7 @@ exports.setProfile = async (ctx) => { ...@@ -51,7 +51,7 @@ exports.setProfile = async (ctx) => {
51 }) 51 })
52 .unknown(); 52 .unknown();
53 console.log(ctx.request.body); 53 console.log(ctx.request.body);
54 - const result = Joi.validate(ctx.request.body, schema); 54 + const result = schema.validate(ctx.request.body);
55 if (result.error) { 55 if (result.error) {
56 ctx.status = 400; 56 ctx.status = 400;
57 ctx.body = result.error; 57 ctx.body = result.error;
...@@ -118,14 +118,16 @@ POST /api/proflie/recommend ...@@ -118,14 +118,16 @@ POST /api/proflie/recommend
118 */ 118 */
119 exports.recommend = async (ctx) => { 119 exports.recommend = async (ctx) => {
120 const { username } = ctx.request.body; 120 const { username } = ctx.request.body;
121 -
122 if (!username) { 121 if (!username) {
122 + console.log('no given username');
123 ctx.status = 401; 123 ctx.status = 401;
124 return; 124 return;
125 } 125 }
126 try { 126 try {
127 + console.log('finding username:', username);
127 const profile = await Profile.findByUsername(username); 128 const profile = await Profile.findByUsername(username);
128 if (!profile) { 129 if (!profile) {
130 + console.log('no profile');
129 ctx.status = 401; 131 ctx.status = 401;
130 return; 132 return;
131 } 133 }
...@@ -137,5 +139,7 @@ exports.recommend = async (ctx) => { ...@@ -137,5 +139,7 @@ exports.recommend = async (ctx) => {
137 //데이터가 비었을 떄 예외처리 필요 139 //데이터가 비었을 떄 예외처리 필요
138 } catch (e) { 140 } catch (e) {
139 ctx.throw(500, e); 141 ctx.throw(500, e);
142 + } finally {
143 + console.log('successfully sent user recommendation')
140 } 144 }
141 }; 145 };
......