mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-18 08:43:57 +00:00
feat(bots/discord): support nickname decancering
This commit is contained in:
@@ -5,6 +5,9 @@ export type Config = {
|
|||||||
guilds: string[]
|
guilds: string[]
|
||||||
moderation?: {
|
moderation?: {
|
||||||
roles: string[]
|
roles: string[]
|
||||||
|
cure?: {
|
||||||
|
defaultName: string
|
||||||
|
}
|
||||||
log?: {
|
log?: {
|
||||||
channel: string
|
channel: string
|
||||||
thread?: string
|
thread?: string
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ export default {
|
|||||||
owners: ['USER_ID_HERE'],
|
owners: ['USER_ID_HERE'],
|
||||||
guilds: ['GUILD_ID_HERE'],
|
guilds: ['GUILD_ID_HERE'],
|
||||||
moderation: {
|
moderation: {
|
||||||
|
cure: {
|
||||||
|
defaultName: 'Server member',
|
||||||
|
},
|
||||||
roles: ['ROLE_ID_HERE'],
|
roles: ['ROLE_ID_HERE'],
|
||||||
log: {
|
log: {
|
||||||
channel: 'CHANNEL_ID_HERE',
|
channel: 'CHANNEL_ID_HERE',
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
"@revanced/bot-api": "workspace:*",
|
"@revanced/bot-api": "workspace:*",
|
||||||
"@revanced/bot-shared": "workspace:*",
|
"@revanced/bot-shared": "workspace:*",
|
||||||
"chalk": "^5.3.0",
|
"chalk": "^5.3.0",
|
||||||
|
"decancer": "^3.2.2",
|
||||||
"discord.js": "^14.15.3",
|
"discord.js": "^14.15.3",
|
||||||
"drizzle-orm": "^0.31.2"
|
"drizzle-orm": "^0.31.2"
|
||||||
},
|
},
|
||||||
|
|||||||
26
bots/discord/src/commands/moderation/cure.ts
Normal file
26
bots/discord/src/commands/moderation/cure.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js'
|
||||||
|
|
||||||
|
import type { Command } from '..'
|
||||||
|
|
||||||
|
import { config } from '$/context'
|
||||||
|
import { cureNickname } from '$/utils/discord/moderation'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('cure')
|
||||||
|
.setDescription("Cure a member's nickname")
|
||||||
|
.addUserOption(option => option.setName('member').setRequired(true).setDescription('The member to cure'))
|
||||||
|
.toJSON(),
|
||||||
|
|
||||||
|
memberRequirements: {
|
||||||
|
roles: config.moderation?.roles ?? [],
|
||||||
|
},
|
||||||
|
|
||||||
|
global: false,
|
||||||
|
|
||||||
|
async execute(_, interaction) {
|
||||||
|
const user = interaction.options.getUser('user', true)
|
||||||
|
const member = await interaction.guild!.members.fetch(user.id)
|
||||||
|
await cureNickname(member)
|
||||||
|
},
|
||||||
|
} satisfies Command
|
||||||
18
bots/discord/src/events/discord/cureRequired.ts
Normal file
18
bots/discord/src/events/discord/cureRequired.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { on } from '$/utils/discord/events'
|
||||||
|
import { cureNickname } from '$/utils/discord/moderation'
|
||||||
|
|
||||||
|
on('guildMemberUpdate', async (_, oldMember, newMember) => {
|
||||||
|
if (newMember.user.bot) return
|
||||||
|
if (oldMember.nickname !== newMember.nickname) await cureNickname(newMember)
|
||||||
|
})
|
||||||
|
|
||||||
|
on('guildMemberAdd', (_, member) => {
|
||||||
|
if (member.user.bot) return
|
||||||
|
cureNickname(member)
|
||||||
|
})
|
||||||
|
|
||||||
|
on('messageCreate', async (_, msg) => {
|
||||||
|
if (msg.author.bot) return
|
||||||
|
if (!msg.member) return
|
||||||
|
await cureNickname(msg.member)
|
||||||
|
})
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { config, logger } from '$/context'
|
import { config, logger } from '$/context'
|
||||||
import type { ChatInputCommandInteraction, EmbedBuilder, Guild, User } from 'discord.js'
|
import decancer from 'decancer'
|
||||||
|
import type { ChatInputCommandInteraction, EmbedBuilder, Guild, GuildMember, User } from 'discord.js'
|
||||||
import { applyReferenceToModerationActionEmbed, createModerationActionEmbed } from './embeds'
|
import { applyReferenceToModerationActionEmbed, createModerationActionEmbed } from './embeds'
|
||||||
|
|
||||||
const PresetLogAction = {
|
const PresetLogAction = {
|
||||||
@@ -43,3 +44,16 @@ export const getLogChannel = async (guild: Guild) => {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const cureNickname = async (member: GuildMember) => {
|
||||||
|
if (!member.manageable) throw new Error('Member is not manageable')
|
||||||
|
const name = member.displayName
|
||||||
|
let cured = decancer(name)
|
||||||
|
.toString()
|
||||||
|
.replace(/[^a-zA-Z0-9]/g, '')
|
||||||
|
|
||||||
|
if (!cured || !/^[a-zA-Z]/.test(cured)) cured = config.moderation?.cure?.defaultName ?? 'ReVanced member'
|
||||||
|
|
||||||
|
await member.setNickname(cured, 'Nickname cured')
|
||||||
|
logger.log(`Cured nickname for ${member.user.tag} (${member.id}) from "${name}"`)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user