feat: Add learn command

This commit is contained in:
Siwoo Jeon 2025-03-01 00:01:21 +09:00
parent 8d2437a18a
commit 6cc359929e
Signed by: migan
GPG key ID: 036E9A8C5E8E48DA
4 changed files with 138 additions and 0 deletions

View file

@ -11,6 +11,7 @@
"@sapphire/utilities": "^3.18.2", "@sapphire/utilities": "^3.18.2",
"discord-api-types": "^0.37.119", "discord-api-types": "^0.37.119",
"discord.js": "^14.18.0", "discord.js": "^14.18.0",
"es-hangul": "^2.3.1",
"mongoose": "^8.10.1", "mongoose": "^8.10.1",
}, },
"devDependencies": { "devDependencies": {
@ -129,6 +130,8 @@
"discord.js": ["discord.js@14.18.0", "", { "dependencies": { "@discordjs/builders": "^1.10.1", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.0", "@discordjs/rest": "^2.4.3", "@discordjs/util": "^1.1.1", "@discordjs/ws": "^1.2.1", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.37.119", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "tslib": "^2.6.3", "undici": "6.21.1" } }, "sha512-SvU5kVUvwunQhN2/+0t55QW/1EHfB1lp0TtLZUSXVHDmyHTrdOj5LRKdR0zLcybaA15F+NtdWuWmGOX9lE+CAw=="], "discord.js": ["discord.js@14.18.0", "", { "dependencies": { "@discordjs/builders": "^1.10.1", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.0", "@discordjs/rest": "^2.4.3", "@discordjs/util": "^1.1.1", "@discordjs/ws": "^1.2.1", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.37.119", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "tslib": "^2.6.3", "undici": "6.21.1" } }, "sha512-SvU5kVUvwunQhN2/+0t55QW/1EHfB1lp0TtLZUSXVHDmyHTrdOj5LRKdR0zLcybaA15F+NtdWuWmGOX9lE+CAw=="],
"es-hangul": ["es-hangul@2.3.1", "", {}, "sha512-somwJpQpVP5LLI6DquIvRnoTSqVyfIfT1a8/jxHRueWNiTse7/kJ0JZVpf4KrzhY8CoqEK0LUZXFhGkf1hBZKQ=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="], "generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "^1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="],

View file

@ -22,6 +22,7 @@
"@sapphire/utilities": "^3.18.2", "@sapphire/utilities": "^3.18.2",
"discord-api-types": "^0.37.119", "discord-api-types": "^0.37.119",
"discord.js": "^14.18.0", "discord.js": "^14.18.0",
"es-hangul": "^2.3.1",
"mongoose": "^8.10.1" "mongoose": "^8.10.1"
}, },
"scripts": { "scripts": {

127
src/commands/learn.ts Normal file
View file

@ -0,0 +1,127 @@
import { Learn } from '../lib/databases'
import { ApplyOptions } from '@sapphire/decorators'
import { Args, Command } from '@sapphire/framework'
import { ChatInputCommandInteraction, codeBlock, Message } from 'discord.js'
import { josa } from 'es-hangul'
@ApplyOptions<Command.Options>({
name: '배워',
aliases: ['공부'],
description: '단어를 가르치는 명령ㅇ어에요.',
detailedDescription: {
usage: '머핀아 배워 (등록할 단어) (대답)',
examples: [
'머핀아 배워 안녕 안녕!',
'머핀아 배워 "야 죽을래?" "아니요 ㅠㅠㅠ"',
'머핀아 배워 미간은_누구야? 이봇의_개발자요',
],
},
})
export class LearnCommand extends Command {
public registerApplicationCommands(registry: Command.Registry) {
registry.registerChatInputCommand(builder =>
builder
.setName(this.name)
.setDescription(this.description)
.addStringOption(option =>
option
.setRequired(true)
.setName('단어')
.setDescription('등록할 단어를 입력해주세요.'),
)
.addStringOption(option =>
option
.setRequired(true)
.setName('대답')
.setDescription('해당 단어의 대답을 입력해주세요.'),
),
)
}
public async messageRun(msg: Message<true>, args: Args) {
return await this._run(msg, args)
}
public async chatInputRun(
interaction: ChatInputCommandInteraction<'cached'>,
) {
return await this._run(interaction)
}
private async _run(
ctx: Message<true> | ChatInputCommandInteraction<'cached'>,
args?: Args,
) {
const userId = ctx instanceof Message ? ctx.author.id : ctx.user.id
let command: string | undefined
let result: string | undefined
if (typeof this.detailedDescription === 'string') return
if (ctx instanceof ChatInputCommandInteraction) {
await ctx.deferReply()
command = ctx.options.getString('단어', true)
result = ctx.options.getString('대답', true)
} else {
if (!args) return
command = (await args.pick('string').catch(() => undefined))?.replaceAll(
'_',
' ',
)
result = (await args.pick('string').catch(() => undefined))?.replaceAll(
'_',
' ',
)
}
if (!command || !result)
return await ctx.reply(
codeBlock(
'md',
`사용법: ${this.detailedDescription.usage}\n` +
`예시: ${this.detailedDescription.examples?.map(example => example).join('\n')}`,
),
)
let commands: string[] = []
let aliases: string[] = []
for (const [name, command] of this.container.stores.get('commands')) {
commands = [...commands, name]
aliases = [...aliases, ...command.aliases]
}
const ignores = [...commands, ...aliases, '미간', 'Migan', 'migan', '간미']
const disallows = [
'@everyone',
'@here',
`<@${this.container.config.bot.ownerId}>`,
]
for (const ignore of ignores) {
if (command.includes(ignore))
return ctx instanceof Message
? await ctx.reply('해ㄷ당 단어는 배울ㄹ 수 없어요.')
: await ctx.editReply('해ㄷ당 단어는 배울ㄹ 수 없어요.')
}
for (const disallowed of disallows) {
if (result.includes(disallowed))
return ctx instanceof Message
? await ctx.reply('해당 단ㅇ어는 개발자님이 특별히 금지하였ㅇ어요.')
: await ctx.editReply(
'해당 단ㅇ어는 개발자님이 특별히 금지하였ㅇ어요.',
)
}
await new Learn({
command,
result,
user_id: userId,
}).save()
return ctx instanceof Message
? await ctx.reply(`${josa(command, '을/를')} 배웠ㅇ어요.`)
: await ctx.editReply(`${josa(command, '을/를')} 배웠ㅇ어요.`)
}
}

View file

@ -11,6 +11,13 @@ declare module '@sapphire/pieces' {
} }
} }
declare module '@sapphire/framework' {
interface DetailedDescriptionCommandObject {
usage: string
examples?: string[]
}
}
container.dbDisconnect = async () => await disconnect() container.dbDisconnect = async () => await disconnect()
container.config = new Config() container.config = new Config()
container.prefix = container.config.bot.prefix container.prefix = container.config.bot.prefix