From 07ac8c44250f0303553da0d0585e67a0ed023102 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:00:59 +0900 Subject: [PATCH 01/33] refactor: add fetch, send message, utils to lib --- src/lib/fetch.js | 16 ++++++++++++++++ src/lib/sendMessage.js | 19 +++++++++++++++++++ src/lib/utils.js | 26 ++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 src/lib/fetch.js create mode 100644 src/lib/sendMessage.js create mode 100644 src/lib/utils.js diff --git a/src/lib/fetch.js b/src/lib/fetch.js new file mode 100644 index 0000000..71e9d1f --- /dev/null +++ b/src/lib/fetch.js @@ -0,0 +1,16 @@ +import fetch from 'node-fetch'; + +export const send = async (auth, url, body, method) => { + if (method !== 'post' && method !== 'get') throw new Error('wrong http method!'); + + return fetch(url, { + headers: { + accept: 'application/json', + 'content-type': 'application/json', + 'x-access-key': auth.accessKey, + 'x-access-secret': auth.accessSecret, + }, + body: body ? JSON.stringify(body) : undefined, + method: method, + }); +}; diff --git a/src/lib/sendMessage.js b/src/lib/sendMessage.js new file mode 100644 index 0000000..8c786ed --- /dev/null +++ b/src/lib/sendMessage.js @@ -0,0 +1,19 @@ +import { auth } from "../config/auth.js"; +import { BASE_URL, APP_VERSION } from "../constants/url.js"; +import { makeUrl, makeSenderUrl, makeSearchParamsUrl } from "./utils.js"; +import { send } from "./fetch.js"; + +export const sendMessage = (sender, senderId, additionalPath, searchParams, body, method) => { + const urlWithSender = makeSenderUrl(makeUrl(BASE_URL, APP_VERSION), sender); + const urlWithSenderId = senderId ? `${urlWithSender}/${senderId}` : urlWithSender; + const urlWithPath = additionalPath ? `${urlWithSenderId}/${additionalPath}` : urlWithSenderId; + const url = makeSearchParamsUrl(urlWithPath, searchParams); + + try { + const response = await send(auth, url, body, method); + console.log(response.json()); + return response; + } catch (err) { + console.log(`${sender} failed to ${method} message ` + err); + } +}; diff --git a/src/lib/utils.js b/src/lib/utils.js new file mode 100644 index 0000000..51b5e5a --- /dev/null +++ b/src/lib/utils.js @@ -0,0 +1,26 @@ +export const makeUrl = (url, appVersion) => { + return `${url}/open/${appVersion}`; +}; + +export const makeSenderUrl = (url, sender) => { + return `${url}/${sender}`; +}; + +export const makeSearchParamsUrl = (url, searchParams) => { + if (searchParams.constructor !== Object) throw new Error('searchParams should be object type!'); + if (searchParams == undefined) return url; + + const keys = Object.keys(searchParams); + let urlWithSearchParams = `${url}?${String(keys[0])}=${String(searchParams[keys[0]])}`; + + if (keys.length > 1) { + keys.map((key, i) => { + if (i > 0) { + const query = `&${key}=${String(searchParams[key])}`; + urlWithSearchParams += query; + } + }); + } + + return urlWithSearchParams; +}; From 0ebbd83a8a399e8acee5315bff4fd159113daec6 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:01:17 +0900 Subject: [PATCH 02/33] refactor: add sender, url to constants --- src/constants/sender.js | 5 +++++ src/constants/url.js | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 src/constants/sender.js create mode 100644 src/constants/url.js diff --git a/src/constants/sender.js b/src/constants/sender.js new file mode 100644 index 0000000..2c7ce67 --- /dev/null +++ b/src/constants/sender.js @@ -0,0 +1,5 @@ +export const sender = { + GROUP: 'groups', + MANAGER: 'managers', + ANNOUNCEMENTS: 'announcements', +}; diff --git a/src/constants/url.js b/src/constants/url.js new file mode 100644 index 0000000..3b86d49 --- /dev/null +++ b/src/constants/url.js @@ -0,0 +1,2 @@ +export const BASE_URL = 'https://api.channel.io'; +export const APP_VERSION = 'v5'; From 987fea2c88017b136b8e44a02e048526e5f312f6 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:01:33 +0900 Subject: [PATCH 03/33] refactor: add auth to config --- src/config/auth.js | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/config/auth.js diff --git a/src/config/auth.js b/src/config/auth.js new file mode 100644 index 0000000..56658f6 --- /dev/null +++ b/src/config/auth.js @@ -0,0 +1,4 @@ +export const auth = { + accessKey: process.env.ACCESS_KEY, + accessSecret: process.env.ACCESS_SECRET, +}; From 05e86cd64c6d8c8aa66bf7cd90efb9d90cd9cf73 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:01:59 +0900 Subject: [PATCH 04/33] refactor: use send message function --- src/celebrate.js | 77 +++++++++++++------------------ src/random-select.js | 105 ------------------------------------------- src/randomSelect.js | 57 +++++++++++++++++++++++ src/send-message.js | 42 ----------------- 4 files changed, 87 insertions(+), 194 deletions(-) delete mode 100644 src/random-select.js create mode 100644 src/randomSelect.js delete mode 100644 src/send-message.js diff --git a/src/celebrate.js b/src/celebrate.js index 5e9388e..73179f8 100644 --- a/src/celebrate.js +++ b/src/celebrate.js @@ -1,50 +1,33 @@ -import fetch from "node-fetch"; -import dotenv from "dotenv"; -dotenv.config(); +import { sendMessage } from './lib/sendMessage.js'; +import { sender } from './constants/sender'; -async function celebrate(auth, selectedManager, groupId, botName, isFull = true) { - try { - let msg = ""; - if (!isFull) { - let halfName = ""; - for (let i = 0; i < selectedManager.length; i++) { - if (i % 2 == 0) { - halfName += selectedManager[i]; - } else { - halfName += "*"; - } - } - msg = "πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ " + halfName + " λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!"; - } else { - msg = "πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ " + selectedManager + " λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!"; - } - const url = "https://api.channel.io/open/v5/groups/" + String(groupId) + "/messages?botName=" + botName; - const body = { - blocks: [ - { - type: "text", - value: msg, - }, - ], - options: ["actAsManager"], - }; - const header = { - accept: "application/json", - "content-type": "application/json", - "x-access-key": auth["accessKey"], - "x-access-secret": auth["accessSecret"], - }; - const response = await fetch(url, { - method: "post", - body: JSON.stringify(body), - headers: header, - }); - const data = await response.json(); - - console.log(data); - } catch (err) { - console.log(err); +const celebrate = async (selectedManager, groupId, botName, isFull = true) => { + let msg = ''; + if (!isFull) { + let halfName = ''; + for (let i = 0; i < selectedManager.length; i++) { + if (i % 2 == 0) { + halfName += selectedManager[i]; + } else { + halfName += '*'; + } } -} + msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + halfName + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; + } else { + msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + selectedManager + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; + } -export default celebrate; \ No newline at end of file + const body = { + blocks: [ + { + type: 'text', + value: msg, + }, + ], + options: ['actAsManager'], + }; + + sendMessage(sender.GROUP, String(groupId), 'messages', { botName: botName }, body, 'post'); +}; + +export default celebrate; diff --git a/src/random-select.js b/src/random-select.js deleted file mode 100644 index 20668f4..0000000 --- a/src/random-select.js +++ /dev/null @@ -1,105 +0,0 @@ -import fetch from "node-fetch"; - -async function getMembers(auth, groupId) { - try { - let memberList = []; - const url = "https://api.channel.io/open/v5/groups/" + String(groupId) + "/sessions"; - const headers = { - accept: "application/json", - "x-access-key": auth["accessKey"], - "x-access-secret": auth["accessSecret"], - } - const response = await fetch( - url, - { - method: "get", - headers: headers, - } - ); - const data = await response.json(); - await Promise.all(data["sessions"].map(async (iter) => { - memberList.push(iter["personId"]); - })) - - return memberList; - - } catch (err) { - console.log(err); - } -} - -function selectMember(memberList) { - let pickedIdx = 0; - let managerId = ""; - try { - pickedIdx = Math.floor(Math.random() * memberList.length); - managerId = memberList[pickedIdx]; - return managerId; - } catch (err) { - console.log(err); - } -} - -async function getMemberName(auth, managerId) { - try { - const url = "https://api.channel.io/open/v5/managers/" + String(managerId); - const headers = { - accept: "application/json", - "x-access-key": auth["accessKey"], - "x-access-secret": auth["accessSecret"], - }; - const response = await fetch( - url, - { - method: "get", - headers: headers, - } - ); - const data = await response.json(); - return data["manager"]["name"]; - } catch (err) { - console.log(err); - } -} - -async function personalAnnounce(auth, managerId, botName) { - try { - const url = "https://api.channel.io/open/v5/announcements/announce?botName=" + botName + "&managerIds=" + String(managerId); - const headers = { - access: "application/json", - "content-type": "application/json", - "x-access-key": auth["accessKey"], - "x-access-secret": auth["accessSecret"], - } - const body = { - blocks: [ - { - type: "text", - value: "πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!", - }, - ], - options: ["actAsManager"], - }; - const response = await fetch( - url, - { - method: "post", - headers: headers, - body: JSON.stringify(body), - - } - ) - } catch (err) { - console.log(err); - } -} - -async function randomSelect(auth, groupId, botName) { - const memberList = await getMembers(auth, groupId); - const managerId = await selectMember(memberList); - const selectedManager = await getMemberName(auth, managerId); - const announcement = await personalAnnounce(auth, managerId, botName); - return selectedManager; -} - -export default randomSelect; \ No newline at end of file diff --git a/src/randomSelect.js b/src/randomSelect.js new file mode 100644 index 0000000..0df6c31 --- /dev/null +++ b/src/randomSelect.js @@ -0,0 +1,57 @@ +import { sendMessage } from './lib/sendMessage.js'; +import { sender } from './constants/sender'; + +const getMembers = async (groupId) => { + let members = []; + + const response = sendMessage(sender.GROUP, String(groupId), 'sessions', undefined, undefined, 'get'); + const data = response.json(); + + await Promise.all( + data['sessions'].map(async (iter) => { + members.push(iter['personId']); + }), + ); + + return members; +}; + +const selectMember = (memberList) => { + let pickedIdx = 0; + let managerId = ''; + + pickedIdx = Math.floor(Math.random() * memberList.length); + managerId = memberList[pickedIdx]; + + return managerId; +}; + +const getMemberName = async (managerId) => { + const response = sendMessage(sender.MANAGER, String(managerId), '', undefined, undefined, 'get'); + const data = await response.json(); + return data['manager']['name']; +}; + +const personalAnnounce = async (managerId, botName) => { + const body = { + blocks: [ + { + type: 'text', + value: 'πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!', + }, + ], + options: ['actAsManager'], + }; + + sendMessage(sender.ANNOUNCEMENTS, undefined, 'announce', { botName: botName, managerIds: String(managerId) }, body, 'post'); +}; + +const randomSelect = async (groupId, botName) => { + const memberList = await getMembers(groupId); + const managerId = await selectMember(memberList); + const selectedManager = await getMemberName(managerId); + await personalAnnounce(managerId, botName); + return selectedManager; +}; + +export default randomSelect; diff --git a/src/send-message.js b/src/send-message.js deleted file mode 100644 index 75de195..0000000 --- a/src/send-message.js +++ /dev/null @@ -1,42 +0,0 @@ -import fetch from "node-fetch"; -import dotenv from "dotenv"; -dotenv.config(); - -async function sendMessage(auth, msg, groupId, botName) { - try { - const url = "https://api.channel.io/open/v5/groups/" + String(groupId) + "/messages?botName=" + botName; - const body = { - blocks: [ - { - type: "text", - value: msg, - }, - ], - reactions: [ - { - emojiName: "πŸ’₯", - personKeys: ["string"], - } - ], - options: ["actAsManager"], - }; - const header = { - accept: "application/json", - "content-type": "application/json", - "x-access-key": auth["accessKey"], - "x-access-secret": auth["accessSecret"], - }; - const response = await fetch(url, { - method: "post", - body: JSON.stringify(body), - headers: header, - }); - const data = await response.json(); - console.log(data); - return; - } catch (err) { - console.log(err); - } -} - -export default sendMessage; From 34bdb1d3bf1dede58ec9dcde105bdae3c29028e5 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:02:15 +0900 Subject: [PATCH 05/33] refactor: use summon function --- index.js | 38 +++++++++++++++++++++++++++ server.js | 72 --------------------------------------------------- src/summon.js | 48 ++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 72 deletions(-) create mode 100644 index.js delete mode 100644 server.js create mode 100644 src/summon.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..fd07806 --- /dev/null +++ b/index.js @@ -0,0 +1,38 @@ +import express from 'express'; +import dotenv from 'dotenv'; +import { summon } from './src/summon'; + +dotenv.config(); +const port = process.env.PORT || 8080; + +const app = express(); + +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); + +const botName = 'DevKor'; +const keyword = 'λͺ…'; + +app.post('/', async (res) => { + try { + const { body } = res; + const { event, entity } = body; + const { plainText = '', personType = '', chatId: groupId } = entity; + + const isPushEvent = event === 'push'; + const hasKeyword = plainText.includes(keyword); + const isManager = personType === 'manager'; + + const needToSummon = isPushEvent && hasKeyword && isManager; + + if (needToSummon) { + summon(plainText, keyword, groupId, botName); + } + } catch (err) { + console.log(err); + } +}); + +app.listen(port, () => { + console.log(`Listening on port ${port}...`); +}); diff --git a/server.js b/server.js deleted file mode 100644 index 6a68920..0000000 --- a/server.js +++ /dev/null @@ -1,72 +0,0 @@ -import express from "express"; -import dotenv from "dotenv"; -import sendMessage from "./src/send-message.js"; -import randomSelect from "./src/random-select.js"; -import celebrate from "./src/celebrate.js"; -import checkText from "./src/check-text.js"; - -dotenv.config(); - -const auth = { - "accessKey": process.env.ACCESS_KEY, - "accessSecret": process.env.ACCESS_SECRET, -}; -const app = express(); -const port = process.env.PORT; -const keyword = "λͺ…"; -const botName = "DevKor"; - -app.use(express.json()); -app.use(express.urlencoded({ extended: false })); - -app.listen(port, () => { - console.log(`Listening on port ${port}...`); -}) - -app.post("/", async (res) => { - try { - const { body } = res; - const { event, entity } = body; - const { plainText = "", personType = "", chatId: groupId } = entity; - - const isPushEvent = event === "push"; - const hasKeyword = plainText.includes(keyword); - const isManager = personType === "manager"; - - let [n, msg] = checkText(plainText, keyword); - - let hasNumber = false; - if (n) { - hasNumber = true; - } - if (msg) { - sendMessage(auth, msg, groupId, botName); - } - - const needToSummon = isPushEvent && hasKeyword && isManager && hasNumber; - let selectedManager = "" - let isFull = true; - - if (needToSummon) { - if (Number.isInteger(n)) { - for (let i = 0; i < n; i++) { - selectedManager = await randomSelect(auth, groupId, botName); - celebrate(auth, selectedManager, groupId, botName, isFull); - } - } else { - n = Math.floor(n); - msg = "μ•„ 또 μ†Œμˆ˜μ ..😀"; - sendMessage(auth, msg, groupId, botName); - for (let i = 0; i < n; i++) { - selectedManager = await randomSelect(auth, groupId, botName); - celebrate(auth, selectedManager, groupId, botName, isFull); - } - isFull = false; - selectedManager = await randomSelect(auth, groupId, botName); - celebrate(auth, selectedManager, groupId, botName, isFull); - } - } - } catch (err) { - console.log(err); - } -}) diff --git a/src/summon.js b/src/summon.js new file mode 100644 index 0000000..755e0ea --- /dev/null +++ b/src/summon.js @@ -0,0 +1,48 @@ +import { sender } from "./constants/sender"; +import { sendMessage } from "./lib/sendMessage.js"; +import randomSelect from "./randomSelect.js"; +import celebrate from "./celebrate.js"; +import checkText from "./lib/checkText.js"; + +const commonBody = (msg) => { + return { + blocks: [ + { + type: "text", + value: msg, + }, + ], + reactions: [ + { + emojiName: "πŸ’₯", + personKeys: ["string"], + } + ], + options: ["actAsManager"], + } +}; + +export const summon = (plainText, keyword, groupId, botName) => { + const [n, isInt, msg] = checkText(plainText, keyword); + + if (msg) { + sendMessage(sender.GROUP, groupId, "message", {botName: botName},commonBody(msg), "post"); + } + + if (n) { + let selectedManager = ""; + let isFull = true; + + const num = isInt ? n : Math.floor(n); + for (let i = 0; i < num; i++) { + selectedManager = await randomSelect(groupId, botName); + celebrate(selectedManager, groupId, botName, isFull); + } + + if (!isInt) { + isFull = false; + selectedManager = await randomSelect(groupId, botName); + celebrate(selectedManager, groupId, botName, isFull); + } + } +} \ No newline at end of file From d3eba812c6e411b1abdc73b400b707dba89486c8 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:02:39 +0900 Subject: [PATCH 06/33] refactor: add check num to check text --- src/check-text.js | 30 ------------------------------ src/lib/checkText.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 30 deletions(-) delete mode 100644 src/check-text.js create mode 100644 src/lib/checkText.js diff --git a/src/check-text.js b/src/check-text.js deleted file mode 100644 index 07b8489..0000000 --- a/src/check-text.js +++ /dev/null @@ -1,30 +0,0 @@ -function checkText(plainText, keyword) { - const textList = plainText.split(" "); - let n = ""; - let msg = ""; - - textList.map((x) => { - if (x.includes(keyword)) { - let text = x.split(keyword)[0]; - for (let i = text.length - 1; i >= 0; i--) { - if (Number(text[i]) >= 0) { - n = text[i] + n; - } else { - if (text[i] === "-") { - msg = "😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μ–‘μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄."; - } - else if (text[i] === ".") { - n = text[i] + n; - } - else { - break - } - } - } - n = Number(n); - } - }) - return [n, msg]; -} - -export default checkText; \ No newline at end of file diff --git a/src/lib/checkText.js b/src/lib/checkText.js new file mode 100644 index 0000000..3fdf3f4 --- /dev/null +++ b/src/lib/checkText.js @@ -0,0 +1,43 @@ +const checkNum = (string) => { + const num = Number(string); + if (!isNaN(num)) { + const isInt = num % 1 === 0 ? true : false; + return { + isInt: isInt, + num: num, + }; + } + + return { + isInt: false, + num: undefined, + }; +}; + +const checkText = (plainText, keyword) => { + const textList = plainText.split(' '); + let n = undefined; + let msg = undefined; + + const textLen = textList.length; + for (let i = textLen - 1; i >= 0; i--) { + let x = textList[i]; + + if (x.includes(keyword)) { + const text = x.split(keyword)[0]; + const { isInt, num } = checkNum(text); + + if (num < 0) { + msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μ–‘μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; + } else if (!isInt) { + msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; + n = num; + } else { + n = num; + } + return [n, isInt, msg]; + } + } +}; + +export default checkText; From 7e4a24d3a6f5dcdec5eb565455cb175a2066267c Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:03:29 +0900 Subject: [PATCH 07/33] style: add prettierrc --- .prettierrc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..255e44f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "bracketSpacing": true, + "jsxBracketSameLine": true, + "singleQuote": true, + "trailingComma": "all", + "arrowParens": "always", + "printWidth": 200, + "tabWidth": 2 +} From b8037ab64e5c59bc84cb5f2e9fd1756edb727b99 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:09:57 +0900 Subject: [PATCH 08/33] test: add console log to test --- src/lib/checkText.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 3fdf3f4..954f279 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -24,6 +24,7 @@ const checkText = (plainText, keyword) => { let x = textList[i]; if (x.includes(keyword)) { + console.log(x); const text = x.split(keyword)[0]; const { isInt, num } = checkNum(text); From c5922512df8a3aa306eecb497bd975dcd26adaf5 Mon Sep 17 00:00:00 2001 From: seol Date: Fri, 10 Jun 2022 05:10:58 +0900 Subject: [PATCH 09/33] rename: rename index to server --- index.js => server.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename index.js => server.js (100%) diff --git a/index.js b/server.js similarity index 100% rename from index.js rename to server.js From 26591cdf9aca0024b23628e75dbcb1f4b85ae77c Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:14:39 +0900 Subject: [PATCH 10/33] fix: fix import error --- server.js | 2 +- src/celebrate.js | 2 +- src/randomSelect.js | 2 +- src/summon.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index fd07806..99e11ac 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,6 @@ import express from 'express'; import dotenv from 'dotenv'; -import { summon } from './src/summon'; +import { summon } from './src/summon.js'; dotenv.config(); const port = process.env.PORT || 8080; diff --git a/src/celebrate.js b/src/celebrate.js index 73179f8..37c2d74 100644 --- a/src/celebrate.js +++ b/src/celebrate.js @@ -1,5 +1,5 @@ import { sendMessage } from './lib/sendMessage.js'; -import { sender } from './constants/sender'; +import { sender } from './constants/sender.js'; const celebrate = async (selectedManager, groupId, botName, isFull = true) => { let msg = ''; diff --git a/src/randomSelect.js b/src/randomSelect.js index 0df6c31..c4c48ba 100644 --- a/src/randomSelect.js +++ b/src/randomSelect.js @@ -1,5 +1,5 @@ import { sendMessage } from './lib/sendMessage.js'; -import { sender } from './constants/sender'; +import { sender } from './constants/sender.js'; const getMembers = async (groupId) => { let members = []; diff --git a/src/summon.js b/src/summon.js index 755e0ea..a1b567c 100644 --- a/src/summon.js +++ b/src/summon.js @@ -1,4 +1,4 @@ -import { sender } from "./constants/sender"; +import { sender } from "./constants/sender.js"; import { sendMessage } from "./lib/sendMessage.js"; import randomSelect from "./randomSelect.js"; import celebrate from "./celebrate.js"; From 9b1bfee7cc6f9bb171105f2156548b84d02530df Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:21:10 +0900 Subject: [PATCH 11/33] refactor: cast string in send message func --- src/celebrate.js | 2 +- src/lib/sendMessage.js | 2 +- src/randomSelect.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/celebrate.js b/src/celebrate.js index 37c2d74..adc41d5 100644 --- a/src/celebrate.js +++ b/src/celebrate.js @@ -27,7 +27,7 @@ const celebrate = async (selectedManager, groupId, botName, isFull = true) => { options: ['actAsManager'], }; - sendMessage(sender.GROUP, String(groupId), 'messages', { botName: botName }, body, 'post'); + sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); }; export default celebrate; diff --git a/src/lib/sendMessage.js b/src/lib/sendMessage.js index 8c786ed..e0bb009 100644 --- a/src/lib/sendMessage.js +++ b/src/lib/sendMessage.js @@ -5,7 +5,7 @@ import { send } from "./fetch.js"; export const sendMessage = (sender, senderId, additionalPath, searchParams, body, method) => { const urlWithSender = makeSenderUrl(makeUrl(BASE_URL, APP_VERSION), sender); - const urlWithSenderId = senderId ? `${urlWithSender}/${senderId}` : urlWithSender; + const urlWithSenderId = senderId ? `${urlWithSender}/${String(senderId)}` : urlWithSender; const urlWithPath = additionalPath ? `${urlWithSenderId}/${additionalPath}` : urlWithSenderId; const url = makeSearchParamsUrl(urlWithPath, searchParams); diff --git a/src/randomSelect.js b/src/randomSelect.js index c4c48ba..c5409ed 100644 --- a/src/randomSelect.js +++ b/src/randomSelect.js @@ -4,7 +4,7 @@ import { sender } from './constants/sender.js'; const getMembers = async (groupId) => { let members = []; - const response = sendMessage(sender.GROUP, String(groupId), 'sessions', undefined, undefined, 'get'); + const response = sendMessage(sender.GROUP, groupId, 'sessions', undefined, undefined, 'get'); const data = response.json(); await Promise.all( @@ -27,7 +27,7 @@ const selectMember = (memberList) => { }; const getMemberName = async (managerId) => { - const response = sendMessage(sender.MANAGER, String(managerId), '', undefined, undefined, 'get'); + const response = sendMessage(sender.MANAGER, managerId, '', undefined, undefined, 'get'); const data = await response.json(); return data['manager']['name']; }; From 9cb221168c2c0c7a2f90812a35df544b394d9195 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:22:39 +0900 Subject: [PATCH 12/33] fix: fix error handling order --- src/lib/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/utils.js b/src/lib/utils.js index 51b5e5a..30a2e8e 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -7,8 +7,8 @@ export const makeSenderUrl = (url, sender) => { }; export const makeSearchParamsUrl = (url, searchParams) => { - if (searchParams.constructor !== Object) throw new Error('searchParams should be object type!'); if (searchParams == undefined) return url; + if (searchParams.constructor !== Object) throw new Error('searchParams should be object type!'); const keys = Object.keys(searchParams); let urlWithSearchParams = `${url}?${String(keys[0])}=${String(searchParams[keys[0]])}`; From b1013ead34891fbce135c9b528c724a5b47e7777 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:24:37 +0900 Subject: [PATCH 13/33] refactor: import auth in fetch func --- src/config/auth.js | 3 +++ src/lib/fetch.js | 3 ++- src/lib/sendMessage.js | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/config/auth.js b/src/config/auth.js index 56658f6..4d28fa1 100644 --- a/src/config/auth.js +++ b/src/config/auth.js @@ -1,3 +1,6 @@ +import dotenv from 'dotenv'; +dotenv.config(); + export const auth = { accessKey: process.env.ACCESS_KEY, accessSecret: process.env.ACCESS_SECRET, diff --git a/src/lib/fetch.js b/src/lib/fetch.js index 71e9d1f..099ac1c 100644 --- a/src/lib/fetch.js +++ b/src/lib/fetch.js @@ -1,6 +1,7 @@ import fetch from 'node-fetch'; +import { auth } from '../config/auth.js'; -export const send = async (auth, url, body, method) => { +export const send = async (url, body, method) => { if (method !== 'post' && method !== 'get') throw new Error('wrong http method!'); return fetch(url, { diff --git a/src/lib/sendMessage.js b/src/lib/sendMessage.js index e0bb009..40235fe 100644 --- a/src/lib/sendMessage.js +++ b/src/lib/sendMessage.js @@ -1,4 +1,3 @@ -import { auth } from "../config/auth.js"; import { BASE_URL, APP_VERSION } from "../constants/url.js"; import { makeUrl, makeSenderUrl, makeSearchParamsUrl } from "./utils.js"; import { send } from "./fetch.js"; @@ -10,7 +9,7 @@ export const sendMessage = (sender, senderId, additionalPath, searchParams, body const url = makeSearchParamsUrl(urlWithPath, searchParams); try { - const response = await send(auth, url, body, method); + const response = await send(url, body, method); console.log(response.json()); return response; } catch (err) { From 230fd57263c6e46ffcd9d1194078338aca9c2dcb Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:27:22 +0900 Subject: [PATCH 14/33] fix: fix error handling to print message --- src/lib/fetch.js | 2 +- src/lib/utils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/fetch.js b/src/lib/fetch.js index 099ac1c..de58a70 100644 --- a/src/lib/fetch.js +++ b/src/lib/fetch.js @@ -2,7 +2,7 @@ import fetch from 'node-fetch'; import { auth } from '../config/auth.js'; export const send = async (url, body, method) => { - if (method !== 'post' && method !== 'get') throw new Error('wrong http method!'); + if (method !== 'post' && method !== 'get') console.log('wrong http method!'); return fetch(url, { headers: { diff --git a/src/lib/utils.js b/src/lib/utils.js index 30a2e8e..da83be2 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -8,7 +8,7 @@ export const makeSenderUrl = (url, sender) => { export const makeSearchParamsUrl = (url, searchParams) => { if (searchParams == undefined) return url; - if (searchParams.constructor !== Object) throw new Error('searchParams should be object type!'); + if (searchParams.constructor !== Object) console.log('searchParams should be object type!'); const keys = Object.keys(searchParams); let urlWithSearchParams = `${url}?${String(keys[0])}=${String(searchParams[keys[0]])}`; From f81134b5583e08b86c36887ac990190fd4213d2d Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:43:16 +0900 Subject: [PATCH 15/33] fix: fix additional path error --- src/lib/fetch.js | 2 +- src/lib/sendMessage.js | 2 ++ src/lib/utils.js | 2 +- src/summon.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/fetch.js b/src/lib/fetch.js index de58a70..e3d1b82 100644 --- a/src/lib/fetch.js +++ b/src/lib/fetch.js @@ -2,7 +2,7 @@ import fetch from 'node-fetch'; import { auth } from '../config/auth.js'; export const send = async (url, body, method) => { - if (method !== 'post' && method !== 'get') console.log('wrong http method!'); + if (method !== 'post' && method !== 'get') return console.log('wrong http method!'); return fetch(url, { headers: { diff --git a/src/lib/sendMessage.js b/src/lib/sendMessage.js index 40235fe..9694b38 100644 --- a/src/lib/sendMessage.js +++ b/src/lib/sendMessage.js @@ -3,6 +3,8 @@ import { makeUrl, makeSenderUrl, makeSearchParamsUrl } from "./utils.js"; import { send } from "./fetch.js"; export const sendMessage = (sender, senderId, additionalPath, searchParams, body, method) => { + if (additionalPath && additionalPath !== 'messages' && additionalPath !== 'sessions' && additionalPath !== 'announce') return console.log('wrong additional path!'); + const urlWithSender = makeSenderUrl(makeUrl(BASE_URL, APP_VERSION), sender); const urlWithSenderId = senderId ? `${urlWithSender}/${String(senderId)}` : urlWithSender; const urlWithPath = additionalPath ? `${urlWithSenderId}/${additionalPath}` : urlWithSenderId; diff --git a/src/lib/utils.js b/src/lib/utils.js index da83be2..6cec57c 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -8,7 +8,7 @@ export const makeSenderUrl = (url, sender) => { export const makeSearchParamsUrl = (url, searchParams) => { if (searchParams == undefined) return url; - if (searchParams.constructor !== Object) console.log('searchParams should be object type!'); + if (searchParams.constructor !== Object) return console.log('searchParams should be object type!'); const keys = Object.keys(searchParams); let urlWithSearchParams = `${url}?${String(keys[0])}=${String(searchParams[keys[0]])}`; diff --git a/src/summon.js b/src/summon.js index a1b567c..c8911fd 100644 --- a/src/summon.js +++ b/src/summon.js @@ -26,7 +26,7 @@ export const summon = (plainText, keyword, groupId, botName) => { const [n, isInt, msg] = checkText(plainText, keyword); if (msg) { - sendMessage(sender.GROUP, groupId, "message", {botName: botName},commonBody(msg), "post"); + sendMessage(sender.GROUP, groupId, "messages", {botName: botName},commonBody(msg), "post"); } if (n) { From b93d0ab04a67ac49785f148d41ee56b67596d4aa Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 13:52:45 +0900 Subject: [PATCH 16/33] fix: fix async await --- src/lib/fetch.js | 2 +- src/lib/sendMessage.js | 14 ++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/lib/fetch.js b/src/lib/fetch.js index e3d1b82..de09d1b 100644 --- a/src/lib/fetch.js +++ b/src/lib/fetch.js @@ -1,7 +1,7 @@ import fetch from 'node-fetch'; import { auth } from '../config/auth.js'; -export const send = async (url, body, method) => { +export const send = (url, body, method) => { if (method !== 'post' && method !== 'get') return console.log('wrong http method!'); return fetch(url, { diff --git a/src/lib/sendMessage.js b/src/lib/sendMessage.js index 9694b38..b2d8d40 100644 --- a/src/lib/sendMessage.js +++ b/src/lib/sendMessage.js @@ -1,6 +1,6 @@ -import { BASE_URL, APP_VERSION } from "../constants/url.js"; -import { makeUrl, makeSenderUrl, makeSearchParamsUrl } from "./utils.js"; -import { send } from "./fetch.js"; +import { BASE_URL, APP_VERSION } from '../constants/url.js'; +import { makeUrl, makeSenderUrl, makeSearchParamsUrl } from './utils.js'; +import { send } from './fetch.js'; export const sendMessage = (sender, senderId, additionalPath, searchParams, body, method) => { if (additionalPath && additionalPath !== 'messages' && additionalPath !== 'sessions' && additionalPath !== 'announce') return console.log('wrong additional path!'); @@ -10,11 +10,5 @@ export const sendMessage = (sender, senderId, additionalPath, searchParams, body const urlWithPath = additionalPath ? `${urlWithSenderId}/${additionalPath}` : urlWithSenderId; const url = makeSearchParamsUrl(urlWithPath, searchParams); - try { - const response = await send(url, body, method); - console.log(response.json()); - return response; - } catch (err) { - console.log(`${sender} failed to ${method} message ` + err); - } + return send(url, body, method); }; From 361307c6d90eccab045403c57e71000217ed7fb1 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 14:18:45 +0900 Subject: [PATCH 17/33] feat: add get random num func for unique selection --- src/lib/getRandomNum.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/lib/getRandomNum.js diff --git a/src/lib/getRandomNum.js b/src/lib/getRandomNum.js new file mode 100644 index 0000000..19f32d4 --- /dev/null +++ b/src/lib/getRandomNum.js @@ -0,0 +1,10 @@ +export const getRandomNum = (max, n) => { + const set = new Set(); + + while (set.size !== n) { + const randomNum = Math.floor(Math.random() * max); + set.add(randomNum); + } + + return set; +}; From 23332875757fb43bbccacb17252e91068d3eff91 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 14:19:02 +0900 Subject: [PATCH 18/33] refactor: change export method --- src/lib/checkText.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 954f279..9ccef23 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -14,7 +14,7 @@ const checkNum = (string) => { }; }; -const checkText = (plainText, keyword) => { +export const checkText = (plainText, keyword) => { const textList = plainText.split(' '); let n = undefined; let msg = undefined; @@ -40,5 +40,3 @@ const checkText = (plainText, keyword) => { } } }; - -export default checkText; From bd396737d3ad40377285f451955ad0cca3e7a3be Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 14:22:45 +0900 Subject: [PATCH 19/33] feat: add handling for limit num --- src/celebrate.js | 31 ++++++------ src/randomSelect.js | 61 +++++++---------------- src/summon.js | 115 +++++++++++++++++++++++++++++--------------- 3 files changed, 107 insertions(+), 100 deletions(-) diff --git a/src/celebrate.js b/src/celebrate.js index adc41d5..3805597 100644 --- a/src/celebrate.js +++ b/src/celebrate.js @@ -1,22 +1,7 @@ import { sendMessage } from './lib/sendMessage.js'; import { sender } from './constants/sender.js'; -const celebrate = async (selectedManager, groupId, botName, isFull = true) => { - let msg = ''; - if (!isFull) { - let halfName = ''; - for (let i = 0; i < selectedManager.length; i++) { - if (i % 2 == 0) { - halfName += selectedManager[i]; - } else { - halfName += '*'; - } - } - msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + halfName + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; - } else { - msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + selectedManager + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; - } - +export const celebrate = (msg, groupId, botName) => { const body = { blocks: [ { @@ -30,4 +15,16 @@ const celebrate = async (selectedManager, groupId, botName, isFull = true) => { sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); }; -export default celebrate; +export const personalAnnounce = (managerId, botName) => { + const body = { + blocks: [ + { + type: 'text', + value: 'πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!', + }, + ], + options: ['actAsManager'], + }; + + sendMessage(sender.ANNOUNCEMENTS, undefined, 'announce', { botName: botName, managerIds: managerId }, body, 'post'); +}; diff --git a/src/randomSelect.js b/src/randomSelect.js index c5409ed..2981b04 100644 --- a/src/randomSelect.js +++ b/src/randomSelect.js @@ -1,57 +1,30 @@ import { sendMessage } from './lib/sendMessage.js'; import { sender } from './constants/sender.js'; +import { getRandomNum } from './lib/getRandomNum.js'; -const getMembers = async (groupId) => { - let members = []; +export const getMembers = async (groupId) => { + const members = []; - const response = sendMessage(sender.GROUP, groupId, 'sessions', undefined, undefined, 'get'); - const data = response.json(); + const response = await sendMessage(sender.GROUP, groupId, 'sessions', undefined, undefined, 'get'); + const data = await response.json(); - await Promise.all( - data['sessions'].map(async (iter) => { - members.push(iter['personId']); - }), - ); + data['sessions'].map((iter) => { + members.push(iter['personId']); + }); return members; }; -const selectMember = (memberList) => { - let pickedIdx = 0; - let managerId = ''; - - pickedIdx = Math.floor(Math.random() * memberList.length); - managerId = memberList[pickedIdx]; - - return managerId; -}; +export const selectMembers = async (members, n) => { + const managers = []; + const selectedIdx = getRandomNum(members.length, n); -const getMemberName = async (managerId) => { - const response = sendMessage(sender.MANAGER, managerId, '', undefined, undefined, 'get'); - const data = await response.json(); - return data['manager']['name']; -}; + selectedIdx.forEach(async (idx) => { + const response = await sendMessage(sender.MANAGER, members[idx], '', undefined, undefined, 'get'); + const data = await response.json(); -const personalAnnounce = async (managerId, botName) => { - const body = { - blocks: [ - { - type: 'text', - value: 'πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!', - }, - ], - options: ['actAsManager'], - }; - - sendMessage(sender.ANNOUNCEMENTS, undefined, 'announce', { botName: botName, managerIds: String(managerId) }, body, 'post'); -}; + managers.push({ id: members[idx], name: data['manager']['name'] }); + }); -const randomSelect = async (groupId, botName) => { - const memberList = await getMembers(groupId); - const managerId = await selectMember(memberList); - const selectedManager = await getMemberName(managerId); - await personalAnnounce(managerId, botName); - return selectedManager; + return managers; }; - -export default randomSelect; diff --git a/src/summon.js b/src/summon.js index c8911fd..3bbae72 100644 --- a/src/summon.js +++ b/src/summon.js @@ -1,48 +1,85 @@ -import { sender } from "./constants/sender.js"; -import { sendMessage } from "./lib/sendMessage.js"; -import randomSelect from "./randomSelect.js"; -import celebrate from "./celebrate.js"; -import checkText from "./lib/checkText.js"; - -const commonBody = (msg) => { - return { +import { sender } from './constants/sender.js'; +import { sendMessage } from './lib/sendMessage.js'; +import { getMembers, selectMembers } from './randomSelect.js'; +import { celebrate, personalAnnounce } from './celebrate.js'; +import { checkText } from './lib/checkText.js'; + +export const summon = async (plainText, keyword, groupId, botName) => { + const [n, isInt, msg] = checkText(plainText, keyword); + + // negative number or real numbers + if (msg) { + const body = { + blocks: [ + { + type: 'text', + value: msg, + }, + ], + options: ['actAsManager'], + }; + sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); + } + + if (n) { + let isFull = true; + + const members = await getMembers(groupId); + console.log(members); + + // member limit exceeded number + if (members.length < n) { + const body = { blocks: [ - { - type: "text", - value: msg, - }, - ], - reactions: [ - { - emojiName: "πŸ’₯", - personKeys: ["string"], - } + { + type: 'text', + value: `🀒 MAX_NUM is ${members.length}`, + }, ], - options: ["actAsManager"], + options: ['actAsManager'], + }; + return sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); } -}; -export const summon = (plainText, keyword, groupId, botName) => { - const [n, isInt, msg] = checkText(plainText, keyword); + const num = isInt ? n : Math.floor(n); + + // unique random selection + const managers = await selectMembers(members, num); + + let msg = ''; + const MAX_MSG_NUM = 15; - if (msg) { - sendMessage(sender.GROUP, groupId, "messages", {botName: botName},commonBody(msg), "post"); + if (managers > MAX_MSG_NUM) { + managers.map((manager) => { + personalAnnounce(manager.id, botName); + msg += '\n' + 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + manager.name + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; + }); + celebrate(msg, groupId, botName); + } else { + managers.map((manager) => { + personalAnnounce(manager.id, botName); + msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + manager.name + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; + celebrate(msg, groupId, botName); + }); } - - if (n) { - let selectedManager = ""; - let isFull = true; - - const num = isInt ? n : Math.floor(n); - for (let i = 0; i < num; i++) { - selectedManager = await randomSelect(groupId, botName); - celebrate(selectedManager, groupId, botName, isFull); - } - if (!isInt) { - isFull = false; - selectedManager = await randomSelect(groupId, botName); - celebrate(selectedManager, groupId, botName, isFull); + if (!isInt) { + isFull = false; + const managers = await selectMembers(members, 1); + const name = managers[0].name; + + if (!isFull) { + let halfName = ''; + for (let i = 0; i < name.length; i++) { + if (i % 2 == 0) { + halfName += name[i]; + } else { + halfName += '*'; + } + } } + const msg = 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + halfName + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; + celebrate(msg, groupId, botName); } -} \ No newline at end of file + } +}; From a1823131f2ecc6f449bc2716bbe60b450fd319e0 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:23:47 +0900 Subject: [PATCH 20/33] feat: change return type set to array --- src/lib/getRandomNum.js | 2 +- src/randomSelect.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/getRandomNum.js b/src/lib/getRandomNum.js index 19f32d4..e7cc673 100644 --- a/src/lib/getRandomNum.js +++ b/src/lib/getRandomNum.js @@ -6,5 +6,5 @@ export const getRandomNum = (max, n) => { set.add(randomNum); } - return set; + return [...set]; }; diff --git a/src/randomSelect.js b/src/randomSelect.js index 2981b04..669ffb4 100644 --- a/src/randomSelect.js +++ b/src/randomSelect.js @@ -19,12 +19,12 @@ export const selectMembers = async (members, n) => { const managers = []; const selectedIdx = getRandomNum(members.length, n); - selectedIdx.forEach(async (idx) => { + for (let idx of selectedIdx) { const response = await sendMessage(sender.MANAGER, members[idx], '', undefined, undefined, 'get'); const data = await response.json(); managers.push({ id: members[idx], name: data['manager']['name'] }); - }); + } return managers; }; From cbe161030a9a65455f121fa0ae315e426310cc0d Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:30:24 +0900 Subject: [PATCH 21/33] fix: fix declaration order --- src/summon.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/summon.js b/src/summon.js index 3bbae72..7bdc9f8 100644 --- a/src/summon.js +++ b/src/summon.js @@ -68,8 +68,9 @@ export const summon = async (plainText, keyword, groupId, botName) => { const managers = await selectMembers(members, 1); const name = managers[0].name; + let halfName = ''; + if (!isFull) { - let halfName = ''; for (let i = 0; i < name.length; i++) { if (i % 2 == 0) { halfName += name[i]; From f1773dc51229042e9a25e76163825f9bcd5eab6e Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:32:28 +0900 Subject: [PATCH 22/33] feat: change negative num to positive num --- src/lib/checkText.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 9ccef23..b36d204 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -30,6 +30,7 @@ export const checkText = (plainText, keyword) => { if (num < 0) { msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μ–‘μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; + n = -num; } else if (!isInt) { msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; n = num; From 134663e2ebc82ec3ec3d04e245bedbb128369cd8 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:39:45 +0900 Subject: [PATCH 23/33] fix: change value --- src/lib/checkText.js | 4 ++-- src/summon.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index b36d204..83ec9f7 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -29,8 +29,8 @@ export const checkText = (plainText, keyword) => { const { isInt, num } = checkNum(text); if (num < 0) { - msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μ–‘μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; - n = -num; + msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μžμ—°μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; + n = -Math.floor(num); } else if (!isInt) { msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; n = num; diff --git a/src/summon.js b/src/summon.js index 7bdc9f8..365b07f 100644 --- a/src/summon.js +++ b/src/summon.js @@ -33,7 +33,7 @@ export const summon = async (plainText, keyword, groupId, botName) => { blocks: [ { type: 'text', - value: `🀒 MAX_NUM is ${members.length}`, + value: `🀒 MAX_NUM available is ${members.length}`, }, ], options: ['actAsManager'], From 19d21a67f2d45bc333628b20aa94ae8aa0c5e939 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:44:57 +0900 Subject: [PATCH 24/33] feat: add handling when num is zero --- src/lib/checkText.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 83ec9f7..6f8c172 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -28,7 +28,9 @@ export const checkText = (plainText, keyword) => { const text = x.split(keyword)[0]; const { isInt, num } = checkNum(text); - if (num < 0) { + if (num === 0) { + msg = 'πŸ€₯ 0λͺ…을 μ™œ 뽑아?'; + } else if (num < 0) { msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μžμ—°μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; n = -Math.floor(num); } else if (!isInt) { From 0fab46ecd8162e57793d230bf983ac87962b2298 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 16:50:19 +0900 Subject: [PATCH 25/33] feat: check num only string exist --- src/lib/checkText.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 6f8c172..ed3f1f0 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -1,15 +1,21 @@ const checkNum = (string) => { - const num = Number(string); - if (!isNaN(num)) { - const isInt = num % 1 === 0 ? true : false; + if (string) { + const num = Number(string); + if (!isNaN(num)) { + const isInt = num % 1 === 0 ? true : false; + return { + isInt: isInt, + num: num, + }; + } + return { - isInt: isInt, - num: num, + isInt: false, + num: undefined, }; } - return { - isInt: false, + isInt: undefined, num: undefined, }; }; From cdae859979b0dcc6e4e6fc96a8abd7f5258d121f Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 17:02:27 +0900 Subject: [PATCH 26/33] fix: fix isInt for negative num, last manager for float num --- src/lib/checkText.js | 6 +----- src/summon.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index ed3f1f0..85fe8e6 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -8,11 +8,6 @@ const checkNum = (string) => { num: num, }; } - - return { - isInt: false, - num: undefined, - }; } return { isInt: undefined, @@ -39,6 +34,7 @@ export const checkText = (plainText, keyword) => { } else if (num < 0) { msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μžμ—°μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; n = -Math.floor(num); + isInt = true; } else if (!isInt) { msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; n = num; diff --git a/src/summon.js b/src/summon.js index 365b07f..fdde654 100644 --- a/src/summon.js +++ b/src/summon.js @@ -41,11 +41,16 @@ export const summon = async (plainText, keyword, groupId, botName) => { return sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); } - const num = isInt ? n : Math.floor(n); + const num = isInt ? n : Math.ceil(n); // unique random selection const managers = await selectMembers(members, num); + let lastManager = undefined; + if (!isInt) { + lastManager = managers.pop(); + } + let msg = ''; const MAX_MSG_NUM = 15; @@ -63,10 +68,9 @@ export const summon = async (plainText, keyword, groupId, botName) => { }); } - if (!isInt) { + if (lastManager) { isFull = false; - const managers = await selectMembers(members, 1); - const name = managers[0].name; + const name = lastManager.name; let halfName = ''; From 4124bd3bfa2cbc7c55d1613d878a1f2cdcdba324 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 17:04:04 +0900 Subject: [PATCH 27/33] fix: change constant to let --- src/lib/checkText.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 85fe8e6..4778477 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -27,7 +27,7 @@ export const checkText = (plainText, keyword) => { if (x.includes(keyword)) { console.log(x); const text = x.split(keyword)[0]; - const { isInt, num } = checkNum(text); + let { isInt, num } = checkNum(text); if (num === 0) { msg = 'πŸ€₯ 0λͺ…을 μ™œ 뽑아?'; From 997062edb5dea9e93a6884dbcc98889c855b94a4 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 17:08:15 +0900 Subject: [PATCH 28/33] fix: fix condition --- src/summon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/summon.js b/src/summon.js index fdde654..12a9524 100644 --- a/src/summon.js +++ b/src/summon.js @@ -54,7 +54,7 @@ export const summon = async (plainText, keyword, groupId, botName) => { let msg = ''; const MAX_MSG_NUM = 15; - if (managers > MAX_MSG_NUM) { + if (managers.length > MAX_MSG_NUM) { managers.map((manager) => { personalAnnounce(manager.id, botName); msg += '\n' + 'πŸŽ‰μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€πŸŽ‰ ' + manager.name + ' λ‹˜μ΄ λ‹Ήμ²¨λ˜μ—ˆμŠ΅λ‹ˆλ‹€!'; From 5a7959fe3c307102171770e40d65610abd3c03da Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 17:18:20 +0900 Subject: [PATCH 29/33] fix: fix float condition --- src/lib/checkText.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index 4778477..e1729a9 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -35,7 +35,7 @@ export const checkText = (plainText, keyword) => { msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μžμ—°μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; n = -Math.floor(num); isInt = true; - } else if (!isInt) { + } else if (num && !isInt) { msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; n = num; } else { From 04d909b71fd9112666bc612184701ea3893d67bb Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 19:07:36 +0900 Subject: [PATCH 30/33] fix: change negative num not to floor --- src/lib/checkText.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lib/checkText.js b/src/lib/checkText.js index e1729a9..573e0a9 100644 --- a/src/lib/checkText.js +++ b/src/lib/checkText.js @@ -32,9 +32,8 @@ export const checkText = (plainText, keyword) => { if (num === 0) { msg = 'πŸ€₯ 0λͺ…을 μ™œ 뽑아?'; } else if (num < 0) { - msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μžμ—°μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; - n = -Math.floor(num); - isInt = true; + msg = '😩 μ—νœ΄.. 음수λ₯Ό μž…λ ₯ν•˜λŠ” 바보가 어딨어. λ‚΄κ°€ μ–‘μˆ˜λ‘œ λ°”κΏ”μ€„κ²Œ^^ λ‹€μŒλΆ€ν„΄ μž˜ν•΄.'; + n = -num; } else if (num && !isInt) { msg = 'μ•„ 또 μ†Œμˆ˜μ ..😀'; n = num; From b79ee5cfbc58f324d882fa41d671686e10e43f6f Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 19:07:52 +0900 Subject: [PATCH 31/33] style: change msg value --- src/summon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/summon.js b/src/summon.js index 12a9524..ff694c8 100644 --- a/src/summon.js +++ b/src/summon.js @@ -33,7 +33,7 @@ export const summon = async (plainText, keyword, groupId, botName) => { blocks: [ { type: 'text', - value: `🀒 MAX_NUM available is ${members.length}`, + value: `🀒 μ—¬κΈ° ${members.length}λͺ… 밖에 μ—†μ–΄. μ•ˆλΌ.`, }, ], options: ['actAsManager'], From 07d334aa85a27e9bb303860a3800fb835a92ae1a Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 21:30:22 +0900 Subject: [PATCH 32/33] feat: add routing --- server.js | 62 +------------------ src/celebrate.js | 30 --------- .../selectRandomMem.js} | 0 src/lib/stop.js | 11 ---- src/routes/index.js | 8 +++ src/routes/select/index.js | 28 +++++++++ src/{summon.js => routes/select/select.js} | 33 +++++++++- src/routes/stop/index.js | 42 +++++++++++++ src/routes/stop/stop.js | 11 ++++ 9 files changed, 122 insertions(+), 103 deletions(-) delete mode 100644 src/celebrate.js rename src/{randomSelect.js => lib/selectRandomMem.js} (100%) delete mode 100755 src/lib/stop.js create mode 100644 src/routes/index.js create mode 100644 src/routes/select/index.js rename src/{summon.js => routes/select/select.js} (75%) create mode 100644 src/routes/stop/index.js create mode 100755 src/routes/stop/stop.js diff --git a/server.js b/server.js index 276b0a5..fa2c29b 100644 --- a/server.js +++ b/server.js @@ -1,9 +1,7 @@ import express from 'express'; import dotenv from 'dotenv'; -import { summon } from './src/summon.js'; -import { sendMessage } from "./src/lib/sendMessage.js"; -import { sender } from "./src/constants/sender.js"; -import { stop } from "./src/lib/stop.js"; + +import router from './routes/index'; dotenv.config(); const port = process.env.PORT || 8080; @@ -13,61 +11,7 @@ const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -const botName = 'DevKor'; - -app.post('/select', async (res) => { - try { - const { body } = res; - const { event, entity } = body; - const { plainText = '', personType = '', chatId: groupId } = entity; - - const isPushEvent = event === 'push'; - const keyword = 'λͺ…'; - const hasKeyword = plainText.includes(keyword); - const isManager = personType === 'manager'; - - const needToSummon = isPushEvent && hasKeyword && isManager; - - if (needToSummon) { - summon(plainText, keyword, groupId, botName); - } - } catch (err) { - console.log(err); - } -}); - -app.post('/stop', async (res) => { - try { - const { body } = res; - const { event, entity } = body; - const { plainText = '', personType = '', chatId: groupId } = entity; - - const isPushEvent = event === 'push'; - const keyword = '/멈좰'; - const hasKeyword = plainText.includes(keyword); - const isManager = personType === 'manager'; - - const needToSummon = isPushEvent && hasKeyword && isManager; - - if (needToSummon) { - const body = { - blocks: [ - { - type: 'text', - value: "Okay! I will stop it!", - }, - ], - options: ['actAsManager'], - }; - sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); - setTimeout(() => { - stop() - }, 5000); - } - } catch (err) { - console.log(err); - } -}) +app.use('/', router); app.listen(port, () => { console.log(`Listening on port ${port}...`); diff --git a/src/celebrate.js b/src/celebrate.js deleted file mode 100644 index 3805597..0000000 --- a/src/celebrate.js +++ /dev/null @@ -1,30 +0,0 @@ -import { sendMessage } from './lib/sendMessage.js'; -import { sender } from './constants/sender.js'; - -export const celebrate = (msg, groupId, botName) => { - const body = { - blocks: [ - { - type: 'text', - value: msg, - }, - ], - options: ['actAsManager'], - }; - - sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); -}; - -export const personalAnnounce = (managerId, botName) => { - const body = { - blocks: [ - { - type: 'text', - value: 'πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!', - }, - ], - options: ['actAsManager'], - }; - - sendMessage(sender.ANNOUNCEMENTS, undefined, 'announce', { botName: botName, managerIds: managerId }, body, 'post'); -}; diff --git a/src/randomSelect.js b/src/lib/selectRandomMem.js similarity index 100% rename from src/randomSelect.js rename to src/lib/selectRandomMem.js diff --git a/src/lib/stop.js b/src/lib/stop.js deleted file mode 100755 index ac6d73e..0000000 --- a/src/lib/stop.js +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env node -import shell from "shelljs"; - -export const stop = () => { - shell.cd('~'); - - if (shell.exec("heroku ps:stop run").code !== 0) { - shell.echo("Error: Heroku server down failed"); - shell.exit(1); - } -} \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js new file mode 100644 index 0000000..aff4778 --- /dev/null +++ b/src/routes/index.js @@ -0,0 +1,8 @@ +import express from 'express'; + +const router = express.Router(); + +router.use('/select', require('./select')); +router.use('/stop', require('./stop')); + +module.exports = router; diff --git a/src/routes/select/index.js b/src/routes/select/index.js new file mode 100644 index 0000000..6216083 --- /dev/null +++ b/src/routes/select/index.js @@ -0,0 +1,28 @@ +import express from 'express'; +import { select } from './select.js'; + +const router = express.Router(); +const botName = 'DevKor'; + +router.post('/select', async (res) => { + try { + const { body } = res; + const { event, entity } = body; + const { plainText = '', personType = '', chatId: groupId } = entity; + + const isPushEvent = event === 'push'; + const keyword = 'λͺ…'; + const hasKeyword = plainText.includes(keyword); + const isManager = personType === 'manager'; + + const needToSummon = isPushEvent && hasKeyword && isManager; + + if (needToSummon) { + select(plainText, keyword, groupId, botName); + } + } catch (err) { + console.log(err); + } +}); + +module.exports = router; diff --git a/src/summon.js b/src/routes/select/select.js similarity index 75% rename from src/summon.js rename to src/routes/select/select.js index ff694c8..34c8c95 100644 --- a/src/summon.js +++ b/src/routes/select/select.js @@ -1,10 +1,37 @@ import { sender } from './constants/sender.js'; import { sendMessage } from './lib/sendMessage.js'; -import { getMembers, selectMembers } from './randomSelect.js'; -import { celebrate, personalAnnounce } from './celebrate.js'; +import { getMembers, selectMembers } from '../../lib/selectRandomMem.js'; import { checkText } from './lib/checkText.js'; -export const summon = async (plainText, keyword, groupId, botName) => { +const celebrate = (msg, groupId, botName) => { + const body = { + blocks: [ + { + type: 'text', + value: msg, + }, + ], + options: ['actAsManager'], + }; + + sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); +}; + +const personalAnnounce = (managerId, botName) => { + const body = { + blocks: [ + { + type: 'text', + value: 'πŸŽ‰λ‹Ήμ²¨πŸŽ‰ μΆ•ν•˜λ“œλ¦½λ‹ˆλ‹€!', + }, + ], + options: ['actAsManager'], + }; + + sendMessage(sender.ANNOUNCEMENTS, undefined, 'announce', { botName: botName, managerIds: managerId }, body, 'post'); +}; + +export const select = async (plainText, keyword, groupId, botName) => { const [n, isInt, msg] = checkText(plainText, keyword); // negative number or real numbers diff --git a/src/routes/stop/index.js b/src/routes/stop/index.js new file mode 100644 index 0000000..3f727fe --- /dev/null +++ b/src/routes/stop/index.js @@ -0,0 +1,42 @@ +import express from 'express'; +import { sendMessage } from './src/lib/sendMessage.js'; +import { sender } from './src/constants/sender.js'; +import { stop } from './stop.js'; + +const router = express.Router(); +const botName = 'DevKor'; + +router.post('/stop', async (res) => { + try { + const { body } = res; + const { event, entity } = body; + const { plainText = '', personType = '', chatId: groupId } = entity; + + const isPushEvent = event === 'push'; + const keyword = '/멈좰'; + const hasKeyword = plainText.includes(keyword); + const isManager = personType === 'manager'; + + const needToSummon = isPushEvent && hasKeyword && isManager; + + if (needToSummon) { + const body = { + blocks: [ + { + type: 'text', + value: 'Okay! I will stop it!', + }, + ], + options: ['actAsManager'], + }; + sendMessage(sender.GROUP, groupId, 'messages', { botName: botName }, body, 'post'); + setTimeout(() => { + stop(); + }, 5000); + } + } catch (err) { + console.log(err); + } +}); + +module.exports = router; diff --git a/src/routes/stop/stop.js b/src/routes/stop/stop.js new file mode 100755 index 0000000..0c5337c --- /dev/null +++ b/src/routes/stop/stop.js @@ -0,0 +1,11 @@ +#!/usr/bin/env node +import shell from 'shelljs'; + +export const stop = () => { + shell.cd('~'); + + if (shell.exec('heroku ps:stop run').code !== 0) { + shell.echo('Error: Heroku server down failed'); + shell.exit(1); + } +}; From c5b7c5077a851b8fe487ce5001554c4f455192c8 Mon Sep 17 00:00:00 2001 From: seol Date: Sat, 11 Jun 2022 21:32:03 +0900 Subject: [PATCH 33/33] fix: fix import error --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index fa2c29b..6e52503 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,7 @@ import express from 'express'; import dotenv from 'dotenv'; -import router from './routes/index'; +import router from './routes/index.js'; dotenv.config(); const port = process.env.PORT || 8080;