feat(MessageReaction): backport removeAll and MessageReactionRemoveEmoji event (#3741)

* Add new action and websocket handler

* Add REST method for removing reaction emoji

* Update Message#_removeReaction to handle removing whole emoji

* Add MessageReaction#removeAll and update typings

* Apply uncached user fix
This commit is contained in:
Ryan Munro
2020-01-26 01:36:35 +11:00
committed by SpaceEEC
parent 6b297b8776
commit ab7f9e80b4
9 changed files with 72 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ class ActionsManager {
this.register(require('./MessageUpdate'));
this.register(require('./MessageReactionAdd'));
this.register(require('./MessageReactionRemove'));
this.register(require('./MessageReactionRemoveEmoji'));
this.register(require('./MessageReactionRemoveAll'));
this.register(require('./ChannelCreate'));
this.register(require('./ChannelDelete'));

View File

@@ -0,0 +1,27 @@
const Action = require('./Action');
const Constants = require('../../util/Constants');
class MessageReactionRemoveEmoji extends Action {
handle(data) {
// Verify channel
const channel = this.client.channels.get(data.channel_id);
if (!channel || channel.type === 'voice') return false;
// Verify message
const message = channel.messages.get(data.message_id);
if (!message) return false;
if (!data.emoji) return false;
// Verify reaction
const reaction = message._removeReaction(data.emoji);
if (reaction) this.client.emit(Constants.Events.MESSAGE_REACTION_REMOVE_EMOJI, reaction);
return { message, reaction };
}
}
/**
* Emitted whenever a reaction emoji is removed from a cached message.
* @event Client#messageReactionRemoveEmoji
* @param {MessageReaction} messageReaction The reaction object
*/
module.exports = MessageReactionRemoveEmoji;

View File

@@ -945,6 +945,17 @@ class RESTMethods {
);
}
removeMessageReactionEmoji(message, emoji) {
const endpoint = Endpoints.Message(message).Reaction(emoji);
return this.rest.makeRequest('delete', endpoint, true).then(() =>
this.client.actions.MessageReactionRemoveEmoji.handle({
message_id: message.id,
emoji: Util.parseEmoji(emoji),
channel_id: message.channel.id,
}).reaction
);
}
removeMessageReactions(message) {
return this.rest.makeRequest('delete', Endpoints.Message(message).reactions, true)
.then(() => message);

View File

@@ -55,6 +55,7 @@ class WebSocketPacketManager {
this.register(Constants.WSEvents.RELATIONSHIP_REMOVE, require('./handlers/RelationshipRemove'));
this.register(Constants.WSEvents.MESSAGE_REACTION_ADD, require('./handlers/MessageReactionAdd'));
this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE, require('./handlers/MessageReactionRemove'));
this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE, require('./handlers/MessageReactionRemoveEmoji'));
this.register(Constants.WSEvents.MESSAGE_REACTION_REMOVE_ALL, require('./handlers/MessageReactionRemoveAll'));
this.register(Constants.WSEvents.WEBHOOKS_UPDATE, require('./handlers/WebhooksUpdate'));
}

View File

@@ -0,0 +1,11 @@
const AbstractHandler = require('./AbstractHandler');
class MessageReactionRemoveEmoji extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const data = packet.d;
client.actions.MessageReactionRemoveEmoji.handle(data);
}
}
module.exports = MessageReactionRemoveEmoji;

View File

@@ -590,6 +590,10 @@ class Message {
const emojiID = emoji.id ? `${emoji.name}:${emoji.id}` : emoji.name;
if (this.reactions.has(emojiID)) {
const reaction = this.reactions.get(emojiID);
if (!user) {
this.reactions.delete(emojiID);
return reaction;
}
if (reaction.users.has(user.id)) {
reaction.users.delete(user.id);
reaction.count--;

View File

@@ -69,6 +69,17 @@ class MessageReaction {
);
}
/**
* Removes this reaction from the message
* @returns {Promise<MessageReaction>}
*/
removeAll() {
const message = this.message;
return message.client.rest.methods.removeMessageReactionEmoji(
message, this.emoji.identifier
);
}
/**
* Fetch all the users that gave this reaction. Resolves with a collection of users, mapped by their IDs.
* @param {number} [limit=100] The maximum amount of users to fetch, defaults to 100

View File

@@ -349,6 +349,7 @@ exports.Events = {
MESSAGE_BULK_DELETE: 'messageDeleteBulk',
MESSAGE_REACTION_ADD: 'messageReactionAdd',
MESSAGE_REACTION_REMOVE: 'messageReactionRemove',
MESSAGE_REACTION_REMOVE_EMOJI: 'messageReactionRemoveEmoji',
MESSAGE_REACTION_REMOVE_ALL: 'messageReactionRemoveAll',
USER_UPDATE: 'userUpdate',
USER_NOTE_UPDATE: 'userNoteUpdate',
@@ -418,6 +419,7 @@ exports.ActivityFlags = {
* * MESSAGE_DELETE_BULK
* * MESSAGE_REACTION_ADD
* * MESSAGE_REACTION_REMOVE
* * MESSAGE_REACTION_REMOVE_EMOJI
* * MESSAGE_REACTION_REMOVE_ALL
* * USER_UPDATE
* * USER_NOTE_UPDATE
@@ -461,6 +463,7 @@ exports.WSEvents = {
MESSAGE_DELETE_BULK: 'MESSAGE_DELETE_BULK',
MESSAGE_REACTION_ADD: 'MESSAGE_REACTION_ADD',
MESSAGE_REACTION_REMOVE: 'MESSAGE_REACTION_REMOVE',
MESSAGE_REACTION_RMEOVE_EMOJI: 'MESSAGE_REACTION_REMOVE_EMOJI',
MESSAGE_REACTION_REMOVE_ALL: 'MESSAGE_REACTION_REMOVE_ALL',
USER_UPDATE: 'USER_UPDATE',
USER_NOTE_UPDATE: 'USER_NOTE_UPDATE',

3
typings/index.d.ts vendored
View File

@@ -138,6 +138,7 @@ declare module 'discord.js' {
public on(event: 'messageDeleteBulk', listener: (messages: Collection<Snowflake, Message>) => void): this;
public on(event: 'messageReactionAdd', listener: (messageReaction: MessageReaction, user: User) => void): this;
public on(event: 'messageReactionRemove', listener: (messageReaction: MessageReaction, user: User) => void): this;
public on(event: 'messageReactionRemoveEmoji', listener: (messageReaction: MessageReaction) => void): this;
public on(event: 'messageReactionRemoveAll', listener: (message: Message) => void): this;
public on(event: 'messageUpdate', listener: (oldMessage: Message, newMessage: Message) => void): this;
public on(event: 'presenceUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this;
@@ -187,6 +188,7 @@ declare module 'discord.js' {
public once(event: 'messageDeleteBulk', listener: (messages: Collection<Snowflake, Message>) => void): this;
public once(event: 'messageReactionAdd', listener: (messageReaction: MessageReaction, user: User) => void): this;
public once(event: 'messageReactionRemove', listener: (messageReaction: MessageReaction, user: User) => void): this;
public once(event: 'messageReactionRemoveEmoji', listener: (messageReaction: MessageReaction) => void): this;
public once(event: 'messageReactionRemoveAll', listener: (message: Message) => void): this;
public once(event: 'messageUpdate', listener: (oldMessage: Message, newMessage: Message) => void): this;
public once(event: 'presenceUpdate', listener: (oldMember: GuildMember, newMember: GuildMember) => void): this;
@@ -919,6 +921,7 @@ declare module 'discord.js' {
public users: Collection<string, User>;
public fetchUsers(limit?: number, options?: { after?: number; before?: number }): Promise<Collection<Snowflake, User>>;
public remove(user?: UserResolvable): Promise<MessageReaction>;
public removeAll(): Promise<MessageReaction>;
}
export class NewsChannel extends TextChannel {