diff --git a/packages/discord.js/src/client/BaseClient.js b/packages/discord.js/src/client/BaseClient.js index 60068e164259..3020db823af3 100644 --- a/packages/discord.js/src/client/BaseClient.js +++ b/packages/discord.js/src/client/BaseClient.js @@ -18,6 +18,12 @@ class BaseClient extends EventEmitter { throw new DiscordjsTypeError(ErrorCodes.InvalidType, 'options', 'object', true); } + if (options.rest?.userAgentAppendix) { + // Merging the default options when a custom user agent appendix is supplied + // Replaces the discord.js string. Enforce it. + options.rest.userAgentAppendix = `${Options.userAgentAppendix} ${options.rest.userAgentAppendix}`; + } + /** * The options the client was instantiated with * @type {ClientOptions} diff --git a/packages/discord.js/src/util/Options.js b/packages/discord.js/src/util/Options.js index f6106f3bc5cf..52a756e9446c 100644 --- a/packages/discord.js/src/util/Options.js +++ b/packages/discord.js/src/util/Options.js @@ -1,8 +1,9 @@ 'use strict'; const process = require('node:process'); -const { DefaultRestOptions } = require('@discordjs/rest'); +const { DefaultRestOptions, DefaultUserAgentAppendix } = require('@discordjs/rest'); const { toSnakeCase } = require('./Transformers'); +const { version } = require('../../package.json'); /** * @typedef {Function} CacheFactory @@ -70,6 +71,14 @@ const { toSnakeCase } = require('./Transformers'); * Contains various utilities for client options. */ class Options extends null { + /** + * The default user agent appendix. + * @type {string} + * @memberof Options + * @private + */ + static userAgentAppendix = `discord.js/${version} ${DefaultUserAgentAppendix}`.trimEnd(); + /** * The default client options. * @returns {ClientOptions} @@ -94,7 +103,10 @@ class Options extends null { }, version: 10, }, - rest: DefaultRestOptions, + rest: { + ...DefaultRestOptions, + userAgentAppendix: this.userAgentAppendix, + }, jsonTransformer: toSnakeCase, }; } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index d55c057a19fa..282e81b0db84 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1030,6 +1030,7 @@ export class ClientUser extends User { export class Options extends null { private constructor(); + private static userAgentAppendix: string; public static get DefaultMakeCacheSettings(): CacheWithLimitsOptions; public static get DefaultSweeperSettings(): SweeperOptions; public static createDefault(): ClientOptions; diff --git a/packages/rest/src/lib/REST.ts b/packages/rest/src/lib/REST.ts index d4bd5f5b75fc..7369187f4568 100644 --- a/packages/rest/src/lib/REST.ts +++ b/packages/rest/src/lib/REST.ts @@ -110,7 +110,7 @@ export interface RESTOptions { /** * Extra information to add to the user agent * - * @defaultValue `Node.js ${process.version}` + * @defaultValue DefaultUserAgentAppendix */ userAgentAppendix: string; /** diff --git a/packages/rest/src/lib/utils/constants.ts b/packages/rest/src/lib/utils/constants.ts index ff7ad64fc876..105af92cbdaa 100644 --- a/packages/rest/src/lib/utils/constants.ts +++ b/packages/rest/src/lib/utils/constants.ts @@ -6,6 +6,11 @@ import type { RESTOptions } from '../REST.js'; export const DefaultUserAgent = `DiscordBot (https://discord.js.org, [VI]{{inject}}[/VI])` as `DiscordBot (https://discord.js.org, ${string})`; +/** + * The default string to append onto the user agent. + */ +export const DefaultUserAgentAppendix = process.release?.name === 'node' ? `Node.js/${process.version}` : ''; + export const DefaultRestOptions = { get agent() { return new Agent({ @@ -24,7 +29,7 @@ export const DefaultRestOptions = { rejectOnRateLimit: null, retries: 3, timeout: 15_000, - userAgentAppendix: `Node.js ${process.version}`, + userAgentAppendix: DefaultUserAgentAppendix, version: APIVersion, hashSweepInterval: 14_400_000, // 4 Hours hashLifetime: 86_400_000, // 24 Hours