mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 12:03:31 +01:00
src: support new message fields (#3388)
* src: Update channel pattern * src: Remove useless non-capture group * src: it's as though we're starting fresh * src: Bring this up to date for reals now * src: typings and a bug fix * src: Add crossposted channels to message mentions * src: Requested changes and add typings * src: Move Object.keys outside loop * typings: Fix enum being exported when it shouldn't * src: Consistency with roles and users * docs: Correct docstring for MessageFlags#flags * docs: Correct docstring for MessageMentions#crosspostedChannels * docs: Suggestions Co-authored-by: SpaceEEC * src: Reset flags to 0 if no flags are received on MESSAGE_UPDATE
This commit is contained in:
@@ -20,6 +20,7 @@ module.exports = {
|
|||||||
DataStore: require('./stores/DataStore'),
|
DataStore: require('./stores/DataStore'),
|
||||||
DiscordAPIError: require('./rest/DiscordAPIError'),
|
DiscordAPIError: require('./rest/DiscordAPIError'),
|
||||||
HTTPError: require('./rest/HTTPError'),
|
HTTPError: require('./rest/HTTPError'),
|
||||||
|
MessageFlags: require('./util/MessageFlags'),
|
||||||
Permissions: require('./util/Permissions'),
|
Permissions: require('./util/Permissions'),
|
||||||
Speaking: require('./util/Speaking'),
|
Speaking: require('./util/Speaking'),
|
||||||
Snowflake: require('./util/Snowflake'),
|
Snowflake: require('./util/Snowflake'),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const Permissions = require('../util/Permissions');
|
|||||||
const Base = require('./Base');
|
const Base = require('./Base');
|
||||||
const { Error, TypeError } = require('../errors');
|
const { Error, TypeError } = require('../errors');
|
||||||
const APIMessage = require('./APIMessage');
|
const APIMessage = require('./APIMessage');
|
||||||
|
const MessageFlags = require('../util/MessageFlags');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a message on Discord.
|
* Represents a message on Discord.
|
||||||
@@ -81,7 +82,9 @@ class Message extends Base {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A random number or string used for checking message delivery
|
* A random number or string used for checking message delivery
|
||||||
* @type {string}
|
* <warn>This is only received after the message was sent successfully, and
|
||||||
|
* lost if re-fetched</warn>
|
||||||
|
* @type {?string}
|
||||||
*/
|
*/
|
||||||
this.nonce = data.nonce;
|
this.nonce = data.nonce;
|
||||||
|
|
||||||
@@ -89,7 +92,7 @@ class Message extends Base {
|
|||||||
* Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
|
* Whether or not this message was sent by Discord, not actually a user (e.g. pin notifications)
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
this.system = data.type === 6;
|
this.system = data.type !== 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of embeds in the message - e.g. YouTube Player
|
* A list of embeds in the message - e.g. YouTube Player
|
||||||
@@ -137,7 +140,7 @@ class Message extends Base {
|
|||||||
* All valid mentions that the message contains
|
* All valid mentions that the message contains
|
||||||
* @type {MessageMentions}
|
* @type {MessageMentions}
|
||||||
*/
|
*/
|
||||||
this.mentions = new Mentions(this, data.mentions, data.mention_roles, data.mention_everyone);
|
this.mentions = new Mentions(this, data.mentions, data.mention_roles, data.mention_everyone, data.mention_channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID of the webhook that sent the message, if applicable
|
* ID of the webhook that sent the message, if applicable
|
||||||
@@ -172,6 +175,30 @@ class Message extends Base {
|
|||||||
} else if (data.member && this.guild && this.author) {
|
} else if (data.member && this.guild && this.author) {
|
||||||
this.guild.members.add(Object.assign(data.member, { user: this.author }));
|
this.guild.members.add(Object.assign(data.member, { user: this.author }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags that are applied to the message
|
||||||
|
* @type {Readonly<MessageFlags>}
|
||||||
|
*/
|
||||||
|
this.flags = new MessageFlags(data.flags).freeze();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference data sent in a crossposted message.
|
||||||
|
* @typedef {Object} MessageReference
|
||||||
|
* @property {string} channelID ID of the channel the message was crossposted from
|
||||||
|
* @property {?string} guildID ID of the guild the message was crossposted from
|
||||||
|
* @property {?string} messageID ID of the message that was crossposted
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message reference data
|
||||||
|
* @type {?MessageReference}
|
||||||
|
*/
|
||||||
|
this.reference = data.message_reference ? {
|
||||||
|
channelID: data.message_reference.channel_id,
|
||||||
|
guildID: data.message_reference.guild_id,
|
||||||
|
messageID: data.message_reference.message_id,
|
||||||
|
} : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -214,8 +241,11 @@ class Message extends Base {
|
|||||||
this,
|
this,
|
||||||
'mentions' in data ? data.mentions : this.mentions.users,
|
'mentions' in data ? data.mentions : this.mentions.users,
|
||||||
'mentions_roles' in data ? data.mentions_roles : this.mentions.roles,
|
'mentions_roles' in data ? data.mentions_roles : this.mentions.roles,
|
||||||
'mention_everyone' in data ? data.mention_everyone : this.mentions.everyone
|
'mention_everyone' in data ? data.mention_everyone : this.mentions.everyone,
|
||||||
|
'mention_channels' in data ? data.mention_channels : this.mentions.crosspostedChannels
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.flags = new MessageFlags('flags' in data ? data.flags : 0).freeze();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
const Collection = require('../util/Collection');
|
const Collection = require('../util/Collection');
|
||||||
const Util = require('../util/Util');
|
const Util = require('../util/Util');
|
||||||
const GuildMember = require('./GuildMember');
|
const GuildMember = require('./GuildMember');
|
||||||
|
const { ChannelTypes } = require('../util/Constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps track of mentions in a {@link Message}.
|
* Keeps track of mentions in a {@link Message}.
|
||||||
*/
|
*/
|
||||||
class MessageMentions {
|
class MessageMentions {
|
||||||
constructor(message, users, roles, everyone) {
|
constructor(message, users, roles, everyone, crosspostedChannels) {
|
||||||
/**
|
/**
|
||||||
* The client the message is from
|
* The client the message is from
|
||||||
* @type {Client}
|
* @type {Client}
|
||||||
@@ -86,6 +87,39 @@ class MessageMentions {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this._channels = null;
|
this._channels = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crossposted channel data.
|
||||||
|
* @typedef {Object} CrosspostedChannel
|
||||||
|
* @property {string} channelID ID of the mentioned channel
|
||||||
|
* @property {string} guildID ID of the guild that has the channel
|
||||||
|
* @property {string} type Type of the channel
|
||||||
|
* @property {string} name The name of the channel
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (crosspostedChannels) {
|
||||||
|
if (crosspostedChannels instanceof Collection) {
|
||||||
|
/**
|
||||||
|
* A collection of crossposted channels
|
||||||
|
* @type {Collection<Snowflake, CrosspostedChannel>}
|
||||||
|
*/
|
||||||
|
this.crosspostedChannels = new Collection(crosspostedChannels);
|
||||||
|
} else {
|
||||||
|
this.crosspostedChannels = new Collection();
|
||||||
|
const channelTypes = Object.keys(ChannelTypes);
|
||||||
|
for (const d of crosspostedChannels) {
|
||||||
|
const type = channelTypes[d.type];
|
||||||
|
this.crosspostedChannels.set(d.id, {
|
||||||
|
channelID: d.id,
|
||||||
|
guildID: d.guild_id,
|
||||||
|
type: type ? type.toLowerCase() : 'unknown',
|
||||||
|
name: d.name,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.crosspostedChannels = new Collection();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ exports.WSEvents = keyMirror([
|
|||||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
|
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1
|
||||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
|
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2
|
||||||
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
|
* * USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3
|
||||||
|
* * CHANNEL_FOLLOW_ADD
|
||||||
* @typedef {string} MessageType
|
* @typedef {string} MessageType
|
||||||
*/
|
*/
|
||||||
exports.MessageTypes = [
|
exports.MessageTypes = [
|
||||||
@@ -401,6 +402,7 @@ exports.MessageTypes = [
|
|||||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1',
|
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1',
|
||||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2',
|
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2',
|
||||||
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3',
|
'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3',
|
||||||
|
'CHANNEL_FOLLOW_ADD',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
25
src/util/MessageFlags.js
Normal file
25
src/util/MessageFlags.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const BitField = require('./BitField');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data structure that makes it easy to interact with an {@link Message#flags} bitfield.
|
||||||
|
* @extends {BitField}
|
||||||
|
*/
|
||||||
|
class MessageFlags extends BitField {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Numeric message flags. All available properties:
|
||||||
|
* * `CROSSPOSTED`
|
||||||
|
* * `IS_CROSSPOST`
|
||||||
|
* * `SUPPRESS_EMBEDS`
|
||||||
|
* @type {Object}
|
||||||
|
* @see {@link https://discordapp.com/developers/docs/resources/channel#message-object-message-flags}
|
||||||
|
*/
|
||||||
|
MessageFlags.FLAGS = {
|
||||||
|
CROSSPOSTED: 1 << 0,
|
||||||
|
IS_CROSSPOST: 1 << 1,
|
||||||
|
SUPPRESS_EMBEDS: 1 << 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = MessageFlags;
|
||||||
49
typings/index.d.ts
vendored
49
typings/index.d.ts
vendored
@@ -1,3 +1,14 @@
|
|||||||
|
declare enum ChannelType {
|
||||||
|
text,
|
||||||
|
dm,
|
||||||
|
voice,
|
||||||
|
group,
|
||||||
|
category,
|
||||||
|
news,
|
||||||
|
store,
|
||||||
|
unknown
|
||||||
|
}
|
||||||
|
|
||||||
declare module 'discord.js' {
|
declare module 'discord.js' {
|
||||||
import BaseCollection from '@discordjs/collection';
|
import BaseCollection from '@discordjs/collection';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
@@ -125,7 +136,7 @@ declare module 'discord.js' {
|
|||||||
public readonly createdTimestamp: number;
|
public readonly createdTimestamp: number;
|
||||||
public deleted: boolean;
|
public deleted: boolean;
|
||||||
public id: Snowflake;
|
public id: Snowflake;
|
||||||
public type: 'dm' | 'text' | 'voice' | 'category' | 'news' | 'store' | 'unknown';
|
public type: keyof typeof ChannelType;
|
||||||
public delete(reason?: string): Promise<Channel>;
|
public delete(reason?: string): Promise<Channel>;
|
||||||
public fetch(): Promise<Channel>;
|
public fetch(): Promise<Channel>;
|
||||||
public toString(): string;
|
public toString(): string;
|
||||||
@@ -914,12 +925,17 @@ declare module 'discord.js' {
|
|||||||
public toString(): string;
|
public toString(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class MessageFlags extends BitField<MessageFlagsString> {
|
||||||
|
public static FLAGS: Record<MessageFlagsString, number>;
|
||||||
|
public static resolve(bit?: BitFieldResolvable<MessageFlagsString>): number;
|
||||||
|
}
|
||||||
|
|
||||||
export class Message extends Base {
|
export class Message extends Base {
|
||||||
constructor(client: Client, data: object, channel: TextChannel | DMChannel);
|
constructor(client: Client, data: object, channel: TextChannel | DMChannel);
|
||||||
private _edits: Message[];
|
private _edits: Message[];
|
||||||
private patch(data: object): void;
|
private patch(data: object): void;
|
||||||
|
|
||||||
public activity: GroupActivity | null;
|
public activity: MessageActivity | null;
|
||||||
public application: ClientApplication | null;
|
public application: ClientApplication | null;
|
||||||
public attachments: Collection<Snowflake, MessageAttachment>;
|
public attachments: Collection<Snowflake, MessageAttachment>;
|
||||||
public author: User | null;
|
public author: User | null;
|
||||||
@@ -939,7 +955,7 @@ declare module 'discord.js' {
|
|||||||
public id: Snowflake;
|
public id: Snowflake;
|
||||||
public readonly member: GuildMember | null;
|
public readonly member: GuildMember | null;
|
||||||
public mentions: MessageMentions;
|
public mentions: MessageMentions;
|
||||||
public nonce: string;
|
public nonce: string | null;
|
||||||
public readonly partial: boolean;
|
public readonly partial: boolean;
|
||||||
public readonly pinnable: boolean;
|
public readonly pinnable: boolean;
|
||||||
public pinned: boolean;
|
public pinned: boolean;
|
||||||
@@ -949,6 +965,8 @@ declare module 'discord.js' {
|
|||||||
public type: MessageType;
|
public type: MessageType;
|
||||||
public readonly url: string;
|
public readonly url: string;
|
||||||
public webhookID: Snowflake | null;
|
public webhookID: Snowflake | null;
|
||||||
|
public flags: Readonly<MessageFlags>;
|
||||||
|
public reference: MessageReference | null;
|
||||||
public awaitReactions(filter: CollectorFilter, options?: AwaitReactionsOptions): Promise<Collection<Snowflake, MessageReaction>>;
|
public awaitReactions(filter: CollectorFilter, options?: AwaitReactionsOptions): Promise<Collection<Snowflake, MessageReaction>>;
|
||||||
public createReactionCollector(filter: CollectorFilter, options?: ReactionCollectorOptions): ReactionCollector;
|
public createReactionCollector(filter: CollectorFilter, options?: ReactionCollectorOptions): ReactionCollector;
|
||||||
public delete(options?: { timeout?: number, reason?: string }): Promise<Message>;
|
public delete(options?: { timeout?: number, reason?: string }): Promise<Message>;
|
||||||
@@ -1054,6 +1072,7 @@ declare module 'discord.js' {
|
|||||||
public readonly members: Collection<Snowflake, GuildMember> | null;
|
public readonly members: Collection<Snowflake, GuildMember> | null;
|
||||||
public roles: Collection<Snowflake, Role>;
|
public roles: Collection<Snowflake, Role>;
|
||||||
public users: Collection<Snowflake, User>;
|
public users: Collection<Snowflake, User>;
|
||||||
|
public crosspostedChannels: Collection<Snowflake, CrosspostedChannel>;
|
||||||
public toJSON(): object;
|
public toJSON(): object;
|
||||||
|
|
||||||
public static CHANNELS_PATTERN: RegExp;
|
public static CHANNELS_PATTERN: RegExp;
|
||||||
@@ -1886,6 +1905,10 @@ declare module 'discord.js' {
|
|||||||
| 'LISTENING'
|
| 'LISTENING'
|
||||||
| 'WATCHING';
|
| 'WATCHING';
|
||||||
|
|
||||||
|
type MessageFlagsString = 'CROSSPOSTED'
|
||||||
|
| 'IS_CROSSPOST'
|
||||||
|
| 'SUPPRESS_EMBEDS';
|
||||||
|
|
||||||
interface APIErrror {
|
interface APIErrror {
|
||||||
UNKNOWN_ACCOUNT: number;
|
UNKNOWN_ACCOUNT: number;
|
||||||
UNKNOWN_APPLICATION: number;
|
UNKNOWN_APPLICATION: number;
|
||||||
@@ -2128,11 +2151,17 @@ declare module 'discord.js' {
|
|||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GroupActivity {
|
interface MessageActivity {
|
||||||
partyID: string;
|
partyID: string;
|
||||||
type: number;
|
type: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MessageReference {
|
||||||
|
channelID: string;
|
||||||
|
guildID: string;
|
||||||
|
messageID: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
type GuildAuditLogsAction = keyof GuildAuditLogsActions;
|
type GuildAuditLogsAction = keyof GuildAuditLogsActions;
|
||||||
|
|
||||||
interface GuildAuditLogsActions {
|
interface GuildAuditLogsActions {
|
||||||
@@ -2196,7 +2225,7 @@ declare module 'discord.js' {
|
|||||||
interface GuildCreateChannelOptions {
|
interface GuildCreateChannelOptions {
|
||||||
permissionOverwrites?: OverwriteResolvable[] | Collection<Snowflake, OverwriteResolvable>;
|
permissionOverwrites?: OverwriteResolvable[] | Collection<Snowflake, OverwriteResolvable>;
|
||||||
topic?: string;
|
topic?: string;
|
||||||
type?: 'text' | 'voice' | 'category';
|
type?: Exclude<keyof typeof ChannelType, 'dm' | 'group' | 'unknown'>;
|
||||||
nsfw?: boolean;
|
nsfw?: boolean;
|
||||||
parent?: ChannelResolvable;
|
parent?: ChannelResolvable;
|
||||||
bitrate?: number;
|
bitrate?: number;
|
||||||
@@ -2373,7 +2402,8 @@ declare module 'discord.js' {
|
|||||||
| 'USER_PREMIUM_GUILD_SUBSCRIPTION'
|
| 'USER_PREMIUM_GUILD_SUBSCRIPTION'
|
||||||
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1'
|
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1'
|
||||||
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2'
|
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2'
|
||||||
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3';
|
| 'USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3'
|
||||||
|
| 'CHANNEL_FOLLOW_ADD';
|
||||||
|
|
||||||
interface OverwriteData {
|
interface OverwriteData {
|
||||||
allow?: PermissionResolvable;
|
allow?: PermissionResolvable;
|
||||||
@@ -2611,5 +2641,12 @@ declare module 'discord.js' {
|
|||||||
type CloseEvent = { wasClean: boolean; code: number; reason: string; target: WebSocket; };
|
type CloseEvent = { wasClean: boolean; code: number; reason: string; target: WebSocket; };
|
||||||
type ErrorEvent = { error: any, message: string, type: string, target: WebSocket; };
|
type ErrorEvent = { error: any, message: string, type: string, target: WebSocket; };
|
||||||
|
|
||||||
|
interface CrosspostedChannel {
|
||||||
|
channelID: Snowflake;
|
||||||
|
guildID: Snowflake;
|
||||||
|
type: keyof typeof ChannelType;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user