mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-11 13:56:15 +00:00
feat(events)!: use better api for events
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import { on } from '$utils/api/events'
|
import { on, withContext } from '$utils/api/events'
|
||||||
import { DisconnectReason, HumanizedDisconnectReason } from '@revanced/bot-shared'
|
import { DisconnectReason, HumanizedDisconnectReason } from '@revanced/bot-shared'
|
||||||
import { api, logger } from 'src/context'
|
|
||||||
|
|
||||||
on('disconnect', (reason, msg) => {
|
withContext(on, 'disconnect', ({ api, config, logger }, reason, msg) => {
|
||||||
if (reason === DisconnectReason.PlannedDisconnect && api.isStopping) return
|
if (reason === DisconnectReason.PlannedDisconnect && api.isStopping) return
|
||||||
|
|
||||||
const ws = api.client.ws
|
const ws = api.client.ws
|
||||||
@@ -16,8 +15,7 @@ on('disconnect', (reason, msg) => {
|
|||||||
}`,
|
}`,
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: move to config
|
if (api.disconnectCount >= (config.api.disconnectLimit ?? 3)) {
|
||||||
if (api.disconnectCount >= 3) {
|
|
||||||
console.error('Disconnected from bot API too many times')
|
console.error('Disconnected from bot API too many times')
|
||||||
// We don't want the process hanging
|
// We don't want the process hanging
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
@@ -26,5 +24,6 @@ on('disconnect', (reason, msg) => {
|
|||||||
logger.info(
|
logger.info(
|
||||||
`Disconnected from bot API ${++api.disconnectCount} times (this time because: ${reason}, ${msg}), reconnecting again...`,
|
`Disconnected from bot API ${++api.disconnectCount} times (this time because: ${reason}, ${msg}), reconnecting again...`,
|
||||||
)
|
)
|
||||||
|
|
||||||
setTimeout(() => api.client.connect(), 10000)
|
setTimeout(() => api.client.connect(), 10000)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
import { on } from '$utils/api/events'
|
import { on, withContext } from '$utils/api/events'
|
||||||
import { logger } from 'src/context'
|
|
||||||
|
|
||||||
on('ready', () => {
|
withContext(on, 'ready', ({ logger }) => void logger.info('Connected to the bot API'))
|
||||||
logger.info('Connected to the bot API')
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
import { on } from '$/utils/discord/events'
|
import { on } from '$/utils/discord/events'
|
||||||
import { cureNickname } from '$/utils/discord/moderation'
|
import { cureNickname } from '$/utils/discord/moderation'
|
||||||
|
|
||||||
on('guildMemberUpdate', async (_, oldMember, newMember) => {
|
on('guildMemberUpdate', async (oldMember, newMember) => {
|
||||||
if (newMember.user.bot) return
|
if (newMember.user.bot) return
|
||||||
if (oldMember.displayName !== newMember.displayName) await cureNickname(newMember)
|
if (oldMember.displayName !== newMember.displayName) await cureNickname(newMember)
|
||||||
})
|
})
|
||||||
|
|
||||||
on('guildMemberAdd', (_, member) => {
|
on('guildMemberAdd', member => {
|
||||||
if (member.user.bot) return
|
if (member.user.bot) return
|
||||||
cureNickname(member)
|
cureNickname(member)
|
||||||
})
|
})
|
||||||
|
|
||||||
on('messageCreate', async (_, msg) => {
|
on('messageCreate', async msg => {
|
||||||
if (msg.author.bot) return
|
if (msg.author.bot || !msg.member) return
|
||||||
if (!msg.member) return
|
|
||||||
await cureNickname(msg.member)
|
await cureNickname(msg.member)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { appliedPresets } from '$/database/schemas'
|
import { appliedPresets } from '$/database/schemas'
|
||||||
import { on } from '$/utils/discord/events'
|
import { on, withContext } from '$/utils/discord/events'
|
||||||
import { applyRolesUsingPreset } from '$/utils/discord/rolePresets'
|
import { applyRolesUsingPreset } from '$/utils/discord/rolePresets'
|
||||||
import { and, eq, gt } from 'drizzle-orm'
|
import { and, eq, gt } from 'drizzle-orm'
|
||||||
|
|
||||||
on('guildMemberAdd', async ({ database }, member) => {
|
withContext(on, 'guildMemberAdd', async ({ database }, member) => {
|
||||||
const applieds = await database.query.appliedPresets.findMany({
|
const applieds = await database.query.appliedPresets.findMany({
|
||||||
where: and(
|
where: and(
|
||||||
eq(appliedPresets.memberId, member.id),
|
eq(appliedPresets.memberId, member.id),
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import CommandError from '$/classes/CommandError'
|
import CommandError from '$/classes/CommandError'
|
||||||
import { createErrorEmbed, createStackTraceEmbed } from '$utils/discord/embeds'
|
import { createErrorEmbed, createStackTraceEmbed } from '$utils/discord/embeds'
|
||||||
import { on } from '$utils/discord/events'
|
import { on, withContext } from '$utils/discord/events'
|
||||||
|
|
||||||
export default on('interactionCreate', async (context, interaction) => {
|
withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||||
if (!interaction.isChatInputCommand()) return
|
if (!interaction.isChatInputCommand()) return
|
||||||
|
|
||||||
const { logger, discord, config } = context
|
const { logger, discord, config } = context
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import { responses } from '$/database/schemas'
|
import { responses } from '$/database/schemas'
|
||||||
import { handleUserResponseCorrection } from '$/utils/discord/messageScan'
|
import { handleUserResponseCorrection } from '$/utils/discord/messageScan'
|
||||||
import { createErrorEmbed, createStackTraceEmbed, createSuccessEmbed } from '$utils/discord/embeds'
|
import { createErrorEmbed, createStackTraceEmbed, createSuccessEmbed } from '$utils/discord/embeds'
|
||||||
import { on } from '$utils/discord/events'
|
import { on, withContext } from '$utils/discord/events'
|
||||||
|
|
||||||
import type { ButtonInteraction, StringSelectMenuInteraction, TextBasedChannel } from 'discord.js'
|
import type { ButtonInteraction, StringSelectMenuInteraction, TextBasedChannel } from 'discord.js'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
// No permission check required as it is already done when the user reacts to a bot response
|
// No permission check required as it is already done when the user reacts to a bot response
|
||||||
export default on('interactionCreate', async (context, interaction) => {
|
withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||||
const {
|
const {
|
||||||
logger,
|
logger,
|
||||||
database: db,
|
database: db,
|
||||||
@@ -2,15 +2,15 @@ import { MessageScanLabeledResponseReactions } from '$/constants'
|
|||||||
import { responses } from '$/database/schemas'
|
import { responses } from '$/database/schemas'
|
||||||
import { getResponseFromText, shouldScanMessage } from '$/utils/discord/messageScan'
|
import { getResponseFromText, shouldScanMessage } from '$/utils/discord/messageScan'
|
||||||
import { createMessageScanResponseEmbed } from '$utils/discord/embeds'
|
import { createMessageScanResponseEmbed } from '$utils/discord/embeds'
|
||||||
import { on } from '$utils/discord/events'
|
import { on, withContext } from '$utils/discord/events'
|
||||||
|
|
||||||
on('messageCreate', async (ctx, msg) => {
|
withContext(on, 'messageCreate', async (context, msg) => {
|
||||||
const {
|
const {
|
||||||
api,
|
api,
|
||||||
config: { messageScan: config },
|
config: { messageScan: config },
|
||||||
database: db,
|
database: db,
|
||||||
logger,
|
logger,
|
||||||
} = ctx
|
} = context
|
||||||
|
|
||||||
if (!config || !config.responses) return
|
if (!config || !config.responses) return
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ on('messageCreate', async (ctx, msg) => {
|
|||||||
try {
|
try {
|
||||||
logger.debug(`Classifying message ${msg.id}`)
|
logger.debug(`Classifying message ${msg.id}`)
|
||||||
|
|
||||||
const { response, label } = await getResponseFromText(msg.content, filteredResponses, ctx)
|
const { response, label } = await getResponseFromText(msg.content, filteredResponses, context)
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
logger.debug('Response found')
|
logger.debug('Response found')
|
||||||
@@ -59,7 +59,7 @@ on('messageCreate', async (ctx, msg) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { text: content } = await api.client.parseImage(attachment.url)
|
const { text: content } = await api.client.parseImage(attachment.url)
|
||||||
const { response } = await getResponseFromText(content, filteredResponses, ctx, true)
|
const { response } = await getResponseFromText(content, filteredResponses, context, true)
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
logger.debug(`Response found for attachment: ${attachment.url}`)
|
logger.debug(`Response found for attachment: ${attachment.url}`)
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { MessageScanLabeledResponseReactions as Reactions } from '$/constants'
|
import { MessageScanLabeledResponseReactions as Reactions } from '$/constants'
|
||||||
import { createErrorEmbed, createStackTraceEmbed, createSuccessEmbed } from '$/utils/discord/embeds'
|
import { createErrorEmbed, createStackTraceEmbed, createSuccessEmbed } from '$/utils/discord/embeds'
|
||||||
import { on } from '$/utils/discord/events'
|
import { on, withContext } from '$/utils/discord/events'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActionRowBuilder,
|
ActionRowBuilder,
|
||||||
@@ -10,14 +10,14 @@ import {
|
|||||||
StringSelectMenuOptionBuilder,
|
StringSelectMenuOptionBuilder,
|
||||||
} from 'discord.js'
|
} from 'discord.js'
|
||||||
|
|
||||||
|
import type { ConfigMessageScanResponseLabelConfig } from '$/../config.schema'
|
||||||
import { responses } from '$/database/schemas'
|
import { responses } from '$/database/schemas'
|
||||||
import { handleUserResponseCorrection } from '$/utils/discord/messageScan'
|
import { handleUserResponseCorrection } from '$/utils/discord/messageScan'
|
||||||
import type { ConfigMessageScanResponseLabelConfig } from 'config.schema'
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
const PossibleReactions = Object.values(Reactions) as string[]
|
const PossibleReactions = Object.values(Reactions) as string[]
|
||||||
|
|
||||||
on('messageReactionAdd', async (context, rct, user) => {
|
withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||||
if (user.bot) return
|
if (user.bot) return
|
||||||
|
|
||||||
const { database: db, logger, config } = context
|
const { database: db, logger, config } = context
|
||||||
@@ -3,9 +3,9 @@ import { appliedPresets } from '$/database/schemas'
|
|||||||
import { removeRolePreset } from '$/utils/discord/rolePresets'
|
import { removeRolePreset } from '$/utils/discord/rolePresets'
|
||||||
import type { Client } from 'discord.js'
|
import type { Client } from 'discord.js'
|
||||||
import { lt } from 'drizzle-orm'
|
import { lt } from 'drizzle-orm'
|
||||||
import { on } from 'src/utils/discord/events'
|
import { on, withContext } from 'src/utils/discord/events'
|
||||||
|
|
||||||
export default on('ready', ({ config, logger }, client) => {
|
export default withContext(on, 'ready', ({ config, logger }, client) => {
|
||||||
logger.info(`Connected to Discord API, logged in as ${client.user.displayName} (@${client.user.tag})!`)
|
logger.info(`Connected to Discord API, logged in as ${client.user.displayName} (@${client.user.tag})!`)
|
||||||
logger.info(
|
logger.info(
|
||||||
`Bot is in ${client.guilds.cache.size} guilds, if this is not expected, please run the /leave-unknowns command`,
|
`Bot is in ${client.guilds.cache.size} guilds, if this is not expected, please run the /leave-unknowns command`,
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
import type { ClientWebSocketEvents } from '@revanced/bot-api'
|
import type { ClientWebSocketEvents } from '@revanced/bot-api'
|
||||||
import { api } from '../../context'
|
import * as context from '../../context'
|
||||||
|
|
||||||
const { client } = api
|
const { client } = context.api
|
||||||
|
|
||||||
export const on = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => {
|
export const withContext = <Event extends EventName>(
|
||||||
client.on(event, listener)
|
fn: typeof on | typeof once,
|
||||||
}
|
event: Event,
|
||||||
|
listener: ListenerWithContextOf<Event>,
|
||||||
|
// @ts-expect-error: Not smart enough, sorry!
|
||||||
|
) => fn(event, (...args) => listener(context, ...args))
|
||||||
|
|
||||||
export const once = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => {
|
export const on = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => client.on(event, listener)
|
||||||
client.once(event, listener)
|
export const once = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => client.once(event, listener)
|
||||||
}
|
|
||||||
|
|
||||||
export type EventName = keyof ClientWebSocketEvents
|
export type EventName = keyof ClientWebSocketEvents
|
||||||
export type ListenerOf<Event extends EventName> = ClientWebSocketEvents[Event]
|
export type ListenerOf<Event extends EventName> = ClientWebSocketEvents[Event]
|
||||||
|
export type ListenerWithContextOf<Event extends EventName> = (
|
||||||
|
...args: [typeof import('../../context'), ...Parameters<ClientWebSocketEvents[Event]>]
|
||||||
|
) => void | Promise<void>
|
||||||
|
|||||||
@@ -3,17 +3,21 @@ import type { ClientEvents } from 'discord.js'
|
|||||||
|
|
||||||
const { client } = context.discord
|
const { client } = context.discord
|
||||||
|
|
||||||
export const on = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) =>
|
export const withContext = <Event extends EventName>(
|
||||||
client.on(event, (...args) => listener(context, ...args))
|
fn: typeof on | typeof once,
|
||||||
|
event: Event,
|
||||||
|
listener: ListenerWithContextOf<Event>,
|
||||||
|
) => fn(event, (...args) => listener(context, ...args))
|
||||||
|
|
||||||
export const once = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) =>
|
export const on = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => client.on(event, listener)
|
||||||
client.once(event, (...args) => listener(context, ...args))
|
export const once = <Event extends EventName>(event: Event, listener: ListenerOf<Event>) => client.once(event, listener)
|
||||||
|
|
||||||
export type EventName = keyof ClientEvents
|
export type EventName = keyof ClientEvents
|
||||||
export type EventMap = {
|
export type EventMap = {
|
||||||
[K in EventName]: ListenerOf<K>
|
[K in EventName]: ListenerOf<K>
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListenerOf<Event extends EventName> = (
|
type ListenerOf<Event extends EventName> = (...args: ClientEvents[Event]) => void | Promise<void>
|
||||||
|
type ListenerWithContextOf<Event extends EventName> = (
|
||||||
...args: [typeof import('$/context'), ...ClientEvents[Event]]
|
...args: [typeof import('$/context'), ...ClientEvents[Event]]
|
||||||
) => void | Promise<void>
|
) => void | Promise<void>
|
||||||
|
|||||||
Reference in New Issue
Block a user