Skip to content

Commit

Permalink
Add: slack notification about abusing user
Browse files Browse the repository at this point in the history
  • Loading branch information
kmc7468 committed Feb 21, 2024
1 parent 9137a3c commit 8232539
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 56 deletions.
42 changes: 33 additions & 9 deletions src/modules/slackNotification.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ const { slackWebhookUrl: slackUrl } = require("../../loadenv");
const axios = require("axios");
const logger = require("../modules/logger");

module.exports.notifyToReportChannel = (reportUser, report) => {
const sendTextToReportChannel = (text) => {
if (!slackUrl.report) return;

const data = {
text: `${reportUser}님으로부터 신고가 접수되었습니다.
신고자 ID: ${report.creatorId}
신고 ID: ${report.reportedId}
방 ID: ${report.roomId ?? ""}
사유: ${report.type}
기타: ${report.etcDetail}
`,
text,
};
const config = { "Content-Type": "application/json" };

Expand All @@ -26,3 +19,34 @@ module.exports.notifyToReportChannel = (reportUser, report) => {
logger.error("Fail to send slack webhook", err);
});
};

const notifyReportToReportChannel = (reportUser, report) => {
sendTextToReportChannel(
`${reportUser}님으로부터 신고가 접수되었습니다.
신고자 ID: ${report.creatorId}
신고 ID: ${report.reportedId}
방 ID: ${report.roomId ?? ""}
사유: ${report.type}
기타: ${report.etcDetail}`
);
};

const notifyAbusingToReportChannel = (
abusingUser,
{ from, to, time, maxPartLength }
) => {
sendTextToReportChannel(
`${abusingUser}님이 어뷰징이 의심되는 방을 생성하려고 시도했습니다.
출발지: ${from}
도착지: ${to}
출발 시간: ${time}
최대 참여 가능 인원: ${maxPartLength}명`
);
};

module.exports = {
notifyReportToReportChannel,
notifyAbusingToReportChannel,
};
4 changes: 2 additions & 2 deletions src/services/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const { reportPopulateOption } = require("../modules/populates/reports");
const { sendReportEmail } = require("../modules/stores/aws");
const logger = require("../modules/logger");
const emailPage = require("../views/emailNoSettlementPage");
const { notifyToReportChannel } = require("../modules/slackNotification");
const { notifyReportToReportChannel } = require("../modules/slackNotification");

const createHandler = async (req, res) => {
try {
Expand Down Expand Up @@ -40,7 +40,7 @@ const createHandler = async (req, res) => {

await report.save();

notifyToReportChannel(user.nickname, report);
notifyReportToReportChannel(user.nickname, report);

if (report.type === "no-settlement") {
const emailRoomName = room ? room.name : "";
Expand Down
110 changes: 65 additions & 45 deletions src/services/rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const {
formatSettlement,
getIsOver,
} = require("../modules/populates/rooms");
const {
notifyAbusingToReportChannel,
} = require("../modules/slackNotification");

// 이벤트 코드입니다.
const { contracts } = require("../lottery");
Expand Down Expand Up @@ -106,23 +109,62 @@ const createHandler = async (req, res) => {
}
};

const checkIsAbusing = (
{ from, to, maxPartLength },
countRecentlyMadeRooms,
candidateRoomsByTime
) => {
/**
* 방을 생성하였을 때, 다음 조건 중 하나라도 만족하게 되면 어뷰징 가능성이 있다고 판단합니다.
* 1. 참여한 방 중, 생성하려는 방의 출발 시간 앞 뒤 12시간 내에 출발하는 방이 3개 이상인 경우
* 2. 참여한 방 중, 생성하려는 방의 출발 시간 앞 뒤 12시간 내에 출발하는 방이 2개이고, 다음 조건 중 하나 이상을 만족하는 경우
* a. 두 방의 출발 시간 간격이 1시간 이하인 경우
* b. 두 방의 출발 시간 간격이 1시간 초과이고, 다음 조건 중 하나 이상을 만족하는 경우
* i. 두 방의 출발지가 같은 경우
* ii. 두 방의 목적지가 같은 경우
* iii. 먼저 출발하는 방의 목적지와 나중에 출발하는 방의 출발지가 다른 경우
* iv. 두 방의 최대 탑승 가능 인원이 모두 2명인 경우
* 3. 최근 24시간 내에 생성한 방이 4개 이상인 경우
*/

if (countRecentlyMadeRooms + 1 >= 4) return true; // 조건 3

if (candidateRoomsByTime.length + 1 >= 3) return true; // 조건 1
if (candidateRoomsByTime.length + 1 < 2) return false; // 조건 2의 여집합

let firstRoom = {
from: candidateRoomsByTime[0].from.toString(),
to: candidateRoomsByTime[0].to.toString(),
time: candidateRoomsByTime[0].time,
maxPartLength: candidateRoomsByTime[0].maxPartLength,
};
let secondRoom = {
from,
to,
time: dateTime,
maxPartLength,
};
if (secondRoom.time < firstRoom.time) {
[firstRoom, secondRoom] = [secondRoom, firstRoom];
}

if (secondRoom.time - firstRoom.time <= 3600000) return true; // 조건 2-a
if (
firstRoom.from === secondRoom.from ||
firstRoom.to === secondRoom.to ||
firstRoom.to !== secondRoom.from
)
return true; // 조건 2-b-i, 2-b-ii, 2-b-iii
if (firstRoom.maxPartLength === 2 && secondRoom.maxPartLength === 2)
return true; // 조건 2-b-iv

return false;
};

const createTestHandler = async (req, res) => {
const { from, to, time, maxPartLength } = req.body;
const { time } = req.body;

try {
/**
* 방을 생성하였을 때, 다음 조건 중 하나라도 만족하게 되면 어뷰징 가능성이 있다고 판단합니다.
* 1. 참여한 방 중, 생성하려는 방의 출발 시간 앞 뒤 12시간 내에 출발하는 방이 3개 이상인 경우
* 2. 참여한 방 중, 생성하려는 방의 출발 시간 앞 뒤 12시간 내에 출발하는 방이 2개이고, 다음 조건 중 하나 이상을 만족하는 경우
* a. 두 방의 출발 시간 간격이 1시간 미만인 경우
* b. 두 방의 출발 시간 간격이 1시간 이상이고, 다음 조건 중 하나 이상을 만족하는 경우
* i. 두 방의 출발지가 같은 경우
* ii. 두 방의 목적지가 같은 경우
* iii. 먼저 출발하는 방의 목적지와 나중에 출발하는 방의 출발지가 다른 경우
* iv. 두 방의 최대 탑승 가능 인원이 모두 2명인 경우
* 3. 최근 24시간 내에 생성한 방이 4개 이상인 경우
*/

const countRecentlyMadeRooms = await roomModel.countDocuments({
madeat: { $gte: new Date(req.timestamp - 86400000) }, // 밀리초 단위로 24시간을 나타냅니다.
"part.0.user": req.userOid, // 방 최초 생성자를 저장하는 필드가 없으므로, 첫 번째 참여자를 생성자로 간주합니다.
Expand All @@ -131,7 +173,6 @@ const createTestHandler = async (req, res) => {
return res
.status(500)
.json({ error: "Rooms/create/test : internal server error" });
if (countRecentlyMadeRooms + 1 >= 4) return res.json({ result: false }); // 조건 3

const dateTime = new Date(time);
const candidateRoomsByTime = await roomModel
Expand All @@ -152,38 +193,17 @@ const createTestHandler = async (req, res) => {
return res
.status(500)
.json({ error: "Rooms/create/test : internal server error" });
if (candidateRoomsByTime.length + 1 >= 3)
return res.json({ result: false }); // 조건 1
if (candidateRoomsByTime.length + 1 < 2) return res.json({ result: true }); // 조건 2의 여집합

let firstRoom = {
from: candidateRoomsByTime[0].from.toString(),
to: candidateRoomsByTime[0].to.toString(),
time: candidateRoomsByTime[0].time,
maxPartLength: candidateRoomsByTime[0].maxPartLength,
};
let secondRoom = {
from,
to,
time: dateTime,
maxPartLength,
};
if (secondRoom.time < firstRoom.time) {
[firstRoom, secondRoom] = [secondRoom, firstRoom];

const isAbusing = checkIsAbusing(
req.body,
countRecentlyMadeRooms,
candidateRoomsByTime
);
if (isAbusing) {
notifyAbusingToReportChannel(req.userId, req.body);
}

if (secondRoom.time - firstRoom.time < 3600000)
return res.json({ result: false }); // 조건 2-a
if (
firstRoom.from === secondRoom.from ||
firstRoom.to === secondRoom.to ||
firstRoom.to !== secondRoom.from
)
return res.json({ result: false }); // 조건 2-b-i, 2-b-ii, 2-b-iii
if (firstRoom.maxPartLength === 2 && secondRoom.maxPartLength === 2)
return res.json({ result: false }); // 조건 2-b-iv

return res.json({ result: true });
return res.json({ result: !isAbusing });
} catch (err) {
logger.error(err);
res.status(500).json({
Expand Down

0 comments on commit 8232539

Please sign in to comment.