From a3301c50a41aeb368d0a4df6a876c8f020c12838 Mon Sep 17 00:00:00 2001 From: Essem Date: Fri, 29 May 2026 22:45:17 -0500 Subject: [PATCH] feat: Add support for activity/status objects in messages.json --- src/events/ready.ts | 5 +++++ src/utils/misc.ts | 41 ++++++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/events/ready.ts b/src/events/ready.ts index ed42a5e4..a3cec245 100644 --- a/src/events/ready.ts +++ b/src/events/ready.ts @@ -7,6 +7,8 @@ import { activityChanger, checkBroadcast } from "#utils/misc.js"; import type { EventParams } from "#utils/types.js"; let ready = false; +let activityInterval: NodeJS.Timeout; + export default async ({ client, database }: EventParams) => { if (ready) return; @@ -29,6 +31,9 @@ export default async ({ client, database }: EventParams) => { await checkBroadcast(client, database); activityChanger(client); + if (!activityInterval) { + activityInterval = setInterval(() => activityChanger(client), 900000); + } ready = true; diff --git a/src/utils/misc.ts b/src/utils/misc.ts index a65cf866..066a6934 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -2,7 +2,17 @@ import { execFile as baseExecFile } from "node:child_process"; import process from "node:process"; import util, { promisify } from "node:util"; import { type DotenvParseOutput, config } from "dotenv"; -import type { AnyChannel, AnyPrivateChannel, Client, CommandInteraction, Guild, Message } from "oceanic.js"; +import { + ActivityTypes, + type AnyChannel, + type AnyPrivateChannel, + type BotActivity, + type Client, + type CommandInteraction, + type Guild, + type Message, + type SendStatuses, +} from "oceanic.js"; import commandsConfig from "#config/commands.json" with { type: "json" }; import messagesConfig from "#config/messages.json" with { type: "json" }; import packageJson from "../../package.json" with { type: "json" }; @@ -101,17 +111,31 @@ export function textEncode(string: string) { .replaceAll("\\,", ","); } +const activityTypes = ["online", "dnd", "idle", "invisible"]; + // set activity (a.k.a. the gamer code) export async function activityChanger(bot: Client) { if (!broadcast) { - await bot.editStatus("dnd", [ + let message: (BotActivity & { status: string }) | string = random(messagesConfig.messages); + if (typeof message === "string") { + message = { + name: message, + status: "dnd", + type: ActivityTypes.GAME, + }; + } + if (!activityTypes.includes(message.status)) message.status = "dnd"; + if (message.type < 0 || message.type > 5) message.type = 0; + const text = message.name + (commandsConfig.types.classic ? ` | @${bot.user.username} help` : ""); + await bot.editStatus(message.status as SendStatuses, [ { - type: 0, - name: random(messagesConfig.messages) + (commandsConfig.types.classic ? ` | @${bot.user.username} help` : ""), + ...message, + name: text, + // @ts-expect-error It mistakenly thinks there's no overlap here + state: message.type === ActivityTypes.CUSTOM ? text : undefined, }, ]); } - setTimeout(() => activityChanger(bot), 900000); } export async function checkBroadcast(bot: Client, db: DatabasePlugin | undefined) { @@ -135,13 +159,8 @@ export function startBroadcast(bot: Client, message: string) { } export function endBroadcast(bot: Client) { - bot.editStatus("dnd", [ - { - type: 0, - name: random(messagesConfig.messages) + (commandsConfig.types.classic ? ` | @${bot.user.username} help` : ""), - }, - ]); broadcast = false; + activityChanger(bot); } export async function exit(client: Client, database: DatabasePlugin | undefined) { -- 2.51.2