feat(PartialGroupDMChannel): add missing properties (#10502)

* fix(PartialGroupDMChannel): add missing ownerId property

* refactor: make ownerID nullable

* feat: add last_message_id & last_pin_timestamp prop

* feat: add component collector methods

* fix: handle null case

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>

---------

Co-authored-by: Vlad Frangu <me@vladfrangu.dev>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Naiyar
2025-01-14 15:22:14 +06:00
committed by Jiralite
parent 46060419a9
commit 5e66f85f55
3 changed files with 84 additions and 5 deletions

View File

@@ -95,7 +95,8 @@ const Messages = {
[DjsErrorCodes.ChannelNotCached]: 'Could not find the channel where this message came from in the cache!', [DjsErrorCodes.ChannelNotCached]: 'Could not find the channel where this message came from in the cache!',
[DjsErrorCodes.StageChannelResolve]: 'Could not resolve channel to a stage channel.', [DjsErrorCodes.StageChannelResolve]: 'Could not resolve channel to a stage channel.',
[DjsErrorCodes.GuildScheduledEventResolve]: 'Could not resolve the guild scheduled event.', [DjsErrorCodes.GuildScheduledEventResolve]: 'Could not resolve the guild scheduled event.',
[DjsErrorCodes.FetchOwnerId]: type => `Couldn't resolve the ${type} ownerId to fetch the ${type} member.`, [DjsErrorCodes.FetchOwnerId]: type =>
`Couldn't resolve the ${type} ownerId to fetch the ${type} ${type === 'group DM' ? 'owner' : 'member'}.`,
[DjsErrorCodes.InvalidType]: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`, [DjsErrorCodes.InvalidType]: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
[DjsErrorCodes.InvalidElement]: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`, [DjsErrorCodes.InvalidElement]: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,

View File

@@ -1,12 +1,14 @@
'use strict'; 'use strict';
const { BaseChannel } = require('./BaseChannel'); const { BaseChannel } = require('./BaseChannel');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { DiscordjsError, ErrorCodes } = require('../errors'); const { DiscordjsError, ErrorCodes } = require('../errors');
const PartialGroupDMMessageManager = require('../managers/PartialGroupDMMessageManager'); const PartialGroupDMMessageManager = require('../managers/PartialGroupDMMessageManager');
/** /**
* Represents a Partial Group DM Channel on Discord. * Represents a Partial Group DM Channel on Discord.
* @extends {BaseChannel} * @extends {BaseChannel}
* @implements {TextBasedChannel}
*/ */
class PartialGroupDMChannel extends BaseChannel { class PartialGroupDMChannel extends BaseChannel {
constructor(client, data) { constructor(client, data) {
@@ -44,6 +46,36 @@ class PartialGroupDMChannel extends BaseChannel {
* @type {PartialGroupDMMessageManager} * @type {PartialGroupDMMessageManager}
*/ */
this.messages = new PartialGroupDMMessageManager(this); this.messages = new PartialGroupDMMessageManager(this);
if ('owner_id' in data) {
/**
* The user id of the owner of this Group DM Channel
* @type {?Snowflake}
*/
this.ownerId = data.owner_id;
} else {
this.ownerId ??= null;
}
if ('last_message_id' in data) {
/**
* The channel's last message id, if one was sent
* @type {?Snowflake}
*/
this.lastMessageId = data.last_message_id;
} else {
this.lastMessageId ??= null;
}
if ('last_pin_timestamp' in data) {
/**
* The timestamp when the last pinned message was pinned, if there was one
* @type {?number}
*/
this.lastPinTimestamp = data.last_pin_timestamp ? Date.parse(data.last_pin_timestamp) : null;
} else {
this.lastPinTimestamp ??= null;
}
} }
/** /**
@@ -55,6 +87,19 @@ class PartialGroupDMChannel extends BaseChannel {
return this.icon && this.client.rest.cdn.channelIcon(this.id, this.icon, options); return this.icon && this.client.rest.cdn.channelIcon(this.id, this.icon, options);
} }
/**
* Fetches the owner of this Group DM Channel.
* @param {BaseFetchOptions} [options] The options for fetching the user
* @returns {Promise<User>}
*/
async fetchOwner(options) {
if (!this.ownerId) {
throw new DiscordjsError(ErrorCodes.FetchOwnerId, 'group DM');
}
return this.client.users.fetch(this.ownerId, options);
}
delete() { delete() {
return Promise.reject(new DiscordjsError(ErrorCodes.DeleteGroupDMChannel)); return Promise.reject(new DiscordjsError(ErrorCodes.DeleteGroupDMChannel));
} }
@@ -62,6 +107,25 @@ class PartialGroupDMChannel extends BaseChannel {
fetch() { fetch() {
return Promise.reject(new DiscordjsError(ErrorCodes.FetchGroupDMChannel)); return Promise.reject(new DiscordjsError(ErrorCodes.FetchGroupDMChannel));
} }
// These are here only for documentation purposes - they are implemented by TextBasedChannel
/* eslint-disable no-empty-function */
get lastMessage() {}
get lastPinAt() {}
createMessageComponentCollector() {}
awaitMessageComponent() {}
} }
TextBasedChannel.applyToClass(PartialGroupDMChannel, true, [
'bulkDelete',
'send',
'sendTyping',
'createMessageCollector',
'awaitMessages',
'fetchWebhooks',
'createWebhook',
'setRateLimitPerUser',
'setNSFW',
]);
module.exports = PartialGroupDMChannel; module.exports = PartialGroupDMChannel;

View File

@@ -1373,7 +1373,7 @@ export class ContextMenuCommandInteraction<Cached extends CacheType = CacheType>
// tslint:disable-next-line no-empty-interface // tslint:disable-next-line no-empty-interface
export interface DMChannel export interface DMChannel
extends Omit< extends Omit<
TextBasedChannelFields<false>, TextBasedChannelFields<false, true>,
'bulkDelete' | 'fetchWebhooks' | 'createWebhook' | 'setRateLimitPerUser' | 'setNSFW' 'bulkDelete' | 'fetchWebhooks' | 'createWebhook' | 'setRateLimitPerUser' | 'setNSFW'
> {} > {}
export class DMChannel extends BaseChannel { export class DMChannel extends BaseChannel {
@@ -2694,6 +2694,19 @@ export class OAuth2Guild extends BaseGuild {
public permissions: Readonly<PermissionsBitField>; public permissions: Readonly<PermissionsBitField>;
} }
export interface PartialGroupDMChannel
extends Omit<
TextBasedChannelFields<false, false>,
| 'bulkDelete'
| 'send'
| 'sendTyping'
| 'createMessageCollector'
| 'awaitMessages'
| 'fetchWebhooks'
| 'createWebhook'
| 'setRateLimitPerUser'
| 'setNSFW'
> {}
export class PartialGroupDMChannel extends BaseChannel { export class PartialGroupDMChannel extends BaseChannel {
private constructor(client: Client<true>, data: RawPartialGroupDMChannelData); private constructor(client: Client<true>, data: RawPartialGroupDMChannelData);
public type: ChannelType.GroupDM; public type: ChannelType.GroupDM;
@@ -2701,8 +2714,9 @@ export class PartialGroupDMChannel extends BaseChannel {
public name: string | null; public name: string | null;
public icon: string | null; public icon: string | null;
public recipients: PartialRecipient[]; public recipients: PartialRecipient[];
public messages: PartialGroupDMMessageManager; public ownerId: Snowflake | null;
public iconURL(options?: ImageURLOptions): string | null; public iconURL(options?: ImageURLOptions): string | null;
public fetchOwner(options?: BaseFetchOptions): Promise<User>;
public toString(): ChannelMention; public toString(): ChannelMention;
} }
@@ -4858,13 +4872,13 @@ export interface PartialTextBasedChannelFields<InGuild extends boolean = boolean
send(options: string | MessagePayload | MessageCreateOptions): Promise<Message<InGuild>>; send(options: string | MessagePayload | MessageCreateOptions): Promise<Message<InGuild>>;
} }
export interface TextBasedChannelFields<InGuild extends boolean = boolean> export interface TextBasedChannelFields<InGuild extends boolean = boolean, InDM extends boolean = boolean>
extends PartialTextBasedChannelFields<InGuild> { extends PartialTextBasedChannelFields<InGuild> {
lastMessageId: Snowflake | null; lastMessageId: Snowflake | null;
get lastMessage(): Message | null; get lastMessage(): Message | null;
lastPinTimestamp: number | null; lastPinTimestamp: number | null;
get lastPinAt(): Date | null; get lastPinAt(): Date | null;
messages: If<InGuild, GuildMessageManager, DMMessageManager>; messages: If<InGuild, GuildMessageManager, If<InDM, DMMessageManager, PartialGroupDMMessageManager>>;
awaitMessageComponent<ComponentType extends MessageComponentType>( awaitMessageComponent<ComponentType extends MessageComponentType>(
options?: AwaitMessageCollectorOptionsParams<ComponentType, true>, options?: AwaitMessageCollectorOptionsParams<ComponentType, true>,
): Promise<MappedInteractionTypes[ComponentType]>; ): Promise<MappedInteractionTypes[ComponentType]>;