diff --git a/packages/discord.js/src/managers/GuildManager.js b/packages/discord.js/src/managers/GuildManager.js index 1d2d4ba967724..7266d9a0f102e 100644 --- a/packages/discord.js/src/managers/GuildManager.js +++ b/packages/discord.js/src/managers/GuildManager.js @@ -4,7 +4,7 @@ const process = require('node:process'); const { setTimeout, clearTimeout } = require('node:timers'); const { Collection } = require('@discordjs/collection'); const { makeURLSearchParams } = require('@discordjs/rest'); -const { Routes } = require('discord-api-types/v10'); +const { Routes, RouteBases } = require('discord-api-types/v10'); const CachedManager = require('./CachedManager'); const { Guild } = require('../structures/Guild'); const GuildChannel = require('../structures/GuildChannel'); @@ -278,6 +278,20 @@ class GuildManager extends CachedManager { const data = await this.client.rest.get(Routes.userGuilds(), { query: makeURLSearchParams(options) }); return data.reduce((coll, guild) => coll.set(guild.id, new OAuth2Guild(this.client, guild)), new Collection()); } + + /** + * Returns a URL for the PNG widget of a guild. + * @param {GuildResolvable} guild The guild of the widget image + * @param {GuildWidgetStyle} [style] The style for the widget image + * @returns {string} + */ + widgetImageURL(guild, style) { + const urlSearchParams = String(makeURLSearchParams({ style })); + + return `${RouteBases.api}${Routes.guildWidgetImage(this.resolveId(guild))}${ + urlSearchParams ? `?${urlSearchParams}` : '' + }`; + } } module.exports = GuildManager; diff --git a/packages/discord.js/src/structures/Guild.js b/packages/discord.js/src/structures/Guild.js index f07e9b4e1e86f..5123ee56586cc 100644 --- a/packages/discord.js/src/structures/Guild.js +++ b/packages/discord.js/src/structures/Guild.js @@ -723,6 +723,15 @@ class Guild extends AnonymousGuild { }; } + /** + * Returns a URL for the PNG widget of the guild. + * @param {GuildWidgetStyle} [style] The style for the widget image + * @returns {string} + */ + widgetImageURL(style) { + return this.client.guilds.widgetImageURL(this.id, style); + } + /** * Options used to fetch audit logs. * @typedef {Object} GuildAuditLogsFetchOptions diff --git a/packages/discord.js/src/structures/Widget.js b/packages/discord.js/src/structures/Widget.js index 344c81a475e9f..e082fd5bde201 100644 --- a/packages/discord.js/src/structures/Widget.js +++ b/packages/discord.js/src/structures/Widget.js @@ -83,6 +83,15 @@ class Widget extends Base { this._patch(data); return this; } + + /** + * Returns a URL for the PNG widget of the guild. + * @param {GuildWidgetStyle} [style] The style for the widget image + * @returns {string} + */ + imageURL(style) { + return this.client.guilds.widgetImageURL(this.id, style); + } } module.exports = Widget; diff --git a/packages/discord.js/src/util/APITypes.js b/packages/discord.js/src/util/APITypes.js index 4020ba153b298..8f39c749b06b2 100644 --- a/packages/discord.js/src/util/APITypes.js +++ b/packages/discord.js/src/util/APITypes.js @@ -350,6 +350,11 @@ * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildVerificationLevel} */ +/** + * @external GuildWidgetStyle + * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildWidgetStyle} + */ + /** * @external IntegrationExpireBehavior * @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/IntegrationExpireBehavior} diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 929addb005b8a..a516cedf9e1a9 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -166,6 +166,7 @@ import { AttachmentFlags, RoleFlags, TeamMemberRole, + GuildWidgetStyle, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -1384,6 +1385,7 @@ export class Guild extends AnonymousGuild { public fetchWelcomeScreen(): Promise; public fetchWidget(): Promise; public fetchWidgetSettings(): Promise; + public widgetImageURL(style?: GuildWidgetStyle): string; public leave(): Promise; public disableInvites(disabled?: boolean): Promise; public setAFKChannel(afkChannel: VoiceChannelResolvable | null, reason?: string): Promise; @@ -3450,6 +3452,7 @@ export class Widget extends Base { private constructor(client: Client, data: RawWidgetData); private _patch(data: RawWidgetData): void; public fetch(): Promise; + public imageURL(style?: GuildWidgetStyle): string; public id: Snowflake; public name: string; public instantInvite?: string; @@ -3969,6 +3972,7 @@ export class GuildManager extends CachedManager; public fetch(options: Snowflake | FetchGuildOptions): Promise; public fetch(options?: FetchGuildsOptions): Promise>; + public widgetImageURL(guild: GuildResolvable, style?: GuildWidgetStyle): string; } export interface AddOrRemoveGuildMemberRoleOptions {