From 94bd79f13a46446dc290e392f995cfb4cfeca638 Mon Sep 17 00:00:00 2001 From: Sefa <50076109+Seefaaa@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:12:08 +0300 Subject: [PATCH] Verify log channel --- config.example.toml | 1 + src/commands/api/verify.ts | 43 ++++++++++++++++++++++++++++++--- src/config.ts | 18 +++++++++++--- src/events/interactionCreate.ts | 13 +++++----- src/events/ready.ts | 3 ++- src/index.ts | 4 +-- src/{utils => }/logger.ts | 6 ++++- src/types.d.ts | 3 +-- src/utils/index.ts | 1 - 9 files changed, 70 insertions(+), 22 deletions(-) rename src/{utils => }/logger.ts (85%) diff --git a/config.example.toml b/config.example.toml index cb2a31f..1b4c90e 100644 --- a/config.example.toml +++ b/config.example.toml @@ -5,6 +5,7 @@ guild_id = "" [log] path = "bot.json.log" colorize = true +verify_channel = "" [api] url = "https://api.turkb.us/v2" diff --git a/src/commands/api/verify.ts b/src/commands/api/verify.ts index 32f648a..cbe4d5c 100644 --- a/src/commands/api/verify.ts +++ b/src/commands/api/verify.ts @@ -1,13 +1,28 @@ import { type ChatInputCommandInteraction, + type Client, PermissionFlagsBits, SlashCommandBuilder, + type TextChannel, } from 'discord.js'; +import config from '@/config'; import { verifyRegex } from '@/constants'; +import logger from '@/logger'; import type { Command } from '@/types'; import { post } from '@/utils'; +const logVerify = async (client: Client, message: string) => { + const verifyLogChannel = (await client.channels.fetch( + config.log.verifyChannel + )) as TextChannel; + + verifyLogChannel.send({ + content: message, + allowedMentions: { parse: [] }, + }); +}; + export class VerifyCommand implements Command { public builder = new SlashCommandBuilder() .setName('verify') @@ -28,7 +43,7 @@ export class VerifyCommand implements Command { }); if (statusCode === 200) { - interaction.client.logger.info( + logger.info( `Verified user [${user.tag}](${user.id}) with ckey \`${ckey}\`` ); @@ -36,6 +51,11 @@ export class VerifyCommand implements Command { content: `Discord hesabın \`${ckey}\` adlı BYOND hesabına bağlandı.`, ephemeral: true, }); + + logVerify( + interaction.client, + `${user} hesabını \`${ckey}\` adlı BYOND hesabına bağladı.` + ); } else if (statusCode === 404) { if (!verifyRegex.test(code)) { interaction.reply({ @@ -107,13 +127,18 @@ export class UnverifyCommand implements Command { }); if (statusCode === 200) { - interaction.client.logger.info( + logger.info( `Unverified user [${user.tag}](${user.id}) with ckey \`${ckey}\` by [${interaction.user.tag}](${interaction.user.id})` ); interaction.reply( `<@${user.id}> adlı Discord hesabı ile \`${ckey}\` adlı BYOND hesabının bağlantısı kaldırıldı.` ); + + logVerify( + interaction.client, + `${user} adlı Discord hesabı ile \`${ckey}\` adlı BYOND hesabının bağlantısı ${interaction.user} tarafından kaldırıldı.` + ); } else if (statusCode === 409) { interaction.reply('Hesap zaten bağlı değil.'); } @@ -131,13 +156,18 @@ export class UnverifyCommand implements Command { const userId = discordId.slice(1); const user = await interaction.client.users.fetch(userId); - interaction.client.logger.info( + logger.info( `Unverified user [${user.tag}](${userId}) with ckey \`${ckey}\` by [${interaction.user.tag}](${interaction.user.id})` ); interaction.reply( `\`${ckey}\` adlı BYOND hesabı ile <${discordId}> adlı Discord hesabının bağlantısı kaldırıldı.` ); + + logVerify( + interaction.client, + `${user} adlı Discord hesabı ile \`${ckey}\` adlı BYOND hesabının bağlantısı ${interaction.user} tarafından kaldırıldı.` + ); } else if (statusCode === 404) { interaction.reply('Hesap bulunamadı.'); } else if (statusCode === 409) { @@ -178,13 +208,18 @@ export class ForceVerifyCommand implements Command { }); if (statusCode === 200) { - interaction.client.logger.info( + logger.info( `Force-verified user [${user.tag}](${user.id}) with ckey \`${ckey}\` by [${interaction.user.tag}](${interaction.user.id})` ); interaction.reply( `<@${user.id}> adlı Discord hesabı \`${ckey}\` adlı BYOND hesabına bağlandı.` ); + + logVerify( + interaction.client, + `${user} adlı Discord hesabı ile \`${ckey}\` adlı BYOND hesabı ${interaction.user} tarafından bağlandı.` + ); } else if (statusCode === 404) { interaction.reply('Oyuncu bulunamadı.'); } else if (statusCode === 409) { diff --git a/src/config.ts b/src/config.ts index f8dada8..627b555 100644 --- a/src/config.ts +++ b/src/config.ts @@ -5,7 +5,7 @@ import { TOML } from 'bun'; import type { Config } from '@/types'; if (!existsSync('config.toml')) { - throw new Error('Config: config.toml does not exist in cwd'); + throw new Error('Config: config.toml does not exist on cwd'); } const config = TOML.parse(readFileSync('config.toml', 'utf8')) as Config; @@ -13,10 +13,14 @@ const config = TOML.parse(readFileSync('config.toml', 'utf8')) as Config; export const botToken = config.bot_token; export const applicationId = config.application_id; export const guildId = config.guild_id; -export const log = config.log; +export const log = { + path: config.log?.path, + colorize: config.log?.colorize, + verifyChannel: config.log?.verify_channel, +}; export const api = config.api; -export default { +const default_ = { botToken, applicationId, guildId, @@ -24,6 +28,10 @@ export default { api, }; +export default default_; + +// Validate config + if (typeof botToken !== 'string' || botToken.length === 0) { throw new Error('Config: bot_token is required'); } @@ -44,6 +52,10 @@ if (typeof log.colorize !== 'boolean') { throw new Error('Config: log.colorize is required'); } +if (typeof log.verifyChannel !== 'string' || log.verifyChannel.length === 0) { + throw new Error('Config: log.verify_channel is required'); +} + if (typeof api.url !== 'string' || api.url.length === 0) { throw new Error('Config: api.url is required'); } diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index b5856e0..4444706 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -5,6 +5,7 @@ import { Events, } from 'discord.js'; +import logger from '@/logger'; import type { Command, Event } from '@/types'; import { get } from '@/utils'; @@ -18,7 +19,7 @@ export class InteractionCreateEvent implements Event { await handleAutocomplete(interaction); } } catch (error) { - interaction.client.logger.error(error); + logger.error(error); } } } @@ -29,16 +30,14 @@ async function handleChatInputCommand( const command = interaction.client.commands.get(interaction.commandName); if (!command) { - interaction.client.logger.error( - `No command matching ${interaction.commandName} was found.` - ); + logger.error(`No command matching ${interaction.commandName} was found.`); return; } try { await command.execute(interaction); } catch (error) { - interaction.client.logger.error(error); + logger.error(error); try { if (interaction.replied || interaction.deferred) { interaction.followUp({ @@ -64,7 +63,7 @@ async function handleAutocomplete(interaction: AutocompleteInteraction) { const command = interaction.client.commands.get(interaction.commandName); if (!command) { - interaction.client.logger.error( + logger.error( `No autocomplete matching ${interaction.commandName} was found.` ); return; @@ -81,7 +80,7 @@ async function handleAutocomplete(interaction: AutocompleteInteraction) { await command.autocomplete!(interaction); } catch (error) { - interaction.client.logger.error(error); + logger.error(error); try { interaction.respond([]); } catch {} diff --git a/src/events/ready.ts b/src/events/ready.ts index e010bbf..bfb81cd 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -1,11 +1,12 @@ import { type Client, Events } from 'discord.js'; +import logger from '@/logger'; import type { Event } from '@/types'; export class ReadyEvent implements Event { public name = Events.ClientReady; public once = true; public async execute(client: Client) { - client.logger.info(`Logged in as ${client.user?.tag}!`); + logger.info(`Logged in as ${client.user?.tag}!`); } } diff --git a/src/index.ts b/src/index.ts index 6723323..fe31c32 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import { Client, Collection, GatewayIntentBits } from 'discord.js'; import { botToken } from '@/config'; -import { createLogger, deployCommands } from '@/utils'; +import { deployCommands } from '@/utils'; const client = new Client({ intents: [ @@ -12,8 +12,6 @@ const client = new Client({ ], }); -client.logger = await createLogger(); - client.commands = new Collection(); for (const Command of Object.values(await import('./commands'))) { diff --git a/src/utils/logger.ts b/src/logger.ts similarity index 85% rename from src/utils/logger.ts rename to src/logger.ts index 5b68ab7..70bab3b 100644 --- a/src/utils/logger.ts +++ b/src/logger.ts @@ -5,7 +5,7 @@ import pretty from 'pino-pretty'; import config from '@/config'; import { name } from '@/package'; -export async function createLogger() { +async function createLogger() { const prettyStream = pretty({ colorize: config.log.colorize, ignore: 'pid,hostname', @@ -24,3 +24,7 @@ export async function createLogger() { return logger; } + +const logger = await createLogger(); + +export default logger; diff --git a/src/types.d.ts b/src/types.d.ts index 161d49c..6dba650 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -5,7 +5,6 @@ import type { SlashCommandOptionsOnlyBuilder, SlashCommandSubcommandsOnlyBuilder, } from 'discord.js'; -import type { Logger } from 'pino'; export interface Command { builder: @@ -30,6 +29,7 @@ export interface Config { log: { path: string; colorize: boolean; + verify_channel: string; }; api: { url: string; @@ -40,6 +40,5 @@ export interface Config { declare module 'discord.js' { export interface Client { commands: Collection; - logger: Logger; } } diff --git a/src/utils/index.ts b/src/utils/index.ts index c32d364..4df61c3 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,4 +1,3 @@ export * from './api'; export * from './deployCommands'; -export * from './logger'; export * from './time';