"use strict";
const Collection = require("../util/Collection");
const GuildChannel = require("./GuildChannel");
const Message = require("./Message");
/**
* Represents a textable guild channel. You also probably want to look at NewsChannel, StageChannel, TextChannel, ThreadChannel, and VoiceChannel. See GuildChannel for more properties
* @prop {String?} lastMessageID The ID of the last message in the channel. This can be null if there has never been a message in the channel
* @prop {Collection<Message>} messages Collection of Messages in this channel
* @prop {Number} rateLimitPerUser The time in seconds a user has to wait before sending another message (0-21600) (does not affect bots or users with manageMessages/manageChannel permissions)
*/
class GuildTextableChannel extends GuildChannel {
constructor(data, client, messageLimit) {
super(data, client);
this.messages = new Collection(Message, messageLimit == null ? client.options.messageLimit : messageLimit);
this.lastMessageID = data.last_message_id || null;
this.update(data);
}
update(data) {
super.update(data);
if (data.rate_limit_per_user !== undefined) {
this.rateLimitPerUser = data.rate_limit_per_user;
}
}
/**
* Add a reaction to a message
* @arg {String} messageID The ID of the message
* @arg {String} reaction The reaction (Unicode string if Unicode emoji, `emojiName:emojiID` if custom emoji)
* @returns {Promise}
*/
addMessageReaction(messageID, reaction) {
return this._client.addMessageReaction.call(this._client, this.id, messageID, reaction);
}
/**
* Create a message in the channel
* @arg {String | Object} content A string or object. If an object is passed:
* @arg {Object} [content.allowedMentions] A list of mentions to allow (overrides default)
* @arg {Boolean} [content.allowedMentions.everyone] Whether or not to allow @everyone/@here
* @arg {Boolean} [content.allowedMentions.repliedUser] Whether or not to mention the author of the message being replied to
* @arg {Boolean | Array<String>} [content.allowedMentions.roles] Whether or not to allow all role mentions, or an array of specific role mentions to allow
* @arg {Boolean | Array<String>} [content.allowedMentions.users] Whether or not to allow all user mentions, or an array of specific user mentions to allow
* @arg {Array<Object>} [content.attachments] An array of attachment objects with the filename and description
* @arg {String} [content.attachments[].description] The description of the file
* @arg {String} [content.attachments[].filename] The name of the file
* @arg {Number} content.attachments[].id The index of the file
* @arg {Array<Object>} [content.components] An array of [component objects](https://discord.dev/interactions/message-components#component-object)
* @arg {String} [content.content] A content string
* @arg {Object} [content.embed] [DEPRECATED] An embed object. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/channel#embed-object) for object structure
* @arg {Array<Object>} [content.embeds] An array of embed objects. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/channel#embed-object) for object structure
* @arg {Boolean} [content.enforceNonce] If true and `content.nonce` is present, if multiple messages are sent with the same nonce within a few minutes of each other, that message will be returned and no new message created
* @arg {Number} [content.flags] A number representing the [flags](https://discord.dev/resources/channel#message-object-message-flags) to apply to the message (only SUPPRESS_EMBEDS and SUPPRESS_NOTIFICATIONS)
* @arg {Object} [content.messageReference] The message reference, used when replying to or forwarding messages
* @arg {String} [content.messageReference.channelID] The channel ID of the referenced message. Required when forwarding messages
* @arg {Boolean} [content.messageReference.failIfNotExists=true] Whether to throw an error if the message reference doesn't exist. If false, and the referenced message doesn't exist, the message is created without a referenced message
* @arg {String} [content.messageReference.guildID] The guild ID of the referenced message
* @arg {String} content.messageReference.messageID The message ID of the referenced message. This cannot reference a system message
* @arg {String} [content.messageReference.type=0] The type of reference. Either `0` (REPLY) or `1` (FORWARDED). Will become required in the future
* @arg {String} [content.messageReferenceID] [DEPRECATED] The ID of the message should be replied to. Use `messageReference` instead
* @arg {Object} [content.poll] A poll object. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/poll#poll-object) for object structure
* @arg {String | Number} [content.nonce] A nonce value which will also appear in the messageCreate event
* @arg {Array<String>} [content.stickerIDs] An array of IDs corresponding to stickers to send
* @arg {Boolean} [content.tts] Set the message TTS flag
* @arg {Object | Array<Object>} [file] A file object (or an Array of them)
* @arg {Buffer} file.file A buffer containing file data
* @arg {String} file.name What to name the file
* @returns {Promise<Message>}
*/
createMessage(content, file) {
return this._client.createMessage.call(this._client, this.id, content, file);
}
/**
* Delete a message
* @arg {String} messageID The ID of the message
* @arg {String} [reason] The reason to be displayed in audit logs
* @returns {Promise}
*/
deleteMessage(messageID, reason) {
return this._client.deleteMessage.call(this._client, this.id, messageID, reason);
}
/**
* Bulk delete messages (bot accounts only)
* @arg {Array<String>} messageIDs Array of message IDs to delete
* @arg {String} [reason] The reason to be displayed in audit logs
* @returns {Promise}
*/
deleteMessages(messageIDs, reason) {
return this._client.deleteMessages.call(this._client, this.id, messageIDs, reason);
}
/**
* Edit a message
* @arg {String} messageID The ID of the message
* @arg {String | Array | Object} content A string, array of strings, or object. If an object is passed:
* @arg {Object} [content.allowedMentions] A list of mentions to allow (overrides default)
* @arg {Boolean} [content.allowedMentions.everyone] Whether or not to allow @everyone/@here
* @arg {Boolean | Array<String>} [content.allowedMentions.roles] Whether or not to allow all role mentions, or an array of specific role mentions to allow
* @arg {Boolean | Array<String>} [content.allowedMentions.users] Whether or not to allow all user mentions, or an array of specific user mentions to allow
* @arg {Array<Object>} [content.attachments] An array of attachment objects that will be appended to the message, including new files. Only the provided files will be appended
* @arg {String} [content.attachments[].description] The description of the file
* @arg {String} [content.attachments[].filename] The name of the file. This is not required if you are attaching a new file
* @arg {Number | String} content.attachments[].id The ID of the file. If you are attaching a new file, this would be the index of the file
* @arg {Array<Object>} [content.components] An array of [component objects](https://discord.dev/interactions/message-components#component-object)
* @arg {String} [content.content] A content string
* @arg {Object} [content.embed] [DEPRECATED] An embed object. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/channel#embed-object) for object structure
* @arg {Array<Object>} [content.embeds] An array of embed objects. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/channel#embed-object) for object structure
* @arg {Object | Array<Object>} [content.file] A file object (or an Array of them)
* @arg {Buffer} content.file[].file A buffer containing file data
* @arg {String} content.file[].name What to name the file
* @arg {Number} [content.flags] A number representing the flags to apply to the message. See [the official Discord API documentation entry](https://discord.com/developers/docs/resources/channel#message-object-message-flags) for flags reference
* @returns {Promise<Message>}
*/
editMessage(messageID, content) {
return this._client.editMessage.call(this._client, this.id, messageID, content);
}
/**
* Immediately end a poll. Note: You cannot end polls from other users.
* @arg {String} messageID The ID of the message that the poll is in
* @returns {Promise<Message>}
*/
endPoll(messageID) {
return this._client.endPoll.call(this._client, this.id, messageID);
}
/**
* Get a previous message in the channel
* @arg {String} messageID The ID of the message
* @returns {Promise<Message>}
*/
getMessage(messageID) {
return this._client.getMessage.call(this._client, this.id, messageID);
}
/**
* Get a list of users who reacted with a specific reaction
* @arg {String} messageID The ID of the message
* @arg {String} reaction The reaction (Unicode string if Unicode emoji, `emojiName:emojiID` if custom emoji)
* @arg {Object} [options] Options for the request. If this is a number, it is treated as `options.limit` ([DEPRECATED] behavior)
* @arg {String} [options.after] Get users after this user ID
* @arg {Number} [options.limit=100] The maximum number of users to get
* @arg {Number} [options.type=0] The type of reaction (`0` for normal, `1` for burst)
* @arg {String} [before] [DEPRECATED] Get users before this user ID. Discord no longer supports this parameter
* @arg {String} [after] [DEPRECATED] Get users after this user ID
* @returns {Promise<Array<User>>}
*/
getMessageReaction(messageID, reaction, options, before, after) {
return this._client.getMessageReaction.call(this._client, this.id, messageID, reaction, options, before, after);
}
/**
* Get previous messages in the channel
* @arg {Object} [options] Options for the request. If this is a number ([DEPRECATED] behavior), it is treated as `options.limit`
* @arg {String} [options.after] Get messages after this message ID
* @arg {String} [options.around] Get messages around this message ID (does not work with limit > 100)
* @arg {String} [options.before] Get messages before this message ID
* @arg {Number} [options.limit=50] The max number of messages to get
* @arg {String} [before] [DEPRECATED] Get messages before this message ID
* @arg {String} [after] [DEPRECATED] Get messages after this message ID
* @arg {String} [around] [DEPRECATED] Get messages around this message ID (does not work with limit > 100)
* @returns {Promise<Array<Message>>}
*/
getMessages(options, before, after, around) {
return this._client.getMessages.call(this._client, this.id, options, before, after, around);
}
/**
* Get a list of users that voted for a specific poll answer
* @arg {String} messageID The ID of the message that the poll is in
* @arg {Number} answerID The ID of the answer to get voters for
* @arg {Object} [options] Options for the request
* @arg {String} [options.after] Get users after this user ID
* @arg {Number} [options.limit=25] The max number of users to get
* @returns {Promise<Array<User>>} An array of users who voted for this answer
*/
getPollAnswerVoters(messageID, answerID, options) {
return this._client.getPollAnswerVoters.call(this._client, this.id, messageID, answerID, options);
}
/**
* Purge previous messages in the channel with an optional filter
* @arg {Object} options Options for the request. If this is a number ([DEPRECATED] behavior), it is treated as `options.limit`
* @arg {String} [options.after] Get messages after this message ID
* @arg {String} [options.before] Get messages before this message ID
* @arg {Function} [options.filter] Optional filter function that returns a boolean when passed a Message object
* @arg {Number} options.limit The max number of messages to search through, -1 for no limit
* @arg {String} [options.reason] The reason to be displayed in audit logs
* @arg {Function} [filter] [DEPRECATED] Optional filter function that returns a boolean when passed a Message object
* @arg {String} [before] [DEPRECATED] Get messages before this message ID
* @arg {String} [after] [DEPRECATED] Get messages after this message ID
* @arg {String} [reason] [DEPRECATED] The reason to be displayed in audit logs
* @returns {Promise<Number>} Resolves with the number of messages deleted
*/
purge(limit, filter, before, after, reason) {
return this._client.purgeChannel.call(this._client, this.id, limit, filter, before, after, reason);
}
/**
* Remove a reaction from a message
* @arg {String} messageID The ID of the message
* @arg {String} reaction The reaction (Unicode string if Unicode emoji, `emojiName:emojiID` if custom emoji)
* @arg {String} [userID="@me"] The ID of the user to remove the reaction for
* @returns {Promise}
*/
removeMessageReaction(messageID, reaction, userID) {
return this._client.removeMessageReaction.call(this._client, this.id, messageID, reaction, userID);
}
/**
* Remove all reactions from a message for a single emoji
* @arg {String} messageID The ID of the message
* @arg {String} reaction The reaction (Unicode string if Unicode emoji, `emojiName:emojiID` if custom emoji)
* @returns {Promise}
*/
removeMessageReactionEmoji(messageID, reaction) {
return this._client.removeMessageReactionEmoji.call(this._client, this.id, messageID, reaction);
}
/**
* Remove all reactions from a message
* @arg {String} messageID The ID of the message
* @returns {Promise}
*/
removeMessageReactions(messageID) {
return this._client.removeMessageReactions.call(this._client, this.id, messageID);
}
/**
* Send typing status in the channel
* @returns {Promise}
*/
sendTyping() {
return this._client.sendChannelTyping.call(this._client, this.id);
}
/**
* Un-send a message. You're welcome Programmix
* @arg {String} messageID The ID of the message
* @returns {Promise}
*/
unsendMessage(messageID) {
return this._client.deleteMessage.call(this.client, this.id, messageID);
}
toJSON(props = []) {
return super.toJSON([
"lastMessageID",
"lastPinTimestamp",
"rateLimitPerUser",
...props,
]);
}
}
module.exports = GuildTextableChannel;