mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-11 05:46:16 +00:00
feat(bots/discord): support training without label
This commit is contained in:
@@ -66,7 +66,6 @@ export default {
|
||||
},
|
||||
},
|
||||
humanCorrections: {
|
||||
falsePositiveLabel: 'false_positive',
|
||||
allow: {
|
||||
members: {
|
||||
permissions: 8n,
|
||||
|
||||
@@ -36,7 +36,6 @@ export type Config = {
|
||||
blacklist?: Filter
|
||||
}
|
||||
humanCorrections: {
|
||||
falsePositiveLabel: string
|
||||
allow?: {
|
||||
users?: string[]
|
||||
members?: {
|
||||
@@ -72,7 +71,7 @@ export type ConfigMessageScanResponse = {
|
||||
image?: Array<RegExp>
|
||||
}
|
||||
filterOverride?: NonNullable<Config['messageScan']>['filter']
|
||||
response: ConfigMessageScanResponseMessage | null
|
||||
response: ConfigMessageScanResponseMessage
|
||||
respondToReply?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ const msRcConfig = config.messageScan?.humanCorrections?.allow
|
||||
|
||||
export default new Command({
|
||||
name: 'train',
|
||||
description: 'Train a specific message or text to a specific label',
|
||||
description: 'Train a specific message to a specific label',
|
||||
type: Command.Type.ChatGuild,
|
||||
requirements: {
|
||||
users: msRcConfig?.users,
|
||||
@@ -26,9 +26,9 @@ export default new Command({
|
||||
required: true,
|
||||
},
|
||||
label: {
|
||||
description: 'The label to train the message as',
|
||||
description: 'The label to train the message as (leave empty for out of scope)',
|
||||
type: Command.OptionType.String,
|
||||
required: true,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
allowMessageCommand: true,
|
||||
@@ -49,7 +49,7 @@ export default new Command({
|
||||
'This command can only be used in or on text channels',
|
||||
)
|
||||
|
||||
if (!labels.includes(label))
|
||||
if (label && !labels.includes(label))
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidArgument,
|
||||
`The provided label is invalid.\nValid labels are:${labels.map(l => `\n- \`${l}\``).join('')}`,
|
||||
@@ -60,14 +60,14 @@ export default new Command({
|
||||
)
|
||||
if (!refMsg) throw new CommandError(CommandErrorType.InvalidArgument, 'The provided message does not exist.')
|
||||
|
||||
logger.debug(`User ${context.executor.id} is training message ${refMsg?.id} as ${label}`)
|
||||
logger.debug(`User ${context.executor.id} is training message ${refMsg?.id} as ${label ?? 'out of scope'}`)
|
||||
|
||||
await context.api.client.trainMessage(refMsg.content, label)
|
||||
await trigger.reply({
|
||||
embeds: [
|
||||
createSuccessEmbed(
|
||||
'Message trained',
|
||||
`The provided message has been trained as \`${label}\`. Thank you for your contribution!`,
|
||||
`The provided message has been trained as ${label ? `\`${label}\`` : 'out of scope'}. Thank you for your contribution!`,
|
||||
),
|
||||
],
|
||||
flags: MessageFlags.Ephemeral,
|
||||
|
||||
@@ -37,7 +37,10 @@ export default new Command({
|
||||
components: [
|
||||
{
|
||||
custom_id: `tr_${trigger.targetMessage.channelId}_${trigger.targetId}`,
|
||||
options: labels.map(label => ({ label, value: label })),
|
||||
options: [
|
||||
...labels.map(label => ({ label, value: label })),
|
||||
{ label: 'Out of scope', value: '', emoji: { name: '❌' } },
|
||||
],
|
||||
type: ComponentType.StringSelect,
|
||||
} satisfies APIStringSelectComponent,
|
||||
],
|
||||
|
||||
@@ -58,8 +58,8 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
|
||||
const editMessage = (content: string, description?: string) =>
|
||||
editInteractionMessage(interaction, msg.url, content, description)
|
||||
const handleCorrection = (label: string) =>
|
||||
handleUserResponseCorrection(context, response, msg, label, interaction.user)
|
||||
const handleCorrection = (label?: string) =>
|
||||
handleUserResponseCorrection(context, response, msg, interaction.user, label)
|
||||
|
||||
if (response.correctedById)
|
||||
return await editMessage(
|
||||
@@ -82,7 +82,7 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
await editMessage('Canceled', 'You canceled this interaction. 😞')
|
||||
break
|
||||
case 'delete':
|
||||
await handleCorrection(msConfig.humanCorrections.falsePositiveLabel)
|
||||
await handleCorrection()
|
||||
await editMessage(
|
||||
'Marked as false positive',
|
||||
'The response has been deleted and marked as a false positive. Thank you for your feedback. 🎉',
|
||||
|
||||
@@ -30,7 +30,8 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
flags: MessageFlags.Ephemeral,
|
||||
}))
|
||||
|
||||
const selectedLabel = interaction.values[0]!
|
||||
// If selectedLabel is empty, it means "out of scope", so we pass undefined
|
||||
const selectedLabel = interaction.values[0] || undefined
|
||||
await context.api.client.trainMessage(msg.content, selectedLabel)
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
|
||||
@@ -63,8 +63,8 @@ withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||
|
||||
logger.debug(`User ${user.id} is trying to correct the response ${rct.message.id}`)
|
||||
|
||||
const handleCorrection = (label: string) =>
|
||||
handleUserResponseCorrection(context, response, reactionMessage, label, user)
|
||||
const handleCorrection = (label?: string) =>
|
||||
handleUserResponseCorrection(context, response, reactionMessage, user, label)
|
||||
|
||||
try {
|
||||
if (reaction.emoji.name === Reactions.train) {
|
||||
@@ -106,7 +106,7 @@ withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||
.setCustomId(`${componentPrefix}_cancel`),
|
||||
new ButtonBuilder()
|
||||
.setEmoji(Reactions.delete)
|
||||
.setLabel('Delete (mark as false positive)')
|
||||
.setLabel('Delete (mark as out of scope)')
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
.setCustomId(`${componentPrefix}_delete`),
|
||||
),
|
||||
@@ -117,8 +117,8 @@ withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||
components: rows,
|
||||
})
|
||||
} else if (reaction.emoji.name === Reactions.delete) {
|
||||
await handleCorrection(msConfig.humanCorrections.falsePositiveLabel)
|
||||
await user.send({ content: 'The response has been deleted and marked as a false positive.' })
|
||||
await handleCorrection()
|
||||
await user.send({ content: 'The response has been deleted and marked as out of scope.' })
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Failed to correct response:', e)
|
||||
|
||||
@@ -17,7 +17,7 @@ export const getResponseFromText = async (
|
||||
type ResponseConfig = Awaited<ReturnType<typeof getResponseFromText>>
|
||||
let responseConfig: Omit<ResponseConfig, 'triggers'> & { triggers?: ResponseConfig['triggers'] } = {
|
||||
triggers: undefined,
|
||||
response: null,
|
||||
response: null!,
|
||||
}
|
||||
|
||||
const firstLabelIndexes: number[] = []
|
||||
@@ -143,15 +143,22 @@ export const handleUserResponseCorrection = async (
|
||||
{ api, database: db, config: { messageScan: msConfig }, logger }: typeof import('$/context'),
|
||||
response: Response,
|
||||
reply: Message,
|
||||
label: string,
|
||||
user: User | PartialUser,
|
||||
label?: string,
|
||||
) => {
|
||||
if (!label) {
|
||||
await Promise.all([reply.delete(), api.client.trainMessage(response.content, label)]).finally(() =>
|
||||
logger.debug(`User ${user.id} trained message ${response.replyId} as out of scope`),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const correctLabelResponse = msConfig!.responses!.find(r =>
|
||||
r.triggers.text!.some(t => 'label' in t && t.label === label),
|
||||
)
|
||||
|
||||
if (!correctLabelResponse) throw new Error('Cannot find label config for the selected label')
|
||||
if (!correctLabelResponse.response) return void (await reply.delete())
|
||||
|
||||
if (response.label !== label) {
|
||||
db.update(responses)
|
||||
@@ -168,12 +175,12 @@ export const handleUserResponseCorrection = async (
|
||||
}))
|
||||
}
|
||||
|
||||
await api.client.trainMessage(response.content, label)
|
||||
logger.debug(`User ${user.id} trained message ${response.replyId} as ${label} (positive)`)
|
||||
|
||||
await reply.edit({
|
||||
components: [],
|
||||
})
|
||||
await Promise.all([
|
||||
api.client.trainMessage(response.content, label),
|
||||
reply.edit({
|
||||
components: [],
|
||||
}),
|
||||
]).finally(() => logger.debug(`User ${user.id} trained message ${response.replyId} as ${label}`))
|
||||
}
|
||||
|
||||
export const createMessageScanResponseComponents = (reply: Message<true>) => [
|
||||
|
||||
Reference in New Issue
Block a user