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:
Vlad Frangu
2019-10-01 12:01:55 +03:00
committed by SpaceEEC
parent a03e439d6b
commit a4f06bdffd
6 changed files with 140 additions and 11 deletions

View File

@@ -13,6 +13,7 @@ const Permissions = require('../util/Permissions');
const Base = require('./Base');
const { Error, TypeError } = require('../errors');
const APIMessage = require('./APIMessage');
const MessageFlags = require('../util/MessageFlags');
/**
* Represents a message on Discord.
@@ -81,7 +82,9 @@ class Message extends Base {
/**
* 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;
@@ -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)
* @type {boolean}
*/
this.system = data.type === 6;
this.system = data.type !== 0;
/**
* 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
* @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
@@ -172,6 +175,30 @@ class Message extends Base {
} else if (data.member && this.guild && 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,
'mentions' in data ? data.mentions : this.mentions.users,
'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();
}
/**

View File

@@ -3,12 +3,13 @@
const Collection = require('../util/Collection');
const Util = require('../util/Util');
const GuildMember = require('./GuildMember');
const { ChannelTypes } = require('../util/Constants');
/**
* Keeps track of mentions in a {@link Message}.
*/
class MessageMentions {
constructor(message, users, roles, everyone) {
constructor(message, users, roles, everyone, crosspostedChannels) {
/**
* The client the message is from
* @type {Client}
@@ -86,6 +87,39 @@ class MessageMentions {
* @private
*/
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();
}
}
/**