diff --git a/packages/discord.js/src/client/actions/Action.js b/packages/discord.js/src/client/actions/Action.js
index 8d4e30d82..41c4febea 100644
--- a/packages/discord.js/src/client/actions/Action.js
+++ b/packages/discord.js/src/client/actions/Action.js
@@ -33,10 +33,16 @@ class GenericAction {
const payloadData = {};
const id = data.channel_id ?? data.id;
- if (!('recipients' in data)) {
- // Try to resolve the recipient, but do not add the client user.
+ if ('recipients' in data) {
+ // Try to resolve the recipient, but do not add if already existing in recipients.
const recipient = data.author ?? data.user ?? { id: data.user_id };
- if (recipient.id !== this.client.user.id) payloadData.recipients = [recipient];
+ if (!data.recipients.some(existingRecipient => recipient.id === existingRecipient.id)) {
+ payloadData.recipients = [...data.recipients, recipient];
+ }
+ } else {
+ // Try to resolve the recipient.
+ const recipient = data.author ?? data.user ?? { id: data.user_id };
+ payloadData.recipients = [recipient];
}
if (id !== undefined) payloadData.id = id;
diff --git a/packages/discord.js/src/client/actions/InteractionCreate.js b/packages/discord.js/src/client/actions/InteractionCreate.js
index ee04fa20b..4ea5ac86b 100644
--- a/packages/discord.js/src/client/actions/InteractionCreate.js
+++ b/packages/discord.js/src/client/actions/InteractionCreate.js
@@ -21,7 +21,9 @@ class InteractionCreateAction extends Action {
const client = this.client;
// Resolve and cache partial channels for Interaction#channel getter
- const channel = data.channel && this.getChannel(data.channel);
+ const channel =
+ data.channel &&
+ this.getChannel({ ...data.channel, ...('recipients' in data.channel ? { user: data.user } : undefined) });
// Do not emit this for interactions that cache messages that are non-text-based.
let InteractionClass;
diff --git a/packages/discord.js/src/managers/UserManager.js b/packages/discord.js/src/managers/UserManager.js
index d8927a0b2..0842e50e9 100644
--- a/packages/discord.js/src/managers/UserManager.js
+++ b/packages/discord.js/src/managers/UserManager.js
@@ -41,9 +41,12 @@ class UserManager extends CachedManager {
* @private
*/
dmChannel(userId) {
+ const expectedRecipientIds = [userId, this.client.user.id];
return (
- this.client.channels.cache.find(channel => channel.type === ChannelType.DM && channel.recipientId === userId) ??
- null
+ this.client.channels.cache.find(
+ channel =>
+ channel.type === ChannelType.DM && channel.recipientIds.every(id => expectedRecipientIds.includes(id)),
+ ) ?? null
);
}
diff --git a/packages/discord.js/src/structures/DMChannel.js b/packages/discord.js/src/structures/DMChannel.js
index ee466442a..83c14b06a 100644
--- a/packages/discord.js/src/structures/DMChannel.js
+++ b/packages/discord.js/src/structures/DMChannel.js
@@ -30,16 +30,18 @@ class DMChannel extends BaseChannel {
super._patch(data);
if (data.recipients) {
- const recipient = data.recipients[0];
-
/**
- * The recipient's id
- * @type {Snowflake}
+ * The recipients' ids
+ * @type {Snowflake[]}
*/
- this.recipientId = recipient.id;
+ this.recipientIds = [
+ ...new Set([...(this.recipientIds ?? []), ...data.recipients.map(recipient => recipient.id)]),
+ ];
- if ('username' in recipient || this.client.options.partials.includes(Partials.User)) {
- this.client.users._add(recipient);
+ for (const recipient of data.recipients) {
+ if ('username' in recipient || this.client.options.partials.includes(Partials.User)) {
+ this.client.users._add(recipient);
+ }
}
}
@@ -71,6 +73,18 @@ class DMChannel extends BaseChannel {
return this.lastMessageId === undefined;
}
+ /**
+ * The recipient's id.
+ * For DMChannel the client user is not a part of this might return a wrong id.
+ * This will return `null` in the next major version.
+ * @type {Snowflake}
+ * @readonly
+ */
+ get recipientId() {
+ // To not be a breaking change this returns the arbitrary first id if this is not a DMChannel with the client user
+ return this.recipientIds.find(recipientId => recipientId !== this.client.user.id) ?? this.recipientIds[0];
+ }
+
/**
* The recipient on the other end of the DM
* @type {?User}
diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts
index f14e53f40..08a357b9c 100644
--- a/packages/discord.js/typings/index.d.ts
+++ b/packages/discord.js/typings/index.d.ts
@@ -1514,7 +1514,8 @@ export interface DMChannel extends Omit<
export class DMChannel extends BaseChannel {
private constructor(client: Client, data?: RawDMChannelData);
public flags: Readonly;
- public recipientId: Snowflake;
+ public get recipientId(): Snowflake;
+ public recipientIds: Snowflake[];
public get recipient(): User | null;
public type: ChannelType.DM;
public fetch(force?: boolean): Promise;