mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 20:43:30 +01:00
feat(Threads): add support for invitable in private threads (#6501)
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com> Co-authored-by: SpaceEEC <spaceeec@yahoo.com> Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
@@ -99,6 +99,7 @@ const Messages = {
|
|||||||
|
|
||||||
MESSAGE_THREAD_PARENT: 'The message was not sent in a guild text or news channel',
|
MESSAGE_THREAD_PARENT: 'The message was not sent in a guild text or news channel',
|
||||||
MESSAGE_EXISTING_THREAD: 'The message already has a thread',
|
MESSAGE_EXISTING_THREAD: 'The message already has a thread',
|
||||||
|
THREAD_INVITABLE_TYPE: type => `Invitable cannot be edited on ${type}`,
|
||||||
|
|
||||||
WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
|
WEBHOOK_MESSAGE: 'The message was not sent by a webhook.',
|
||||||
WEBHOOK_TOKEN_UNAVAILABLE: 'This action requires a webhook token, but none is available.',
|
WEBHOOK_TOKEN_UNAVAILABLE: 'This action requires a webhook token, but none is available.',
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ class ThreadManager extends CachedManager {
|
|||||||
* @property {ThreadChannelTypes|number} [type] The type of thread to create. Defaults to `GUILD_PUBLIC_THREAD` if
|
* @property {ThreadChannelTypes|number} [type] The type of thread to create. Defaults to `GUILD_PUBLIC_THREAD` if
|
||||||
* created in a {@link TextChannel} <warn>When creating threads in a {@link NewsChannel} this is ignored and is always
|
* created in a {@link TextChannel} <warn>When creating threads in a {@link NewsChannel} this is ignored and is always
|
||||||
* `GUILD_NEWS_THREAD`</warn>
|
* `GUILD_NEWS_THREAD`</warn>
|
||||||
|
* @property {boolean} [invitable] Whether non-moderators can add other non-moderators to the thread
|
||||||
|
* <info>Can only be set when type will be `GUILD_PRIVATE_THREAD`</info>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +108,7 @@ class ThreadManager extends CachedManager {
|
|||||||
* .then(threadChannel => console.log(threadChannel))
|
* .then(threadChannel => console.log(threadChannel))
|
||||||
* .catch(console.error);
|
* .catch(console.error);
|
||||||
*/
|
*/
|
||||||
async create({ name, autoArchiveDuration, startMessage, type, reason } = {}) {
|
async create({ name, autoArchiveDuration, startMessage, type, invitable, reason } = {}) {
|
||||||
let path = this.client.api.channels(this.channel.id);
|
let path = this.client.api.channels(this.channel.id);
|
||||||
if (type && typeof type !== 'string' && typeof type !== 'number') {
|
if (type && typeof type !== 'string' && typeof type !== 'number') {
|
||||||
throw new TypeError('INVALID_TYPE', 'type', 'ThreadChannelType or Number');
|
throw new TypeError('INVALID_TYPE', 'type', 'ThreadChannelType or Number');
|
||||||
@@ -134,6 +136,7 @@ class ThreadManager extends CachedManager {
|
|||||||
name,
|
name,
|
||||||
auto_archive_duration: autoArchiveDuration,
|
auto_archive_duration: autoArchiveDuration,
|
||||||
type: resolvedType,
|
type: resolvedType,
|
||||||
|
invitable: resolvedType === ChannelTypes.GUILD_PRIVATE_THREAD ? invitable : undefined,
|
||||||
},
|
},
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const Channel = require('./Channel');
|
const Channel = require('./Channel');
|
||||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||||
|
const { RangeError } = require('../errors');
|
||||||
const MessageManager = require('../managers/MessageManager');
|
const MessageManager = require('../managers/MessageManager');
|
||||||
const ThreadMemberManager = require('../managers/ThreadMemberManager');
|
const ThreadMemberManager = require('../managers/ThreadMemberManager');
|
||||||
const Permissions = require('../util/Permissions');
|
const Permissions = require('../util/Permissions');
|
||||||
@@ -77,6 +78,13 @@ class ThreadChannel extends Channel {
|
|||||||
*/
|
*/
|
||||||
this.locked = data.thread_metadata.locked ?? false;
|
this.locked = data.thread_metadata.locked ?? false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether members without `MANAGE_THREADS` can invite other members without `MANAGE_THREADS`
|
||||||
|
* <info>Always `null` in public threads</info>
|
||||||
|
* @type {?boolean}
|
||||||
|
*/
|
||||||
|
this.invitable = this.type === 'GUILD_PRIVATE_THREAD' ? data.thread_metadata.invitable ?? false : null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the thread is archived
|
* Whether the thread is archived
|
||||||
* @type {?boolean}
|
* @type {?boolean}
|
||||||
@@ -109,6 +117,7 @@ class ThreadChannel extends Channel {
|
|||||||
if (!this.archiveTimestamp) {
|
if (!this.archiveTimestamp) {
|
||||||
this.archiveTimestamp = null;
|
this.archiveTimestamp = null;
|
||||||
}
|
}
|
||||||
|
this.invitable ??= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('owner_id' in data) {
|
if ('owner_id' in data) {
|
||||||
@@ -273,6 +282,8 @@ class ThreadChannel extends Channel {
|
|||||||
* should automatically archive in case of no recent activity
|
* should automatically archive in case of no recent activity
|
||||||
* @property {number} [rateLimitPerUser] The ratelimit per user for the thread in seconds
|
* @property {number} [rateLimitPerUser] The ratelimit per user for the thread in seconds
|
||||||
* @property {boolean} [locked] Whether the thread is locked
|
* @property {boolean} [locked] Whether the thread is locked
|
||||||
|
* @property {boolean} [invitable] Whether non-moderators can add other non-moderators to a thread
|
||||||
|
* <info>Can only be edited on `GUILD_PRIVATE_THREAD`</info>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,6 +314,7 @@ class ThreadChannel extends Channel {
|
|||||||
auto_archive_duration: autoArchiveDuration,
|
auto_archive_duration: autoArchiveDuration,
|
||||||
rate_limit_per_user: data.rateLimitPerUser,
|
rate_limit_per_user: data.rateLimitPerUser,
|
||||||
locked: data.locked,
|
locked: data.locked,
|
||||||
|
invitable: this.type === 'GUILD_PRIVATE_THREAD' ? data.invitable : undefined,
|
||||||
},
|
},
|
||||||
reason,
|
reason,
|
||||||
});
|
});
|
||||||
@@ -343,6 +355,18 @@ class ThreadChannel extends Channel {
|
|||||||
return this.edit({ autoArchiveDuration }, reason);
|
return this.edit({ autoArchiveDuration }, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether members without the `MANAGE_THREADS` permission can invite other members without the
|
||||||
|
* `MANAGE_THREADS` permission to this thread.
|
||||||
|
* @param {boolean} [invitable=true] Whether non-moderators can invite non-moderators to this thread
|
||||||
|
* @param {string} [reason] Reason for changing invite
|
||||||
|
* @returns {Promise<ThreadChannel>}
|
||||||
|
*/
|
||||||
|
setInvitable(invitable = true, reason) {
|
||||||
|
if (this.type !== 'GUILD_PRIVATE_THREAD') return Promise.reject(new RangeError('THREAD_INVITABLE_TYPE', this.type));
|
||||||
|
return this.edit({ invitable }, reason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the thread can be **unarchived** by anyone with `SEND_MESSAGES` permission.
|
* Sets whether the thread can be **unarchived** by anyone with `SEND_MESSAGES` permission.
|
||||||
* When a thread is locked only members with `MANAGE_THREADS` can unarchive it.
|
* When a thread is locked only members with `MANAGE_THREADS` can unarchive it.
|
||||||
|
|||||||
8
typings/index.d.ts
vendored
8
typings/index.d.ts
vendored
@@ -306,7 +306,7 @@ export class BaseGuildTextChannel extends TextBasedChannel(GuildChannel) {
|
|||||||
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
|
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
|
||||||
public messages: MessageManager;
|
public messages: MessageManager;
|
||||||
public nsfw: boolean;
|
public nsfw: boolean;
|
||||||
public threads: ThreadManager<AllowedThreadTypeForTextChannel>;
|
public threads: ThreadManager<AllowedThreadTypeForTextChannel | AllowedThreadTypeForNewsChannel>;
|
||||||
public topic: string | null;
|
public topic: string | null;
|
||||||
public createInvite(options?: CreateInviteOptions): Promise<Invite>;
|
public createInvite(options?: CreateInviteOptions): Promise<Invite>;
|
||||||
public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
|
public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
|
||||||
@@ -1412,6 +1412,7 @@ export class MessageSelectMenu extends BaseMessageComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NewsChannel extends BaseGuildTextChannel {
|
export class NewsChannel extends BaseGuildTextChannel {
|
||||||
|
public threads: ThreadManager<AllowedThreadTypeForNewsChannel>;
|
||||||
public type: 'GUILD_NEWS';
|
public type: 'GUILD_NEWS';
|
||||||
public addFollower(channel: GuildChannelResolvable, reason?: string): Promise<NewsChannel>;
|
public addFollower(channel: GuildChannelResolvable, reason?: string): Promise<NewsChannel>;
|
||||||
}
|
}
|
||||||
@@ -1782,6 +1783,7 @@ export class TeamMember extends Base {
|
|||||||
|
|
||||||
export class TextChannel extends BaseGuildTextChannel {
|
export class TextChannel extends BaseGuildTextChannel {
|
||||||
public rateLimitPerUser: number;
|
public rateLimitPerUser: number;
|
||||||
|
public threads: ThreadManager<AllowedThreadTypeForTextChannel>;
|
||||||
public type: 'GUILD_TEXT';
|
public type: 'GUILD_TEXT';
|
||||||
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<TextChannel>;
|
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<TextChannel>;
|
||||||
}
|
}
|
||||||
@@ -1796,6 +1798,7 @@ export class ThreadChannel extends TextBasedChannel(Channel) {
|
|||||||
public guild: Guild;
|
public guild: Guild;
|
||||||
public guildId: Snowflake;
|
public guildId: Snowflake;
|
||||||
public readonly guildMembers: Collection<Snowflake, GuildMember>;
|
public readonly guildMembers: Collection<Snowflake, GuildMember>;
|
||||||
|
public invitable: boolean | null;
|
||||||
public readonly joinable: boolean;
|
public readonly joinable: boolean;
|
||||||
public readonly joined: boolean;
|
public readonly joined: boolean;
|
||||||
public locked: boolean | null;
|
public locked: boolean | null;
|
||||||
@@ -1825,6 +1828,7 @@ export class ThreadChannel extends TextBasedChannel(Channel) {
|
|||||||
autoArchiveDuration: ThreadAutoArchiveDuration,
|
autoArchiveDuration: ThreadAutoArchiveDuration,
|
||||||
reason?: string,
|
reason?: string,
|
||||||
): Promise<ThreadChannel>;
|
): Promise<ThreadChannel>;
|
||||||
|
public setInvitable(invitable?: boolean, reason?: string): Promise<ThreadChannel>;
|
||||||
public setLocked(locked?: boolean, reason?: string): Promise<ThreadChannel>;
|
public setLocked(locked?: boolean, reason?: string): Promise<ThreadChannel>;
|
||||||
public setName(name: string, reason?: string): Promise<ThreadChannel>;
|
public setName(name: string, reason?: string): Promise<ThreadChannel>;
|
||||||
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<ThreadChannel>;
|
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<ThreadChannel>;
|
||||||
@@ -4593,6 +4597,7 @@ export type ThreadChannelTypes = 'GUILD_NEWS_THREAD' | 'GUILD_PUBLIC_THREAD' | '
|
|||||||
export interface ThreadCreateOptions<AllowedThreadType> extends StartThreadOptions {
|
export interface ThreadCreateOptions<AllowedThreadType> extends StartThreadOptions {
|
||||||
startMessage?: MessageResolvable;
|
startMessage?: MessageResolvable;
|
||||||
type?: AllowedThreadType;
|
type?: AllowedThreadType;
|
||||||
|
invitable?: AllowedThreadType extends 'GUILD_PRIVATE_THREAD' | 12 ? boolean : never;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThreadEditData {
|
export interface ThreadEditData {
|
||||||
@@ -4601,6 +4606,7 @@ export interface ThreadEditData {
|
|||||||
autoArchiveDuration?: ThreadAutoArchiveDuration;
|
autoArchiveDuration?: ThreadAutoArchiveDuration;
|
||||||
rateLimitPerUser?: number;
|
rateLimitPerUser?: number;
|
||||||
locked?: boolean;
|
locked?: boolean;
|
||||||
|
invitable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ThreadMemberFlagsString = '';
|
export type ThreadMemberFlagsString = '';
|
||||||
|
|||||||
Reference in New Issue
Block a user