mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-11 13:56:15 +00:00
feat(bots/discord): add replyToReplied option in response config
This commit is contained in:
@@ -60,6 +60,7 @@ export type ConfigMessageScanResponse = {
|
|||||||
}
|
}
|
||||||
filterOverride?: NonNullable<Config['messageScan']>['filter']
|
filterOverride?: NonNullable<Config['messageScan']>['filter']
|
||||||
response: ConfigMessageScanResponseMessage | null
|
response: ConfigMessageScanResponseMessage | null
|
||||||
|
replyToReplied?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConfigMessageScanResponseLabelConfig = {
|
export type ConfigMessageScanResponseLabelConfig = {
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ withContext(on, 'messageCreate', async (context, msg) => {
|
|||||||
try {
|
try {
|
||||||
logger.debug(`Classifying message ${msg.id}`)
|
logger.debug(`Classifying message ${msg.id}`)
|
||||||
|
|
||||||
const { response, label } = await getResponseFromText(msg.content, filteredResponses, context)
|
const { response, label, replyToReplied } = await getResponseFromText(msg.content, filteredResponses, context)
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
logger.debug('Response found')
|
logger.debug('Response found')
|
||||||
|
|
||||||
const reply = await msg.reply({
|
const toReply = replyToReplied ? await msg.fetchReference() : msg
|
||||||
|
const reply = await toReply.reply({
|
||||||
...response,
|
...response,
|
||||||
embeds: response.embeds?.map(it => createMessageScanResponseEmbed(it, label ? 'nlp' : 'match')),
|
embeds: response.embeds?.map(it => createMessageScanResponseEmbed(it, label ? 'nlp' : 'match')),
|
||||||
})
|
})
|
||||||
@@ -2,8 +2,7 @@ import { type Response, responses } from '$/database/schemas'
|
|||||||
import type {
|
import type {
|
||||||
Config,
|
Config,
|
||||||
ConfigMessageScanResponse,
|
ConfigMessageScanResponse,
|
||||||
ConfigMessageScanResponseLabelConfig,
|
ConfigMessageScanResponseLabelConfig
|
||||||
ConfigMessageScanResponseMessage,
|
|
||||||
} from 'config.schema'
|
} from 'config.schema'
|
||||||
import type { Message, PartialUser, User } from 'discord.js'
|
import type { Message, PartialUser, User } from 'discord.js'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
@@ -15,9 +14,12 @@ export const getResponseFromText = async (
|
|||||||
// Just to be safe that we will never use data from the context parameter
|
// Just to be safe that we will never use data from the context parameter
|
||||||
{ api, logger }: Omit<typeof import('src/context'), 'config'>,
|
{ api, logger }: Omit<typeof import('src/context'), 'config'>,
|
||||||
ocrMode = false,
|
ocrMode = false,
|
||||||
) => {
|
): Promise<ConfigMessageScanResponse & { label?: string }> => {
|
||||||
let label: string | undefined
|
let responseConfig: Awaited<ReturnType<typeof getResponseFromText>> = {
|
||||||
let response: ConfigMessageScanResponseMessage | undefined | null
|
triggers: {},
|
||||||
|
response: null
|
||||||
|
}
|
||||||
|
|
||||||
const firstLabelIndexes: number[] = []
|
const firstLabelIndexes: number[] = []
|
||||||
|
|
||||||
// Test if all regexes before a label trigger is matched
|
// Test if all regexes before a label trigger is matched
|
||||||
@@ -25,29 +27,28 @@ export const getResponseFromText = async (
|
|||||||
const trigger = responses[i]!
|
const trigger = responses[i]!
|
||||||
|
|
||||||
// Filter override check is not neccessary here, we are already passing responses that match the filter
|
// Filter override check is not neccessary here, we are already passing responses that match the filter
|
||||||
// from the messageCreate handler
|
// from the messageCreate handler, see line 17 of messageCreate handler
|
||||||
const {
|
const {
|
||||||
triggers: { text: textTriggers, image: imageTriggers },
|
triggers: { text: textTriggers, image: imageTriggers }
|
||||||
response: resp,
|
|
||||||
} = trigger
|
} = trigger
|
||||||
if (response) break
|
if (responseConfig) break
|
||||||
|
|
||||||
if (ocrMode) {
|
if (ocrMode) {
|
||||||
if (imageTriggers)
|
if (imageTriggers)
|
||||||
for (const regex of imageTriggers)
|
for (const regex of imageTriggers)
|
||||||
if (regex.test(content)) {
|
if (regex.test(content)) {
|
||||||
logger.debug(`Message matched regex (OCR mode): ${regex.source}`)
|
logger.debug(`Message matched regex (OCR mode): ${regex.source}`)
|
||||||
response = resp
|
responseConfig = trigger
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
for (let j = 0; j < textTriggers!.length; j++) {
|
for (let j = 0; j < textTriggers!.length; j++) {
|
||||||
const trigger = textTriggers![j]!
|
const regex = textTriggers![j]!
|
||||||
|
|
||||||
if (trigger instanceof RegExp) {
|
if (regex instanceof RegExp) {
|
||||||
if (trigger.test(content)) {
|
if (regex.test(content)) {
|
||||||
logger.debug(`Message matched regex (before mode): ${trigger.source}`)
|
logger.debug(`Message matched regex (before mode): ${regex.source}`)
|
||||||
response = resp
|
responseConfig = trigger
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -58,7 +59,7 @@ export const getResponseFromText = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If none of the regexes match, we can search for labels immediately
|
// If none of the regexes match, we can search for labels immediately
|
||||||
if (!response && !ocrMode) {
|
if (!responseConfig && !ocrMode) {
|
||||||
logger.debug('No match from before regexes, doing NLP')
|
logger.debug('No match from before regexes, doing NLP')
|
||||||
const scan = await api.client.parseText(content)
|
const scan = await api.client.parseText(content)
|
||||||
if (scan.labels.length) {
|
if (scan.labels.length) {
|
||||||
@@ -76,24 +77,22 @@ export const getResponseFromText = async (
|
|||||||
|
|
||||||
if (!labelConfig) {
|
if (!labelConfig) {
|
||||||
logger.warn(`No label config found for label ${matchedLabel.name}`)
|
logger.warn(`No label config found for label ${matchedLabel.name}`)
|
||||||
return { response: null, label: undefined }
|
return responseConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchedLabel.confidence >= triggerConfig!.threshold) {
|
if (matchedLabel.confidence >= triggerConfig!.threshold) {
|
||||||
logger.debug('Label confidence is enough')
|
logger.debug('Label confidence is enough')
|
||||||
label = matchedLabel.name
|
responseConfig = labelConfig
|
||||||
response = labelConfig.response
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we still don't have a label, we can match all regexes after the initial label trigger
|
// If we still don't have a response config, we can match all regexes after the initial label trigger
|
||||||
if (!response) {
|
if (!responseConfig) {
|
||||||
logger.debug('No match from NLP, doing after regexes')
|
logger.debug('No match from NLP, doing after regexes')
|
||||||
for (let i = 0; i < responses.length; i++) {
|
for (let i = 0; i < responses.length; i++) {
|
||||||
const {
|
const {
|
||||||
triggers: { text: textTriggers },
|
triggers: { text: textTriggers }
|
||||||
response: resp,
|
|
||||||
} = responses[i]!
|
} = responses[i]!
|
||||||
const firstLabelIndex = firstLabelIndexes[i] ?? -1
|
const firstLabelIndex = firstLabelIndexes[i] ?? -1
|
||||||
|
|
||||||
@@ -103,7 +102,7 @@ export const getResponseFromText = async (
|
|||||||
if (trigger instanceof RegExp) {
|
if (trigger instanceof RegExp) {
|
||||||
if (trigger.test(content)) {
|
if (trigger.test(content)) {
|
||||||
logger.debug(`Message matched regex (after mode): ${trigger.source}`)
|
logger.debug(`Message matched regex (after mode): ${trigger.source}`)
|
||||||
response = resp
|
responseConfig = responses[i]!
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,10 +110,7 @@ export const getResponseFromText = async (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return responseConfig
|
||||||
response,
|
|
||||||
label,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const shouldScanMessage = (
|
export const shouldScanMessage = (
|
||||||
|
|||||||
Reference in New Issue
Block a user