From 9e6d2c10474928673a71251527a0b1b7d65a547f Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Thu, 24 Dec 2020 09:37:57 +0900 Subject: [PATCH 1/5] Add reactions --- src/structures/message.ts | 9 ++++++++ src/structures/textChannel.ts | 40 ++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/structures/message.ts b/src/structures/message.ts index d8e6325..7e32b18 100644 --- a/src/structures/message.ts +++ b/src/structures/message.ts @@ -17,6 +17,7 @@ import { TextChannel } from './textChannel.ts' import { Guild } from './guild.ts' import { MessageReactionsManager } from '../managers/messageReactions.ts' import { MessageSticker } from './messageSticker.ts' +import { Emoji } from './emoji.ts' type AllMessageOptions = MessageOption | Embed @@ -129,4 +130,12 @@ export class Message extends Base { async delete(): Promise { return this.client.rest.delete(CHANNEL_MESSAGE(this.channelID, this.id)) } + + async addReaction(emoji: string | Emoji): Promise { + return this.channel.addReaction(this, emoji) + } + + async removeReaction(emoji: string | Emoji): Promise { + return this.channel.removeReaction(this, emoji) + } } diff --git a/src/structures/textChannel.ts b/src/structures/textChannel.ts index 699b4ad..a95bc6f 100644 --- a/src/structures/textChannel.ts +++ b/src/structures/textChannel.ts @@ -12,10 +12,12 @@ import { import { CHANNEL, CHANNEL_MESSAGE, - CHANNEL_MESSAGES + CHANNEL_MESSAGES, + MESSAGE_REACTION_ME } from '../types/endpoint.ts' import { Channel } from './channel.ts' import { Embed } from './embed.ts' +import { Emoji } from './emoji.ts' import { Guild } from './guild.ts' import { Message } from './message.ts' @@ -124,6 +126,42 @@ export class TextChannel extends Channel { await res.mentions.fromPayload(newMsg) return res } + + async addReaction( + message: Message | string, + emoji: Emoji | string + ): Promise { + if (emoji instanceof Emoji) { + emoji = emoji.getEmojiString + } + if (message instanceof Message) { + message = message.id + } + + const encodedEmoji = encodeURI(emoji) + + await this.client.rest.put( + MESSAGE_REACTION_ME(this.id, message, encodedEmoji) + ) + } + + async removeReaction( + message: Message | string, + emoji: Emoji | string + ): Promise { + if (emoji instanceof Emoji) { + emoji = emoji.getEmojiString + } + if (message instanceof Message) { + message = message.id + } + + const encodedEmoji = encodeURI(emoji) + + await this.client.rest.delete( + MESSAGE_REACTION_ME(this.id, message, encodedEmoji) + ) + } } export class GuildTextChannel extends TextChannel { From 315fd0d0dac95b47f6074cd8c46892935a79b7e2 Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Thu, 24 Dec 2020 09:59:01 +0900 Subject: [PATCH 2/5] Make a test command --- src/test/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/index.ts b/src/test/index.ts index f42d145..c0d14c3 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -112,6 +112,17 @@ client.on('messageCreate', async (msg: Message) => { } else { msg.channel.send('Failed...') } + } else if (msg.content === '!react') { + msg.addReaction('🤔') + } +}) + +client.on('messageReactionRemove', (reaction, user) => { + const msg = reaction.message + + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + if (reaction.me && reaction.emoji.getEmojiString === '🤔') { + msg.removeReaction(reaction.emoji) } }) From eac5d52d83d37c7017c9bf0c94f8dd5313767f98 Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Thu, 24 Dec 2020 09:59:32 +0900 Subject: [PATCH 3/5] Handle null-id emojis --- src/gateway/handlers/guildEmojiUpdate.ts | 22 ++++++++++++------- src/gateway/handlers/messageReactionAdd.ts | 7 +++--- src/gateway/handlers/messageReactionRemove.ts | 3 ++- .../handlers/messageReactionRemoveEmoji.ts | 3 ++- src/managers/guildEmojis.ts | 3 ++- src/managers/messageReactions.ts | 7 ++++-- src/structures/emoji.ts | 12 ++++++---- src/types/emoji.ts | 2 +- 8 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/gateway/handlers/guildEmojiUpdate.ts b/src/gateway/handlers/guildEmojiUpdate.ts index 5af394f..db5e254 100644 --- a/src/gateway/handlers/guildEmojiUpdate.ts +++ b/src/gateway/handlers/guildEmojiUpdate.ts @@ -17,23 +17,29 @@ export const guildEmojiUpdate: GatewayEventHandler = async ( const _updated: EmojiPayload[] = [] for (const raw of d.emojis) { - const has = emojis.get(raw.id) + const emojiID = raw.id !== null ? raw.id : raw.name + const has = emojis.get(emojiID) if (has === undefined) { - await guild.emojis.set(raw.id, raw) - const emoji = (await guild.emojis.get(raw.id)) as Emoji + await guild.emojis.set(emojiID, raw) + const emoji = (await guild.emojis.get(emojiID)) as Emoji added.push(emoji) } else _updated.push(raw) } for (const emoji of emojis.values()) { - const find = _updated.find((e) => emoji.id === e.id) + const emojiID = emoji.id !== null ? emoji.id : emoji.name + const find = _updated.find((e) => { + const eID = e.id !== null ? e.id : e.name + return emojiID === eID + }) if (find === undefined) { - await guild.emojis.delete(emoji.id) + await guild.emojis.delete(emojiID) deleted.push(emoji) } else { - const before = (await guild.emojis.get(find.id)) as Emoji - await guild.emojis.set(find.id, find) - const after = (await guild.emojis.get(find.id)) as Emoji + const foundID = find.id !== null ? find.id : find.name + const before = (await guild.emojis.get(foundID)) as Emoji + await guild.emojis.set(foundID, find) + const after = (await guild.emojis.get(foundID)) as Emoji updated.push({ before, after }) } } diff --git a/src/gateway/handlers/messageReactionAdd.ts b/src/gateway/handlers/messageReactionAdd.ts index 17dbaf7..5b05ddd 100644 --- a/src/gateway/handlers/messageReactionAdd.ts +++ b/src/gateway/handlers/messageReactionAdd.ts @@ -29,15 +29,16 @@ export const messageReactionAdd: GatewayEventHandler = async ( } else return } - let reaction = await message.reactions.get(d.emoji.id) + const emojiID = d.emoji.id !== null ? d.emoji.id : d.emoji.name + let reaction = await message.reactions.get(emojiID) if (reaction === undefined) { - await message.reactions.set(d.emoji.id, { + await message.reactions.set(emojiID, { count: 1, emoji: d.emoji, me: d.user_id === gateway.client.user?.id }) reaction = ((await message.reactions.get( - d.emoji.id + emojiID )) as unknown) as MessageReaction } diff --git a/src/gateway/handlers/messageReactionRemove.ts b/src/gateway/handlers/messageReactionRemove.ts index 56748da..9cf50fa 100644 --- a/src/gateway/handlers/messageReactionRemove.ts +++ b/src/gateway/handlers/messageReactionRemove.ts @@ -27,7 +27,8 @@ export const messageReactionRemove: GatewayEventHandler = async ( } else return } - const reaction = await message.reactions.get(d.emoji.id) + const emojiID = d.emoji.id !== null ? d.emoji.id : d.emoji.name + const reaction = await message.reactions.get(emojiID) if (reaction === undefined) return reaction.users.delete(d.user_id) diff --git a/src/gateway/handlers/messageReactionRemoveEmoji.ts b/src/gateway/handlers/messageReactionRemoveEmoji.ts index e62c172..0d1cd05 100644 --- a/src/gateway/handlers/messageReactionRemoveEmoji.ts +++ b/src/gateway/handlers/messageReactionRemoveEmoji.ts @@ -19,7 +19,8 @@ export const messageReactionRemoveEmoji: GatewayEventHandler = async ( } else return } - const reaction = await message.reactions.get(d.emoji.id) + const emojiID = d.emoji.id !== null ? d.emoji.id : d.emoji.name + const reaction = await message.reactions.get(emojiID) if (reaction === undefined) return await reaction.users.flush() diff --git a/src/managers/guildEmojis.ts b/src/managers/guildEmojis.ts index 30c1d49..2a3aeb2 100644 --- a/src/managers/guildEmojis.ts +++ b/src/managers/guildEmojis.ts @@ -87,7 +87,8 @@ export class GuildEmojisManager extends BaseChildManager { async flush(): Promise { const arr = await this.array() for (const elem of arr) { - this.parent.delete(elem.id) + const emojiID = elem.id !== null ? elem.id : elem.name + this.parent.delete(emojiID) } return true } diff --git a/src/managers/messageReactions.ts b/src/managers/messageReactions.ts index 43d039c..7c43ae6 100644 --- a/src/managers/messageReactions.ts +++ b/src/managers/messageReactions.ts @@ -21,7 +21,9 @@ export class MessageReactionsManager extends BaseManager< const raw = await this._get(id) if (raw === undefined) return - let emoji = await this.client.emojis.get(raw.emoji.id) + const emojiID = raw.emoji.id !== null ? raw.emoji.id : raw.emoji.name + + let emoji = await this.client.emojis.get(emojiID) if (emoji === undefined) emoji = new Emoji(this.client, raw.emoji) const reaction = new MessageReaction(this.client, raw, this.message, emoji) @@ -43,7 +45,8 @@ export class MessageReactionsManager extends BaseManager< return await Promise.all( arr.map(async (raw) => { - let emoji = await this.client.emojis.get(raw.emoji.id) + const emojiID = raw.emoji.id !== null ? raw.emoji.id : raw.emoji.name + let emoji = await this.client.emojis.get(emojiID) if (emoji === undefined) emoji = new Emoji(this.client, raw.emoji) return new MessageReaction(this.client, raw, this.message, emoji) diff --git a/src/structures/emoji.ts b/src/structures/emoji.ts index 0fbc8fe..0aa47f6 100644 --- a/src/structures/emoji.ts +++ b/src/structures/emoji.ts @@ -5,7 +5,7 @@ import { Guild } from './guild.ts' import { User } from './user.ts' export class Emoji extends Base { - id: string + id: string | null name: string roles?: string[] user?: User @@ -16,9 +16,13 @@ export class Emoji extends Base { available?: boolean get getEmojiString(): string { - if (this.animated === false) { - return `<:${this.name}:${this.id}>` - } else return `` + if (this.id === null) { + return this.name + } else { + if (this.animated === false) { + return `<:${this.name}:${this.id}>` + } else return `` + } } toString(): string { diff --git a/src/types/emoji.ts b/src/types/emoji.ts index ab0216c..65d6f39 100644 --- a/src/types/emoji.ts +++ b/src/types/emoji.ts @@ -1,7 +1,7 @@ import { UserPayload } from './user.ts' export interface EmojiPayload { - id: string + id: string | null name: string roles?: string[] user?: UserPayload From 540f3b1877d83258573763afa8b5078f27d5a23e Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Fri, 25 Dec 2020 13:44:42 +0900 Subject: [PATCH 4/5] Support removing other user's reactions --- src/structures/message.ts | 7 +++++-- src/structures/textChannel.ts | 25 ++++++++++++++++++++----- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/structures/message.ts b/src/structures/message.ts index 7e32b18..25671bd 100644 --- a/src/structures/message.ts +++ b/src/structures/message.ts @@ -135,7 +135,10 @@ export class Message extends Base { return this.channel.addReaction(this, emoji) } - async removeReaction(emoji: string | Emoji): Promise { - return this.channel.removeReaction(this, emoji) + async removeReaction( + emoji: string | Emoji, + user?: User | Member | string + ): Promise { + return this.channel.removeReaction(this, emoji, user) } } diff --git a/src/structures/textChannel.ts b/src/structures/textChannel.ts index a95bc6f..15decb2 100644 --- a/src/structures/textChannel.ts +++ b/src/structures/textChannel.ts @@ -13,13 +13,16 @@ import { CHANNEL, CHANNEL_MESSAGE, CHANNEL_MESSAGES, - MESSAGE_REACTION_ME + MESSAGE_REACTION_ME, + MESSAGE_REACTION_USER } from '../types/endpoint.ts' import { Channel } from './channel.ts' import { Embed } from './embed.ts' import { Emoji } from './emoji.ts' import { Guild } from './guild.ts' +import { Member } from './member.ts' import { Message } from './message.ts' +import { User } from './user.ts' export type AllMessageOptions = MessageOption | Embed @@ -147,7 +150,8 @@ export class TextChannel extends Channel { async removeReaction( message: Message | string, - emoji: Emoji | string + emoji: Emoji | string, + user?: User | Member | string ): Promise { if (emoji instanceof Emoji) { emoji = emoji.getEmojiString @@ -155,12 +159,23 @@ export class TextChannel extends Channel { if (message instanceof Message) { message = message.id } + if (user !== undefined) { + if (typeof user !== 'string') { + user = user.id + } + } const encodedEmoji = encodeURI(emoji) - await this.client.rest.delete( - MESSAGE_REACTION_ME(this.id, message, encodedEmoji) - ) + if (user === undefined) { + await this.client.rest.delete( + MESSAGE_REACTION_ME(this.id, message, encodedEmoji) + ) + } else { + await this.client.rest.delete( + MESSAGE_REACTION_USER(this.id, message, encodedEmoji, user) + ) + } } } From 4129ea699bd7a381ff8f803860e2fc108f4530ef Mon Sep 17 00:00:00 2001 From: Helloyunho Date: Sat, 26 Dec 2020 12:07:15 +0900 Subject: [PATCH 5/5] Fix mistake --- src/structures/textChannel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/structures/textChannel.ts b/src/structures/textChannel.ts index 0e7e734..398f2af 100644 --- a/src/structures/textChannel.ts +++ b/src/structures/textChannel.ts @@ -179,6 +179,7 @@ export class TextChannel extends Channel { MESSAGE_REACTION_USER(this.id, message, encodedEmoji, user) ) } + } /** * Fetch Messages of a Channel