Extending the Client with Uptime
Tracking Ready Time (or Uptime) in Your Seyfert Bot
Adding a readyAt property to your bot’s client is a simple way to track when your bot became ready.
Adding readyAt to the Client
To begin, extend the UsingClient interface by adding the readyAt property. This ensures that the property is type-checked across your project.
Step 1: Extend the Interface
Update your Declare Module file with the following code:
declare module "seyfert" { interface interface UsingClient
UsingClient extends type ParseClient<T extends BaseClient> = T
ParseClient<class Client<Ready extends boolean = boolean>
Client<true>> { // Other custom properties... UsingClient.readyAt?: Date
readyAt?: interface Date
Enables basic storage and retrieval of dates and times.
Date; // Tracks when the bot became ready (uptime) }
// Other declarations...}Initializing readyAt
The readyAt property should be set when the bot is ready. This can be done in the ready event handler.
Step 2: Set readyAt in the Ready Event
Add the following code to your botReady event:
import { function createEvent<E extends ClientNameEvents | CustomEventsKeys>(data: { data: { name: E; once?: boolean; }; run: (...args: ResolveEventParams<E>) => any;}): { data: { name: E; once?: boolean; }; run: (...args: ResolveEventParams<E>) => any;}
Creates an event with the specified data and run function.
createEvent } from "seyfert";
export default createEvent<"botReady">(data: { data: { name: "botReady"; once?: boolean; }; run: (args_0: ClientUser, args_1: UsingClient, args_2: number) => any;}): { data: { name: "botReady"; once?: boolean; }; run: (args_0: ClientUser, args_1: UsingClient, args_2: number) => any;}
Creates an event with the specified data and run function.
createEvent({ data: { name: "botReady"; once?: boolean;}
data: { once?: boolean
once: true, name: "botReady"
name: "botReady" }, run: (args_0: ClientUser, args_1: UsingClient, args_2: number) => any
run(user: ClientUser
user, client: UsingClient
client) { // Set the readyAt to the current date and time client: UsingClient
client.UsingClient.readyAt?: Date
readyAt = new var Date: DateConstructornew () => Date (+3 overloads)
Date();
// Other startup logic... },});This ensures that client.readyAt is initialized to the exact moment the bot becomes ready.
For more information on how to declare events, visit Listening to Events.
Using the readyAt Property
You can display the readyAt time using a timestamp formatter. This is especially useful for commands or logs.
Step 3: Format readyAt as a Timestamp
To format and display the readyAt value, use the Formatter.timestamp method:
Formatter.timestamp(client.readyAt);This will return a formatted timestamp that you can include in your messages or logs.
Example Command
Here’s an example command to display the bot’s ready time:
import { function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare, type class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext, class Command
Command, const Formatter: { codeBlock(content: string, language?: string): string; inlineCode(content: string): `\`${string}\``; bold(content: string): `**${string}**`; italic(content: string): `*${string}*`; ... 15 more ...; generateOAuth2URL(applicationId: string, { scopes, permissions, disableGuildSelect }: OAuth2URLOptions): string;}
Represents a formatter utility for formatting content.
Formatter } from "seyfert";
@function Declare(declare: CommandDeclareOptions): <T extends { new (...args: any[]): object;}>(target: T) => { new (...args: any[]): { name: string; nsfw: boolean | undefined; props: ExtraProps | undefined; contexts: InteractionContextType[]; integrationTypes: ApplicationIntegrationType[]; defaultMemberPermissions: bigint | undefined; botPermissions: bigint | undefined; description: string; type: ApplicationCommandType; guildId?: string[]; ignore?: IgnoreCommand; aliases?: string[]; handler?: EntryPointCommandHandlerType; };} & T
Declare({ name: string
name: 'uptime', description: string
description: 'Show the bot’s ready time',})export default class class ReadyAtCommand
ReadyAtCommand extends class Command
Command { async ReadyAtCommand.run(ctx: CommandContext): Promise<void>
run(ctx: CommandContext<{}, never>
ctx: class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext) { const const readyAtFormatted: `<t:${number}:t>` | `<t:${number}:T>` | `<t:${number}:d>` | `<t:${number}:D>` | `<t:${number}:f>` | `<t:${number}:F>` | `<t:${number}:R>`
readyAtFormatted = const Formatter: { codeBlock(content: string, language?: string): string; inlineCode(content: string): `\`${string}\``; bold(content: string): `**${string}**`; italic(content: string): `*${string}*`; ... 15 more ...; generateOAuth2URL(applicationId: string, { scopes, permissions, disableGuildSelect }: OAuth2URLOptions): string;}
Represents a formatter utility for formatting content.
Formatter.function timestamp(timestamp: Date, style?: TimestampStyle): `<t:${number}:t>` | `<t:${number}:T>` | `<t:${number}:d>` | `<t:${number}:D>` | `<t:${number}:f>` | `<t:${number}:F>` | `<t:${number}:R>`
Formats the given timestamp into discord unix timestamp format.
timestamp(ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.client: UsingClient
client.UsingClient.readyAt: Date
readyAt); await ctx: CommandContext<{}, never>
ctx.CommandContext<{}, never>.editOrReply<false>(body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, withResponse?: false | undefined): Promise<...>
editOrReply({ content: string
content: `The bot became ready on ${const readyAtFormatted: `<t:${number}:t>` | `<t:${number}:T>` | `<t:${number}:d>` | `<t:${number}:D>` | `<t:${number}:f>` | `<t:${number}:F>` | `<t:${number}:R>`
readyAtFormatted}.` }); }}Conclusion
By extending your client with a readyAt property, you gain the ability to track and display your bot’s ready time (or “uptime”) in a user-friendly way. This feature not only improves monitoring but also enhances the overall user experience.