This commit is contained in:
2026-05-26 14:15:09 +09:00
parent 55d402f606
commit d6b36c43c2
33 changed files with 1496 additions and 0 deletions

27
src/commands/example.ts Normal file
View File

@@ -0,0 +1,27 @@
import { client } from "../index";
import { Command } from "../types/Command";
import { Message, ChatInputApplicationCommandData, ChannelType, ChatInputCommandInteraction } from "discord.js";
/** example 명령어 */
export default class implements Command {
/** 해당 명령어 설명 */
name = "example";
visible = false;
aliases: string[] = ["예시"];
description: string = "예시 명령어";
metaData: ChatInputApplicationCommandData = {
name: this.name,
description: this.description,
};
/** 실행되는 부분 */
async slashRun(interaction: ChatInputCommandInteraction) {
await interaction.editReply({ embeds: [ client.mkembed({
title: "예시 명령어",
}) ] });
}
async messageRun(message: Message) {
if (message.channel?.type !== ChannelType.GuildText) return;
return await message.channel.send({ content: "예시 명령어" }).then(m => client.msgDelete(m, 5));
}
}

105
src/commands/help.ts Normal file
View File

@@ -0,0 +1,105 @@
import { client, handler } from "../index";
import { Command } from "../types/Command";
import { CacheType, Message, ActionRowBuilder, EmbedBuilder, ChatInputApplicationCommandData, StringSelectMenuBuilder, StringSelectMenuInteraction, ApplicationCommandOptionType, ChannelType, ChatInputCommandInteraction } from "discord.js";
/** help 명령어 */
export default class implements Command {
/** 해당 명령어 설명 */
name = "help";
visible = true;
aliases: string[] = ["도움말"];
description: string = "명령어 확인";
metaData: ChatInputApplicationCommandData = {
name: this.name,
description: this.description,
};
/** 실행되는 부분 */
async slashRun(interaction: ChatInputCommandInteraction) {
await interaction.editReply(this.getHelp());
}
async messageRun(message: Message) {
if (message.channel?.type !== ChannelType.GuildText) return;
return await message.channel.send(this.getHelp()).then(m => client.msgDelete(m, 5));
}
async menuRun(interaction: StringSelectMenuInteraction<CacheType>, args: string[]) {
const command = handler.commands.get(args[0]);
var embed = client.mkembed({});
var embed2: EmbedBuilder | undefined = undefined;
if (command) {
embed.setTitle(`\` /${args[0]} 도움말 \``)
.setDescription(`이름: ${args[0]}\n설명: ${command.description}`);
embed2 = helpData(command.metaData.name, command.metaData);
} else {
embed.setTitle(`\` ${args[0]} 도움말 \``)
.setDescription(`명령어를 찾을수 없습니다.`)
.setFooter({ text: `도움말: /help` })
.setColor('DarkRed');
}
if (embed2) {
await interaction.editReply({ embeds: [ embed, embed2 ] });
return;
}
await interaction.editReply({ embeds: [ embed ] });
}
getHelp(): { embeds: EmbedBuilder[], components: ActionRowBuilder<StringSelectMenuBuilder>[] } {
const slashcmdembed = client.mkembed({
title: `\` slash (/) 도움말 \``,
description: `명령어\n명령어 설명`
});
const msgcmdembed = client.mkembed({
title: `\` 기본 (${client.prefix}) 도움말 \``,
description: `명령어 [같은 명령어]\n명령어 설명`,
footer: { text: `PREFIX: ${client.prefix}` }
});
let cmdlist: { label: string, description: string, value: string }[] = [];
handler.commands.forEach((cmd) => {
if (cmd.slashRun && cmd.visible) {
cmdlist.push({ label: `/${cmd.name}`, description: `${cmd.description}`, value: `${cmd.name}` });
slashcmdembed.addFields([{ name: `**/${cmd.name}**`, value: `${cmd.description}`, inline: true }]);
}
});
handler.commands.forEach((cmd) => {
if (cmd.messageRun && cmd.visible) {
msgcmdembed.addFields([{ name: `**${client.prefix}${cmd.name}${cmd.aliases ? ` [ ${cmd.aliases} ]` : ""}**`, value: `${cmd.description}`, inline: true }]);
}
});
const rowhelp = client.mkembed({
title: '\` 명령어 상세보기 \`',
description: `명령어의 자세한 내용은\n아래의 선택박스에서 선택해\n확인할수있습니다.`,
footer: { text: '여러번 가능' }
});
const row = new ActionRowBuilder<StringSelectMenuBuilder>().addComponents(
new StringSelectMenuBuilder()
.setCustomId('help')
.setPlaceholder('명령어를 선택해주세요.')
.addOptions(cmdlist)
);
return { embeds: [ slashcmdembed, msgcmdembed, rowhelp ], components: [ row ] };
}
}
function helpData(name: string, metadata: ChatInputApplicationCommandData): EmbedBuilder | undefined {
var text = "";
metadata.options?.forEach((opt) => {
text += `/${name} ${opt.name}`;
if (opt.type === ApplicationCommandOptionType.Subcommand && opt.options) {
if (opt.options.length > 1) {
text = "";
opt.options.forEach((opt2) => {
text += `/${name} ${opt.name} [${opt2.type}] : ${opt.description}\n`;
});
} else {
text += ` [${opt.options[0].type}] : ${opt.description}\n`;
}
} else {
text += ` : ${opt.description}\n`;
}
});
if (!text || text.length == 0) return undefined;
return client.mkembed({
title: `\` ${name} 명령어 \``,
description: text,
});
}

41
src/commands/ping.ts Normal file
View File

@@ -0,0 +1,41 @@
import { client } from "../index";
import { Command } from "../types/Command";
import { Message, ChatInputApplicationCommandData, ChannelType, ChatInputCommandInteraction } from "discord.js";
/** ping 명령어 */
export default class implements Command {
/** 해당 명령어 설명 */
name = "ping";
visible = true;
aliases: string[] = ["핑"];
description: string = "기본 명령어";
metaData: ChatInputApplicationCommandData = {
name: this.name,
description: this.description,
};
/** 실행되는 부분 */
async slashRun(interaction: ChatInputCommandInteraction) {
const msg = await interaction.editReply({ embeds: [ client.mkembed({
title: "핑...",
description: "계산중...",
}) ] });
const ping = msg.createdTimestamp - interaction.createdTimestamp;
await interaction.editReply({ embeds: [ client.mkembed({
title: "퐁!!",
description: `${ping}ms`,
}) ] });
}
async messageRun(message: Message) {
if (message.channel?.type !== ChannelType.GuildText) return;
const msg = await message.channel.send({ embeds: [ client.mkembed({
title: "핑...",
description: "계산중...",
}) ] });
const ping = msg.createdTimestamp - message.createdTimestamp;
return await msg.edit({ embeds: [ client.mkembed({
title: "퐁!!",
description: `${ping}ms`,
}) ] }).then(m => client.msgDelete(m, 1));
}
}

31
src/commands/signature.ts Normal file
View File

@@ -0,0 +1,31 @@
import { client } from "../index";
import { Command } from "../types/Command";
import { Message, ChatInputApplicationCommandData, ChannelType, ChatInputCommandInteraction } from "discord.js";
/** signature 명령어 */
export default class implements Command {
/** 해당 명령어 설명 */
name = "시그니처";
visible = true;
aliases: string[] = ["signature"];
description: string = "시그니처";
metaData: ChatInputApplicationCommandData = {
name: this.name,
description: this.description,
};
/** 실행되는 부분 */
async slashRun(interaction: ChatInputCommandInteraction) {
await interaction.editReply({ embeds: [ client.mkembed({
title: "시그니처 사이트",
url: "https://sig.tkrmagid.kr",
}) ] });
}
async messageRun(message: Message) {
if (message.channel?.type !== ChannelType.GuildText) return;
return await message.channel.send({ embeds: [ client.mkembed({
title: "시그니처 사이트",
url: "https:sig.tkrmagid.kr",
}) ] }).then(m => client.msgDelete(m, 5));
}
}

129
src/commands/tts.ts Normal file
View File

@@ -0,0 +1,129 @@
import { client } from "../index";
import { Command } from "../types/Command";
import { DB } from "../utils/Database";
import { Message, ChatInputApplicationCommandData, ChannelType, ApplicationCommandOptionType, ChatInputCommandInteraction, EmbedBuilder, Guild } from "discord.js";
/** tts 명령어 */
export default class implements Command {
/** 해당 명령어 설명 */
name = "tts";
visible = true;
aliases: string[] = [];
description: string = "tts 명령어";
metaData: ChatInputApplicationCommandData = {
name: this.name,
description: this.description,
options: [
{
type: ApplicationCommandOptionType.SubcommandGroup,
name: "channel",
description: "채널 관련",
options: [
{
type: ApplicationCommandOptionType.Subcommand,
name: "make",
description: "채널 만들기",
},
{
type: ApplicationCommandOptionType.Subcommand,
name: "register",
description: "기존 채팅채널 등록",
options: [
{
type: ApplicationCommandOptionType.Channel,
name: "channel",
description: "등록할 채널 (선택)",
channel_types: [ChannelType.GuildText],
},
{
type: ApplicationCommandOptionType.String,
name: "channel_id",
description: "채널 ID 또는 #멘션 (선택)",
},
]
}
]
},
]
};
/** 실행되는 부분 */
async slashRun(interaction: ChatInputCommandInteraction) {
const group = interaction.options.getSubcommandGroup();
const cmd = interaction.options.getSubcommand();
if (group === "channel") {
if (cmd === "make") {
await interaction.editReply({ embeds: [ await this.channel_create(interaction.guild) ] });
return;
}
if (cmd === "register") {
const channel = interaction.options.getChannel("channel");
const channelId = interaction.options.getString("channel_id");
await interaction.editReply({ embeds: [ this.channel_register(interaction.guild, channel?.id || channelId) ] });
return;
}
}
}
async messageRun(message: Message) {
if (message.channel?.type !== ChannelType.GuildText) return;
return await message.channel.send({ content: "예시 명령어" }).then(m => client.msgDelete(m, 5));
}
async channel_create(guild: Guild | null): Promise<EmbedBuilder> {
if (!guild) return client.mkembed({
title: "guild를 가져올수 없습니다.",
color: "DarkRed",
});
const channel = await guild.channels.create({
name: "TTS채널",
type: ChannelType.GuildText,
topic: "채팅치면 봇이 음성채널에 와서 읽어줍니다.",
});
channel.send({ embeds: [ client.mkembed({
title: "TTS 채널입니다.",
description: [
"**음성채널에 들어간 후",
"이곳에 채팅을 입력하면",
`봇 ( <@${client.user?.id}> )(이)가 음성에`,
"들어와 채팅을 읽어줍니다.**"
].join("\n"),
}) ] });
return this.channel_register(guild, channel.id);
}
channel_register(guild: Guild | null, channelId: string | null): EmbedBuilder {
if (!guild) return client.mkembed({
title: "guild를 가져올수 없습니다.",
color: "DarkRed",
});
if (!channelId) return client.mkembed({
title: "채널 아이디 가져오기 오류",
color: "DarkRed",
});
const channel = guild.channels.cache.get(channelId.replace(/\<|\#|\!|\>/g,"").trim());
if (!channel?.id) return client.mkembed({
title: `${channelId} 채널 가져오기 오류`,
color: "DarkRed",
});
if (!DB.guild.get(guild.id) && !DB.guild.set({
id: guild.id,
name: guild.name,
channel_id: "",
})) return client.mkembed({
title: "DB 생성 오류",
color: "DarkRed",
});
if (!DB.guild.update({
id: guild.id,
name: guild.name,
channel_id: channel.id,
})) return client.mkembed({
title: "DB 등록 오류",
color: "DarkRed",
});
return client.mkembed({
title: "채널 생성/등록 완료",
description: `채널: <#${channel.id}>`,
});
}
}