Skip to content

Commit

Permalink
feat: use webhook for logging (#625)
Browse files Browse the repository at this point in the history
* feat: use webhook for sending log

* fix: use property instead of hashmap

* fix: ci fail due to webhook URL validation

* chore: new url based on regex

* feat: send reports to webhook

* chore: env example
  • Loading branch information
eunwoo1104 authored Aug 31, 2023
1 parent b3bac55 commit 8015784
Show file tree
Hide file tree
Showing 10 changed files with 35 additions and 31 deletions.
13 changes: 7 additions & 6 deletions .env.demo.local
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ DISCORD_CLIENT_INTENTS=32767

GUILD_ID=653083797763522580
REVIEW_GUILD_ID=906537041326637086
REPORT_CHANNEL_ID=813255797823766568
LOGGING_CHANNEL_ID=844006379823955978
STATS_LOGGING_CHANNEL_ID=653227346962153472
REVIEW_LOG_CHANNEL_ID=906551334063439902
OPEN_REVIEW_LOG_CHANNEL_ID=1008376563731013643

GITHUB_CLIENT_ID=GH_CLIENT_ID
GITHUB_CLIENT_SECRET=GH_CLIENT_SECRET
Expand All @@ -31,4 +26,10 @@ CSRF_SECRET=CSRF_SECRET
DD_TRACE_DEBUG=true
DD_TRACE_ENABLED=true

NEXT_PUBLIC_HCAPTCHA_SITEKEY=HCAPTCHA_SITEKEY
NEXT_PUBLIC_HCAPTCHA_SITEKEY=HCAPTCHA_SITEKEY

LOG_WEBHOOK_URL=
REVIEW_LOG_WEBHOOK_URL=
OPEN_REVIEW_LOG_WEBHOOK_URL=
STATS_LOG_WEBHOOK_URL=
REPORT_WEBHOOK_URL=
4 changes: 2 additions & 2 deletions pages/api/v1/bots/servers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { get, update } from '@utils/Query'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { BotStatUpdate, BotStatUpdateSchema } from '@utils/Yup'
import { getStatsLoggingChannel } from '@utils/DiscordBot'
import { webhookClients } from '@utils/DiscordBot'
import { KoreanbotsEndPoints } from '@utils/Constants'
import { makeDiscordCodeblock } from '@utils/Tools'

Expand Down Expand Up @@ -42,7 +42,7 @@ const BotStats = RequestHandler()
const d = await update.updateServer(botInfo.id, validated.servers, undefined)
if(d===1 || d===2) return ResponseWrapper(res, { code: 403, message: `서버 수를 ${[null, '1만', '100만'][d]} 이상으로 설정하실 수 없습니다. 문의해주세요.`, version: 1 })
get.bot.clear(bot)
await getStatsLoggingChannel().send({
await webhookClients.internal.statsLog.send({
content: `[BOT/STATS] <@${botInfo.id}> (${botInfo.id})\n${makeDiscordCodeblock(`${botInfo.servers > validated.servers ? '-' : '+'} ${botInfo.servers} -> ${validated.servers} (${botInfo.servers > validated.servers ? '▼' : '▲'}${Math.abs(validated.servers - botInfo.servers)})`, 'diff')}`,
embeds: [new EmbedBuilder().setDescription(`${botInfo.name} - <@${botInfo.id}> ([${botInfo.id}](${KoreanbotsEndPoints.URL.bot(botInfo.id)}`)]
})
Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/bots/[id]/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { AddBotSubmit, AddBotSubmitSchema, CsrfCaptcha, ManageBot, ManageBotSche
import RequestHandler from '@utils/RequestHandler'
import { User } from '@types'
import { checkUserFlag, diff, inspect, makeDiscordCodeblock, objectDiff, serialize } from '@utils/Tools'
import { discordLog, getBotReviewLogChannel, getMainGuild } from '@utils/DiscordBot'
import { discordLog, getMainGuild, webhookClients } from '@utils/DiscordBot'
import { KoreanbotsEndPoints } from '@utils/Constants'

const patchLimiter = rateLimit({
Expand Down Expand Up @@ -91,7 +91,7 @@ const Bots = RequestHandler()
format: 'js'
})
const userinfo = await get.user.load(user)
await getBotReviewLogChannel().send({
await webhookClients.internal.reviewLog.send({
embeds: [
new EmbedBuilder()
.setAuthor({
Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/bots/[id]/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { get } from '@utils/Query'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { ReportSchema, Report} from '@utils/Yup'
import { getReportChannel } from '@utils/DiscordBot'
import { webhookClients } from '@utils/DiscordBot'
import { checkToken } from '@utils/Csrf'

const limiter = rateLimit({
Expand Down Expand Up @@ -38,7 +38,7 @@ const BotReport = RequestHandler().post(limiter)
})

if(!validated) return
await getReportChannel().send({ content: `Reported by <@${user}> (${user})\nReported **${bot.name}** <@${bot.id}> (${bot.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
await webhookClients.internal.reportChannel.send({ threadName: `봇-${bot.id}`, content: `Reported by <@${user}> (${user})\nReported **${bot.name}** <@${bot.id}> (${bot.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
return ResponseWrapper(res, { code: 200, message: '성공적으로 처리되었습니다.' })
})

Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/bots/[id]/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { get, update } from '@utils/Query'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { BotStatUpdate, BotStatUpdateSchema } from '@utils/Yup'
import { getStatsLoggingChannel } from '@utils/DiscordBot'
import { webhookClients } from '@utils/DiscordBot'
import { checkUserFlag, makeDiscordCodeblock } from '@utils/Tools'
import { KoreanbotsEndPoints } from '@utils/Constants'
import { User, WebhookType } from '@types'
Expand Down Expand Up @@ -70,7 +70,7 @@ const BotStats = RequestHandler().post(limiter)
timestamp: Date.now()
})
}
await getStatsLoggingChannel().send({
await webhookClients.internal.statsLog.send({
content: `[BOT/STATS] <@${botInfo.id}> (${botInfo.id})\n${makeDiscordCodeblock(`${botInfo.servers > validated.servers ? '-' : '+'} ${botInfo.servers} -> ${validated.servers} (${botInfo.servers > validated.servers ? '▼' : '▲'}${Math.abs(validated.servers - botInfo.servers)})`, 'diff')}`,
embeds: [new EmbedBuilder().setDescription(`${botInfo.name} - <@${botInfo.id}> ([${botInfo.id}](${KoreanbotsEndPoints.URL.bot(botInfo.id)}))`)]
})
Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/management/bots/submits/[id]/[date]/approve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import tracer from 'dd-trace'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { get, update } from '@utils/Query'
import { DiscordBot, getBotReviewLogChannel } from '@utils/DiscordBot'
import { DiscordBot, webhookClients } from '@utils/DiscordBot'
import { KoreanbotsEndPoints } from '@utils/Constants'

const ApproveBotSubmit = RequestHandler()
Expand All @@ -21,7 +21,7 @@ const ApproveBotSubmit = RequestHandler()
get.bot.clear(req.query.id)
const embed = new EmbedBuilder().setTitle('승인').setColor(Colors.Green).setDescription(`[${submit.id}/${submit.date}](${KoreanbotsEndPoints.URL.submittedBot(submit.id, submit.date)})`).setTimestamp()
if(req.body.reviewer) embed.addFields({name: '📃 정보', value: `심사자: ${req.body.reviewer}`})
await getBotReviewLogChannel().send({embeds: [embed]})
await webhookClients.internal.reviewLog.send({embeds: [embed]})
tracer.trace('botSubmits.approve', span => {
span.setTag('id', submit.id)
span.setTag('date', submit.date)
Expand Down
6 changes: 3 additions & 3 deletions pages/api/v2/management/bots/submits/[id]/[date]/deny.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import tracer from 'dd-trace'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { get, update } from '@utils/Query'
import { DiscordBot, getBotReviewLogChannel, getOpenBotReviewLogChannel } from '@utils/DiscordBot'
import { DiscordBot, webhookClients } from '@utils/DiscordBot'
import { BotSubmissionDenyReasonPresetsName, KoreanbotsEndPoints } from '@utils/Constants'

const DenyBotSubmit = RequestHandler()
Expand All @@ -19,10 +19,10 @@ const DenyBotSubmit = RequestHandler()
get.botSubmit.clear(JSON.stringify({ id: req.query.id, date: req.query.date }))
const embed = new EmbedBuilder().setTitle('거부').setColor(Colors.Red).setDescription(`[${submit.id}/${submit.date}](${KoreanbotsEndPoints.URL.submittedBot(submit.id, submit.date)})`).setTimestamp()
if(req.body.reviewer || req.body.reason) embed.addFields({name: '📃 정보', value: `${req.body.reason ? `사유: ${BotSubmissionDenyReasonPresetsName[req.body.reason] || req.body.reason}\n`: ''}${req.body.reviewer ? `심사자: ${req.body.reviewer}` : ''}`})
await getBotReviewLogChannel().send({embeds: [embed]})
await webhookClients.internal.reviewLog.send({embeds: [embed]})
const openEmbed = new EmbedBuilder().setTitle('거부').setColor(Colors.Red).setDescription(`<@${submit.id}> (${submit.id})`).setTimestamp()
if(req.body.reason) openEmbed.addFields({name: '📃 사유', value: `${req.body.reason ? `${BotSubmissionDenyReasonPresetsName[req.body.reason] || req.body.reason}\n`: '없음'}`})
await getOpenBotReviewLogChannel().send({embeds: [openEmbed]})
await webhookClients.internal.openReviewLog.send({embeds: [openEmbed]})
tracer.trace('botSubmits.deny', span => {
span.setTag('id', submit.id)
span.setTag('date', submit.date)
Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/servers/[id]/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { get } from '@utils/Query'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { ReportSchema, Report} from '@utils/Yup'
import { getReportChannel } from '@utils/DiscordBot'
import { webhookClients } from '@utils/DiscordBot'
import { checkToken } from '@utils/Csrf'

const limiter = rateLimit({
Expand Down Expand Up @@ -38,7 +38,7 @@ const ServerReport = RequestHandler().post(limiter)
})

if(!validated) return
await getReportChannel().send({content: `Reported by <@${user}> (${user})\nReported **${server.name}** (${server.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
await webhookClients.internal.reportChannel.send({ threadName: `서버-${server.id}`, content: `Reported by <@${user}> (${user})\nReported **${server.name}** (${server.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
return ResponseWrapper(res, { code: 200, message: '성공적으로 처리되었습니다.' })
})

Expand Down
4 changes: 2 additions & 2 deletions pages/api/v2/users/[id]/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { get } from '@utils/Query'
import RequestHandler from '@utils/RequestHandler'
import ResponseWrapper from '@utils/ResponseWrapper'
import { ReportSchema, Report} from '@utils/Yup'
import { getReportChannel } from '@utils/DiscordBot'
import { webhookClients } from '@utils/DiscordBot'
import { checkToken } from '@utils/Csrf'

const limiter = rateLimit({
Expand Down Expand Up @@ -37,7 +37,7 @@ const UserReport = RequestHandler().post(limiter)
})

if(!validated) return
await getReportChannel().send({ content: `Reported by <@${user}> (${user})\nReported **${userInfo.tag === '0' ? userInfo.globalName + ' @' + userInfo.username : userInfo.username + '#' + userInfo.tag} <@${userInfo.id}> (${userInfo.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
await webhookClients.internal.reportChannel.send({ threadName: `유저-${userInfo.id}`, content: `Reported by <@${user}> (${user})\nReported **${userInfo.tag === '0' ? userInfo.globalName + ' @' + userInfo.username : userInfo.username + '#' + userInfo.tag}** <@${userInfo.id}> (${userInfo.id})\nCategory ${req.body.category}\nDesc\n\`\`\`${req.body.description}\`\`\``, allowedMentions: { parse: ['users'] }})
return ResponseWrapper(res, { code: 200, message: '성공적으로 처리되었습니다.' })
})

Expand Down
19 changes: 11 additions & 8 deletions utils/DiscordBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ export const ServerListDiscordBot = new Discord.Client({
intents: []
})

const dummyURL = 'https://discord.com/api/webhooks/123123123123123123/asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf'

export const webhookClients = {
bot: new Discord.Collection<string, Discord.WebhookClient>(),
server: new Discord.Collection<string, Discord.WebhookClient>()
server: new Discord.Collection<string, Discord.WebhookClient>(),
internal: {
log: new Discord.WebhookClient({url: process.env.LOG_WEBHOOK_URL ?? dummyURL}),
reviewLog: new Discord.WebhookClient({url: process.env.REVIEW_LOG_WEBHOOK_URL ?? dummyURL}),
openReviewLog: new Discord.WebhookClient({url: process.env.OPEN_REVIEW_LOG_WEBHOOK_URL ?? dummyURL}),
statsLog: new Discord.WebhookClient({url: process.env.STATS_LOG_WEBHOOK_URL ?? dummyURL}),
reportChannel: new Discord.WebhookClient({url: process.env.REPORT_WEBHOOK_URL ?? dummyURL})
}
}

DiscordBot.on('ready', async () => {
Expand All @@ -23,15 +32,9 @@ DiscordBot.login(process.env.DISCORD_TOKEN)
ServerListDiscordBot.login(process.env.DISCORD_SERVERLIST_TOKEN)

export const getMainGuild = () => DiscordBot.guilds.cache.get(process.env.GUILD_ID)
export const getReviewGuild = () => DiscordBot.guilds.cache.get(process.env.REVIEW_GUILD_ID)
export const getReportChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.REPORT_CHANNEL_ID) as Discord.TextChannel
export const getLoggingChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.LOGGING_CHANNEL_ID) as Discord.TextChannel
export const getStatsLoggingChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.STATS_LOGGING_CHANNEL_ID) as Discord.TextChannel
export const getBotReviewLogChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel
export const getOpenBotReviewLogChannel = (): Discord.TextChannel => DiscordBot.channels.cache.get(process.env.OPEN_REVIEW_LOG_CHANNEL_ID) as Discord.TextChannel

export const discordLog = async (type: string, issuerID: string, embed?: Discord.EmbedBuilder, attachment?: { content: string, format: string}, content?: string): Promise<void> => {
getLoggingChannel().send({
webhookClients.internal.log.send({
content: `[${type}] <@${issuerID}> (${issuerID})\n${content || ''}`,
embeds: [embed && embed.setTitle(type).setTimestamp(new Date())],
...(attachment && { files: [
Expand Down

0 comments on commit 8015784

Please sign in to comment.