Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(MessageManager): extend API coverage #4869

Merged
merged 32 commits into from May 10, 2021
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
dfb2a20
feat(MessageManager): move Message#edit API calls to Manager
monbrey Sep 14, 2020
e9855f4
fix(MessageEditOptions): update method reference
monbrey Sep 14, 2020
909b7d7
feat(MessageManager): move Message#crosspost API calls to Manager
monbrey Sep 14, 2020
0afb292
feat(MessageManager): move Message#pin API calls to Manager
monbrey Sep 15, 2020
ffb94ca
feat(MessageManager): move Message#unpin API calls to Manager
monbrey Sep 15, 2020
dcd5246
feat(MessageManager): move Message#react API calls to Manager
monbrey Sep 16, 2020
ae2ffab
fix(MessageManager): throw TypeError on non-MessageResolvable params
monbrey Sep 16, 2020
85646ca
chore: typings
monbrey Sep 30, 2020
c1e831c
Merge remote-tracking branch 'upstream/master' into message-manager-a…
monbrey Sep 30, 2020
1e84854
fix(MessageManager): consistent API call notation
monbrey Sep 30, 2020
96570d9
chore: linting
monbrey Sep 30, 2020
fbf5f3c
fix: apply suggestions from code review
monbrey Oct 5, 2020
d712d29
fix: rename shadowed variable
monbrey Oct 5, 2020
4e49e04
feat: typings for APIRawMessage overloads
monbrey Oct 16, 2020
bb22ae1
fix(MessageManager): return Message instance from MessageManager#edit
monbrey Dec 15, 2020
78ce3b1
feat(MessageManager): return Message from MessageManager#crosspost
monbrey Dec 15, 2020
609b0e0
fix(Message): return result of Manager call directly on crosspost
monbrey Dec 15, 2020
149af15
fix(Typings): edit and crosspost no longer return raw api messages
monbrey Dec 15, 2020
f2f2182
Merge branch 'master' into message-manager-additions
monbrey Dec 28, 2020
77d3019
fix: linting
monbrey Dec 28, 2020
8436588
fix: tslint
monbrey Dec 28, 2020
64b77d7
feat: return Message from MessageManager#edit
monbrey Feb 4, 2021
7bf12fb
fix: suggestions
monbrey Feb 4, 2021
6793fe5
fix: remove unused interface
monbrey Feb 14, 2021
0d49034
fix(Typings): convert MessageManager#edit to overloads
monbrey Apr 30, 2021
667895d
fix(Message): use async/await
monbrey Apr 30, 2021
7f41309
Merge branch 'master' into message-manager-additions
monbrey Apr 30, 2021
85b8fa6
fix: drop unsupported options.reason
monbrey May 2, 2021
09af53f
Merge branch 'message-manager-additions' of https://github.com/monbre…
monbrey May 2, 2021
c7cfd6e
fix(Message): remove unsupport options.reason from pin/unpin
monbrey May 2, 2021
6fc2592
fix: typings
monbrey May 2, 2021
3946c8b
chore: change MessageManager#edit to accept a single options object
monbrey May 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/managers/MessageManager.js
Expand Up @@ -2,6 +2,7 @@

const BaseManager = require('./BaseManager');
const { TypeError } = require('../errors');
const APIMessage = require('../structures/APIMessage');
const Message = require('../structures/Message');
const Collection = require('../util/Collection');
const LimitedCollection = require('../util/LimitedCollection');
Expand Down Expand Up @@ -113,6 +114,87 @@ class MessageManager extends BaseManager {
* @returns {?Snowflake}
*/

/**
* Edits a message, even if it's not cached.
* @param {MessageResolvable} message The message to edit
* @param {StringResolvable|APIMessage} [content] The new content for the message
* @param {MessageEditOptions|MessageEmbed} [options] The options to provide
* @returns {Promise<Message>}
*/
async edit(message, content, options) {
monbrey marked this conversation as resolved.
Show resolved Hide resolved
message = this.resolveID(message);
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');

const { data } =
content instanceof APIMessage ? content.resolveData() : APIMessage.create(this, content, options).resolveData();
const d = await this.client.api.channels[this.channel.id].messages[message].patch({ data });

if (this.cache.has(message)) {
const clone = this.cache.get(message)._clone();
clone._patch(d);
return clone;
}
return this.add(d);
}

/**
* Publishes a message in an announcement channel to all channels following it, even if it's not cached.
* @param {MessageResolvable} message The message to publish
* @returns {Promise<Message>}
*/
async crosspost(message) {
message = this.resolveID(message);
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');

const data = await this.client.api.channels(this.channel.id).messages(message).crosspost.post();
return this.cache.get(data.id) || this.add(data);
}

/**
* Pins a message to the channel's pinned messages, even if it's not cached.
* @param {MessageResolvable} message The message to pin
* @param {Object} [options] Options for pinning
* @param {string} [options.reason] Reason for pinning
* @returns {Promise<void>}
*/
async pin(message, options) {
message = this.resolveID(message);
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');

await this.client.api.channels(this.channel.id).pins(message).put(options);
monbrey marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Unins a message from the channel's pinned messages, even if it's not cached.
* @param {MessageResolvable} message The message to unpin
* @param {Object} [options] Options for unpinning
* @param {string} [options.reason] Reason for unpinning
* @returns {Promise<void>}
*/
async unpin(message, options) {
message = this.resolveID(message);
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');

await this.client.api.channels(this.channel.id).pins(message).delete(options);
monbrey marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Adds a reaction to a message, even if it's not cached.
* @param {MessageResolvable} message The messag to react to
* @param {EmojiIdentifierResolvable} emoji The emoji to react with
* @returns {Promise<void>}
*/
async react(message, emoji) {
message = this.resolveID(message);
if (!message) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');

emoji = this.client.emojis.resolveIdentifier(emoji);
if (!emoji) throw new TypeError('EMOJI_TYPE', 'emoji', 'EmojiIdentifierResolvable');

// eslint-disable-next-line newline-per-chained-call
kyranet marked this conversation as resolved.
Show resolved Hide resolved
await this.client.api.channels(this.channel.id).messages(message).reactions(emoji, '@me').put();
}

/**
* Deletes a message, even if it's not cached.
* @param {MessageResolvable} message The message to delete
Expand Down
55 changes: 15 additions & 40 deletions src/structures/Message.js
Expand Up @@ -8,7 +8,7 @@ const Embed = require('./MessageEmbed');
const Mentions = require('./MessageMentions');
const ReactionCollector = require('./ReactionCollector');
const Sticker = require('./Sticker');
const { Error, TypeError } = require('../errors');
const { Error } = require('../errors');
const ReactionManager = require('../managers/ReactionManager');
const Collection = require('../util/Collection');
const { MessageTypes, SystemMessageTypes } = require('../util/Constants');
Expand Down Expand Up @@ -447,7 +447,7 @@ class Message extends Base {
}

/**
* Options that can be passed into editMessage.
* Options that can be passed into {@link Message#edit}.
* @typedef {Object} MessageEditOptions
* @property {string} [content] Content to be edited
* @property {MessageEmbed|Object} [embed] An embed to be added/edited
Expand All @@ -468,13 +468,7 @@ class Message extends Base {
* .catch(console.error);
*/
edit(content, options) {
const { data } =
content instanceof APIMessage ? content.resolveData() : APIMessage.create(this, content, options).resolveData();
return this.client.api.channels[this.channel.id].messages[this.id].patch({ data }).then(d => {
const clone = this._clone();
clone._patch(d);
return clone;
});
return this.channel.messages.edit(this.id, content, options);
}

/**
Expand All @@ -488,9 +482,8 @@ class Message extends Base {
* .catch(console.error);
* }
*/
async crosspost() {
await this.client.api.channels(this.channel.id).messages(this.id).crosspost.post();
return this;
crosspost() {
return this.channel.messages.crosspost(this.id);
}

/**
Expand All @@ -505,11 +498,7 @@ class Message extends Base {
* .catch(console.error)
*/
pin(options) {
return this.client.api
.channels(this.channel.id)
.pins(this.id)
.put(options)
.then(() => this);
return this.channel.messages.pin(this.id, options).then(() => this);
}

/**
Expand All @@ -524,11 +513,7 @@ class Message extends Base {
* .catch(console.error)
*/
unpin(options) {
return this.client.api
.channels(this.channel.id)
.pins(this.id)
.delete(options)
.then(() => this);
return this.channel.messages.unpin(this.id, options).then(() => this);
}

/**
Expand All @@ -546,24 +531,14 @@ class Message extends Base {
* .then(console.log)
* .catch(console.error);
*/
react(emoji) {
emoji = this.client.emojis.resolveIdentifier(emoji);
if (!emoji) throw new TypeError('EMOJI_TYPE');

return this.client.api
.channels(this.channel.id)
.messages(this.id)
.reactions(emoji, '@me')
.put()
.then(
() =>
this.client.actions.MessageReactionAdd.handle({
user: this.client.user,
channel: this.channel,
message: this,
emoji: Util.parseEmoji(emoji),
}).reaction,
);
async react(emoji) {
await this.channel.messages.react(this.id, emoji);
return this.client.actions.MessageReactionAdd.handle({
user: this.client.user,
channel: this.channel,
message: this,
emoji: Util.parseEmoji(emoji),
}).reaction;
}

/**
Expand Down
15 changes: 14 additions & 1 deletion typings/index.d.ts
Expand Up @@ -2061,14 +2061,27 @@ declare module 'discord.js' {
constructor(channel: TextChannel | DMChannel, iterable?: Iterable<any>);
public channel: TextBasedChannelFields;
public cache: Collection<Snowflake, Message>;
public crosspost(message: MessageResolvable): Promise<Message>;
public delete(message: MessageResolvable): Promise<void>;
public edit(
message: MessageResolvable,
content: APIMessageContentResolvable | MessageEditOptions | MessageEmbed | APIMessage,
): Promise<Message>;
public edit(
message: MessageResolvable,
content: StringResolvable,
options: MessageEditOptions | MessageEmbed,
): Promise<Message>;
public fetch(message: Snowflake, cache?: boolean, force?: boolean): Promise<Message>;
public fetch(
options?: ChannelLogsQueryOptions,
cache?: boolean,
force?: boolean,
): Promise<Collection<Snowflake, Message>>;
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message>>;
public delete(message: MessageResolvable): Promise<void>;
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
public pin(message: MessageResolvable, options?: { reason?: string }): Promise<void>;
public unpin(message: MessageResolvable, options?: { reason?: string }): Promise<void>;
}

export class PresenceManager extends BaseManager<Snowflake, Presence, PresenceResolvable> {
Expand Down