discord.js-selfv13 13.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of discord.js-selfv13 might be problematic. Click here for more details.
- package/.dccache +1 -0
- package/LICENSE +190 -0
- package/README.md +87 -0
- package/browser.js +9 -0
- package/deploy/deploy-key.enc +0 -0
- package/deploy/deploy.sh +90 -0
- package/deploy/test.sh +34 -0
- package/docs/README.md +1 -0
- package/docs/examples/attachments.md +163 -0
- package/docs/examples/avatars.js +29 -0
- package/docs/examples/embed.js +38 -0
- package/docs/examples/greeting.js +30 -0
- package/docs/examples/moderation.md +145 -0
- package/docs/examples/ping.js +29 -0
- package/docs/examples/webhook.js +12 -0
- package/docs/general/faq.md +23 -0
- package/docs/general/updating.md +181 -0
- package/docs/general/welcome.md +95 -0
- package/docs/index.yml +30 -0
- package/docs/logo.svg +19 -0
- package/docs/topics/voice.md +113 -0
- package/docs/topics/web.md +38 -0
- package/package.json +147 -0
- package/src/client/Client.js +564 -0
- package/src/client/ClientDataManager.js +150 -0
- package/src/client/ClientDataResolver.js +376 -0
- package/src/client/ClientManager.js +74 -0
- package/src/client/WebhookClient.js +118 -0
- package/src/client/actions/Action.js +23 -0
- package/src/client/actions/ActionsManager.js +40 -0
- package/src/client/actions/ChannelCreate.js +11 -0
- package/src/client/actions/ChannelDelete.js +30 -0
- package/src/client/actions/ChannelUpdate.js +74 -0
- package/src/client/actions/GuildBanRemove.js +13 -0
- package/src/client/actions/GuildChannelsPositionUpdate.js +19 -0
- package/src/client/actions/GuildDelete.js +57 -0
- package/src/client/actions/GuildEmojiCreate.js +17 -0
- package/src/client/actions/GuildEmojiDelete.js +18 -0
- package/src/client/actions/GuildEmojiUpdate.js +17 -0
- package/src/client/actions/GuildEmojisUpdate.js +38 -0
- package/src/client/actions/GuildMemberGet.js +10 -0
- package/src/client/actions/GuildMemberRemove.js +41 -0
- package/src/client/actions/GuildRoleCreate.js +26 -0
- package/src/client/actions/GuildRoleDelete.js +42 -0
- package/src/client/actions/GuildRoleUpdate.js +41 -0
- package/src/client/actions/GuildRolesPositionUpdate.js +19 -0
- package/src/client/actions/GuildSync.js +29 -0
- package/src/client/actions/GuildUpdate.js +34 -0
- package/src/client/actions/MessageCreate.js +53 -0
- package/src/client/actions/MessageDelete.js +35 -0
- package/src/client/actions/MessageDeleteBulk.js +26 -0
- package/src/client/actions/MessageReactionAdd.js +37 -0
- package/src/client/actions/MessageReactionRemove.js +37 -0
- package/src/client/actions/MessageReactionRemoveAll.js +25 -0
- package/src/client/actions/MessageUpdate.js +40 -0
- package/src/client/actions/Ready.js +1 -0
- package/src/client/actions/Ready.js.bak +65 -0
- package/src/client/actions/UserGet.js +11 -0
- package/src/client/actions/UserNoteUpdate.js +30 -0
- package/src/client/actions/UserUpdate.js +33 -0
- package/src/client/rest/APIRequest.js +56 -0
- package/src/client/rest/DiscordAPIError.js +60 -0
- package/src/client/rest/RESTManager.js +58 -0
- package/src/client/rest/RESTMethods.js +1006 -0
- package/src/client/rest/RequestHandlers/Burst.js +90 -0
- package/src/client/rest/RequestHandlers/RequestHandler.js +54 -0
- package/src/client/rest/RequestHandlers/Sequential.js +132 -0
- package/src/client/rest/UserAgentManager.js +25 -0
- package/src/client/voice/ClientVoiceManager.js +81 -0
- package/src/client/voice/VoiceBroadcast.js +366 -0
- package/src/client/voice/VoiceConnection.js +530 -0
- package/src/client/voice/VoiceUDPClient.js +127 -0
- package/src/client/voice/VoiceWebSocket.js +246 -0
- package/src/client/voice/dispatcher/StreamDispatcher.js +331 -0
- package/src/client/voice/opus/BaseOpusEngine.js +60 -0
- package/src/client/voice/opus/NodeOpusEngine.js +40 -0
- package/src/client/voice/opus/OpusEngineList.js +28 -0
- package/src/client/voice/opus/OpusScriptEngine.js +45 -0
- package/src/client/voice/player/AudioPlayer.js +170 -0
- package/src/client/voice/receiver/VoiceReadable.js +17 -0
- package/src/client/voice/receiver/VoiceReceiver.js +219 -0
- package/src/client/voice/util/SecretKey.js +16 -0
- package/src/client/voice/util/Secretbox.js +33 -0
- package/src/client/voice/util/VolumeInterface.js +86 -0
- package/src/client/websocket/WebSocketConnection.js +506 -0
- package/src/client/websocket/WebSocketManager.js +90 -0
- package/src/client/websocket/packets/WebSocketPacketManager.js +110 -0
- package/src/client/websocket/packets/handlers/AbstractHandler.js +11 -0
- package/src/client/websocket/packets/handlers/ChannelCreate.js +17 -0
- package/src/client/websocket/packets/handlers/ChannelDelete.js +20 -0
- package/src/client/websocket/packets/handlers/ChannelPinsUpdate.js +37 -0
- package/src/client/websocket/packets/handlers/ChannelUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/GuildBanAdd.js +23 -0
- package/src/client/websocket/packets/handlers/GuildBanRemove.js +20 -0
- package/src/client/websocket/packets/handlers/GuildCreate.js +22 -0
- package/src/client/websocket/packets/handlers/GuildDelete.js +19 -0
- package/src/client/websocket/packets/handlers/GuildEmojisUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js +19 -0
- package/src/client/websocket/packets/handlers/GuildMemberAdd.js +17 -0
- package/src/client/websocket/packets/handlers/GuildMemberRemove.js +13 -0
- package/src/client/websocket/packets/handlers/GuildMemberUpdate.js +18 -0
- package/src/client/websocket/packets/handlers/GuildMembersChunk.js +33 -0
- package/src/client/websocket/packets/handlers/GuildRoleCreate.js +11 -0
- package/src/client/websocket/packets/handlers/GuildRoleDelete.js +11 -0
- package/src/client/websocket/packets/handlers/GuildRoleUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/GuildSync.js +11 -0
- package/src/client/websocket/packets/handlers/GuildUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/MessageCreate.js +19 -0
- package/src/client/websocket/packets/handlers/MessageDelete.js +19 -0
- package/src/client/websocket/packets/handlers/MessageDeleteBulk.js +17 -0
- package/src/client/websocket/packets/handlers/MessageReactionAdd.js +11 -0
- package/src/client/websocket/packets/handlers/MessageReactionRemove.js +11 -0
- package/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js +11 -0
- package/src/client/websocket/packets/handlers/MessageUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/PresenceUpdate.js +76 -0
- package/src/client/websocket/packets/handlers/Ready.js +83 -0
- package/src/client/websocket/packets/handlers/RelationshipAdd.js +19 -0
- package/src/client/websocket/packets/handlers/RelationshipRemove.js +19 -0
- package/src/client/websocket/packets/handlers/Resumed.js +28 -0
- package/src/client/websocket/packets/handlers/TypingStart.js +68 -0
- package/src/client/websocket/packets/handlers/UserGuildSettingsUpdate.js +21 -0
- package/src/client/websocket/packets/handlers/UserNoteUpdate.js +12 -0
- package/src/client/websocket/packets/handlers/UserSettingsUpdate.js +18 -0
- package/src/client/websocket/packets/handlers/UserUpdate.js +11 -0
- package/src/client/websocket/packets/handlers/VoiceServerUpdate.js +19 -0
- package/src/client/websocket/packets/handlers/VoiceStateUpdate.js +52 -0
- package/src/client/websocket/packets/handlers/WebhooksUpdate.js +19 -0
- package/src/index.js +66 -0
- package/src/sharding/Shard.js +282 -0
- package/src/sharding/ShardClientUtil.js +146 -0
- package/src/sharding/ShardingManager.js +220 -0
- package/src/structures/Attachment.js +75 -0
- package/src/structures/CategoryChannel.js +22 -0
- package/src/structures/Channel.js +78 -0
- package/src/structures/ClientUser.js +447 -0
- package/src/structures/ClientUserChannelOverride.js +30 -0
- package/src/structures/ClientUserGuildSettings.js +60 -0
- package/src/structures/ClientUserSettings.js +80 -0
- package/src/structures/DMChannel.js +76 -0
- package/src/structures/Emoji.js +256 -0
- package/src/structures/GroupDMChannel.js +246 -0
- package/src/structures/Guild.js +1461 -0
- package/src/structures/GuildAuditLogs.js +371 -0
- package/src/structures/GuildChannel.js +537 -0
- package/src/structures/GuildMember.js +613 -0
- package/src/structures/Invite.js +164 -0
- package/src/structures/Message.js +605 -0
- package/src/structures/MessageAttachment.js +68 -0
- package/src/structures/MessageCollector.js +100 -0
- package/src/structures/MessageEmbed.js +386 -0
- package/src/structures/MessageMentions.js +144 -0
- package/src/structures/MessageReaction.js +96 -0
- package/src/structures/NewsChannel.js +24 -0
- package/src/structures/OAuth2Application.js +148 -0
- package/src/structures/PartialGuild.js +51 -0
- package/src/structures/PartialGuildChannel.js +44 -0
- package/src/structures/PermissionOverwrites.js +69 -0
- package/src/structures/Presence.js +241 -0
- package/src/structures/ReactionCollector.js +85 -0
- package/src/structures/ReactionEmoji.js +49 -0
- package/src/structures/RichEmbed.js +295 -0
- package/src/structures/Role.js +376 -0
- package/src/structures/StoreChannel.js +25 -0
- package/src/structures/TextChannel.js +154 -0
- package/src/structures/User.js +329 -0
- package/src/structures/UserConnection.js +48 -0
- package/src/structures/UserProfile.js +62 -0
- package/src/structures/VoiceChannel.js +146 -0
- package/src/structures/VoiceRegion.js +50 -0
- package/src/structures/Webhook.js +304 -0
- package/src/structures/interfaces/Collector.js +179 -0
- package/src/structures/interfaces/TextBasedChannel.js +635 -0
- package/src/structures/shared/resolvePermissions.js +26 -0
- package/src/util/Collection.js +532 -0
- package/src/util/Constants.js +845 -0
- package/src/util/Permissions.js +306 -0
- package/src/util/Snowflake.js +82 -0
- package/src/util/Util.js +221 -0
- package/test/random.js +207 -0
- package/test/shard.js +31 -0
- package/test/sharder.js +7 -0
- package/test/voice.js +78 -0
- package/test/webpack.html +31 -0
- package/tsconfig.json +13 -0
- package/tslint.json +62 -0
- package/typings/discord.js-test.ts +69 -0
- package/typings/index.d.ts +2190 -0
- package/webpack.config.js +62 -0
@@ -0,0 +1,635 @@
|
|
1
|
+
const path = require('path');
|
2
|
+
const Message = require('../Message');
|
3
|
+
const MessageCollector = require('../MessageCollector');
|
4
|
+
const Collection = require('../../util/Collection');
|
5
|
+
const Attachment = require('../../structures/Attachment');
|
6
|
+
const RichEmbed = require('../../structures/RichEmbed');
|
7
|
+
const Snowflake = require('../../util/Snowflake');
|
8
|
+
const util = require('util');
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Interface for classes that have text-channel-like features.
|
12
|
+
* @interface
|
13
|
+
*/
|
14
|
+
class TextBasedChannel {
|
15
|
+
constructor() {
|
16
|
+
/**
|
17
|
+
* A collection containing the messages sent to this channel
|
18
|
+
* @type {Collection<Snowflake, Message>}
|
19
|
+
*/
|
20
|
+
this.messages = new Collection();
|
21
|
+
|
22
|
+
/**
|
23
|
+
* The ID of the last message in the channel, if one was sent
|
24
|
+
* @type {?Snowflake}
|
25
|
+
*/
|
26
|
+
this.lastMessageID = null;
|
27
|
+
|
28
|
+
/**
|
29
|
+
* The Message object of the last message in the channel, if one was sent
|
30
|
+
* @type {?Message}
|
31
|
+
*/
|
32
|
+
this.lastMessage = null;
|
33
|
+
|
34
|
+
/**
|
35
|
+
* The timestamp when the last pinned message was pinned, if there was one
|
36
|
+
* @type {?number}
|
37
|
+
*/
|
38
|
+
this.lastPinTimestamp = null;
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Options provided when sending or editing a message.
|
43
|
+
* @typedef {Object} MessageOptions
|
44
|
+
* @property {boolean} [tts=false] Whether or not the message should be spoken aloud
|
45
|
+
* @property {string} [nonce=''] The nonce for the message
|
46
|
+
* @property {RichEmbed|Object} [embed] An embed for the message
|
47
|
+
* (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details)
|
48
|
+
* @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here
|
49
|
+
* should be replaced with plain-text
|
50
|
+
* @property {FileOptions|BufferResolvable|Attachment} [file] A file to send with the message **(deprecated)**
|
51
|
+
* @property {FileOptions[]|BufferResolvable[]|Attachment[]} [files] Files to send with the message
|
52
|
+
* @property {string|boolean} [code] Language for optional codeblock formatting to apply
|
53
|
+
* @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if
|
54
|
+
* it exceeds the character limit. If an object is provided, these are the options for splitting the message
|
55
|
+
* @property {UserResolvable} [reply] User to reply to (prefixes the message with a mention, except in DMs)
|
56
|
+
*/
|
57
|
+
|
58
|
+
/**
|
59
|
+
* @typedef {Object} FileOptions
|
60
|
+
* @property {BufferResolvable} attachment File to attach
|
61
|
+
* @property {string} [name='file.jpg'] Filename of the attachment
|
62
|
+
*/
|
63
|
+
|
64
|
+
/**
|
65
|
+
* Options for splitting a message.
|
66
|
+
* @typedef {Object} SplitOptions
|
67
|
+
* @property {number} [maxLength=1950] Maximum character length per message piece
|
68
|
+
* @property {string} [char='\n'] Character to split the message with
|
69
|
+
* @property {string} [prepend=''] Text to prepend to every piece except the first
|
70
|
+
* @property {string} [append=''] Text to append to every piece except the last
|
71
|
+
*/
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Send a message to this channel.
|
75
|
+
* @param {StringResolvable} [content] Text for the message
|
76
|
+
* @param {MessageOptions|Attachment|RichEmbed} [options] Options for the message,
|
77
|
+
* can also be just a RichEmbed or Attachment
|
78
|
+
* @returns {Promise<Message|Message[]>}
|
79
|
+
* @example
|
80
|
+
* // Send a basic message
|
81
|
+
* channel.send('hello!')
|
82
|
+
* .then(message => console.log(`Sent message: ${message.content}`))
|
83
|
+
* .catch(console.error);
|
84
|
+
* @example
|
85
|
+
* // Send a remote file
|
86
|
+
* channel.send({
|
87
|
+
* files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
|
88
|
+
* })
|
89
|
+
* .then(console.log)
|
90
|
+
* .catch(console.error);
|
91
|
+
* @example
|
92
|
+
* // Send a local file
|
93
|
+
* channel.send({
|
94
|
+
* files: [{
|
95
|
+
* attachment: 'entire/path/to/file.jpg',
|
96
|
+
* name: 'file.jpg'
|
97
|
+
* }]
|
98
|
+
* })
|
99
|
+
* .then(console.log)
|
100
|
+
* .catch(console.error);
|
101
|
+
* @example
|
102
|
+
* // Send an embed with a local image inside
|
103
|
+
* channel.send('This is an embed', {
|
104
|
+
* embed: {
|
105
|
+
* thumbnail: {
|
106
|
+
* url: 'attachment://file.jpg'
|
107
|
+
* }
|
108
|
+
* },
|
109
|
+
* files: [{
|
110
|
+
* attachment: 'entire/path/to/file.jpg',
|
111
|
+
* name: 'file.jpg'
|
112
|
+
* }]
|
113
|
+
* })
|
114
|
+
* .then(console.log)
|
115
|
+
* .catch(console.error);
|
116
|
+
*/
|
117
|
+
// eslint-disable-next-line complexity
|
118
|
+
send(content, options) {
|
119
|
+
if (!options && typeof content === 'object' && !(content instanceof Array)) {
|
120
|
+
options = content;
|
121
|
+
content = '';
|
122
|
+
} else if (!options) {
|
123
|
+
options = {};
|
124
|
+
}
|
125
|
+
|
126
|
+
const { reply } = options;
|
127
|
+
if (options instanceof Attachment) options = { files: [options.file] };
|
128
|
+
if (options instanceof RichEmbed) {
|
129
|
+
if (options.reply) options.reply = undefined;
|
130
|
+
options = { embed: options };
|
131
|
+
}
|
132
|
+
options.reply = reply;
|
133
|
+
|
134
|
+
if (options.embed) {
|
135
|
+
if (options.embed.file) {
|
136
|
+
if (options.files) options.files.push(options.embed.file);
|
137
|
+
else options.files = [options.embed.file];
|
138
|
+
}
|
139
|
+
if (options.embed.files) {
|
140
|
+
if (options.files) options.files = options.files.concat(options.embed.files);
|
141
|
+
else options.files = options.embed.files;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
if (options.file) {
|
146
|
+
if (options.files) options.files.push(options.file);
|
147
|
+
else options.files = [options.file];
|
148
|
+
}
|
149
|
+
|
150
|
+
if (options.embed) options.embed = new RichEmbed(options.embed)._apiTransform();
|
151
|
+
|
152
|
+
if (options.files) {
|
153
|
+
for (let i = 0; i < options.files.length; i++) {
|
154
|
+
let file = options.files[i];
|
155
|
+
if (!file || typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file };
|
156
|
+
if (!file.name) {
|
157
|
+
if (typeof file.attachment === 'string') {
|
158
|
+
file.name = path.basename(file.attachment);
|
159
|
+
} else if (file.attachment && file.attachment.path) {
|
160
|
+
file.name = path.basename(file.attachment.path);
|
161
|
+
} else if (file instanceof Attachment) {
|
162
|
+
file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' };
|
163
|
+
} else {
|
164
|
+
file.name = 'file.jpg';
|
165
|
+
}
|
166
|
+
} else if (file instanceof Attachment) {
|
167
|
+
file = file.file;
|
168
|
+
}
|
169
|
+
options.files[i] = file;
|
170
|
+
}
|
171
|
+
|
172
|
+
return Promise.all(options.files.map(file =>
|
173
|
+
this.client.resolver.resolveFile(file.attachment).then(resource => {
|
174
|
+
file.file = resource;
|
175
|
+
return file;
|
176
|
+
})
|
177
|
+
)).then(files => this.client.rest.methods.sendMessage(this, content, options, files));
|
178
|
+
}
|
179
|
+
|
180
|
+
return this.client.rest.methods.sendMessage(this, content, options);
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Gets a single message from this channel, regardless of it being cached or not.
|
185
|
+
* @param {Snowflake} messageID ID of the message to get
|
186
|
+
* @returns {Promise<Message>}
|
187
|
+
* @example
|
188
|
+
* // Get message
|
189
|
+
* channel.fetchMessage('99539446449315840')
|
190
|
+
* .then(message => console.log(message.content))
|
191
|
+
* .catch(console.error);
|
192
|
+
*/
|
193
|
+
fetchMessage(messageID) {
|
194
|
+
if (!this.client.user.bot) {
|
195
|
+
return this.fetchMessages({ limit: 1, around: messageID }).then(messages => {
|
196
|
+
const msg = messages.get(messageID);
|
197
|
+
if (!msg) throw new Error('Message not found.');
|
198
|
+
return msg;
|
199
|
+
});
|
200
|
+
}
|
201
|
+
return this.client.rest.methods.getChannelMessage(this, messageID).then(data => {
|
202
|
+
const msg = data instanceof Message ? data : new Message(this, data, this.client);
|
203
|
+
this._cacheMessage(msg);
|
204
|
+
return msg;
|
205
|
+
});
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
* The parameters to pass in when requesting previous messages from a channel. `around`, `before` and
|
210
|
+
* `after` are mutually exclusive. All the parameters are optional.
|
211
|
+
* @typedef {Object} ChannelLogsQueryOptions
|
212
|
+
* @property {number} [limit=50] Number of messages to acquire
|
213
|
+
* @property {Snowflake} [before] ID of a message to get the messages that were posted before it
|
214
|
+
* @property {Snowflake} [after] ID of a message to get the messages that were posted after it
|
215
|
+
* @property {Snowflake} [around] ID of a message to get the messages that were posted around it
|
216
|
+
*/
|
217
|
+
|
218
|
+
/**
|
219
|
+
* Gets the past messages sent in this channel. Resolves with a collection mapping message ID's to Message objects.
|
220
|
+
* <info>The returned Collection does not contain reaction users of the messages if they were not cached.
|
221
|
+
* Those need to be fetched separately in such a case.</info>
|
222
|
+
* @param {ChannelLogsQueryOptions} [options={}] Query parameters to pass in
|
223
|
+
* @returns {Promise<Collection<Snowflake, Message>>}
|
224
|
+
* @example
|
225
|
+
* // Get messages
|
226
|
+
* channel.fetchMessages({ limit: 10 })
|
227
|
+
* .then(messages => console.log(`Received ${messages.size} messages`))
|
228
|
+
* .catch(console.error);
|
229
|
+
* @example
|
230
|
+
* // Get messages and filter by user ID
|
231
|
+
* channel.fetchMessages()
|
232
|
+
* .then(messages => console.log(`${messages.filter(m => m.author.id === '84484653687267328').size} messages`))
|
233
|
+
* .catch(console.error);
|
234
|
+
*/
|
235
|
+
fetchMessages(options = {}) {
|
236
|
+
return this.client.rest.methods.getChannelMessages(this, options).then(data => {
|
237
|
+
const messages = new Collection();
|
238
|
+
for (const message of data) {
|
239
|
+
const msg = new Message(this, message, this.client);
|
240
|
+
messages.set(message.id, msg);
|
241
|
+
this._cacheMessage(msg);
|
242
|
+
}
|
243
|
+
return messages;
|
244
|
+
});
|
245
|
+
}
|
246
|
+
|
247
|
+
/**
|
248
|
+
* Fetches the pinned messages of this channel and returns a collection of them.
|
249
|
+
* <info>The returned Collection does not contain any reaction data of the messages.
|
250
|
+
* Those need to be fetched separately.</info>
|
251
|
+
* @returns {Promise<Collection<Snowflake, Message>>}
|
252
|
+
* @example
|
253
|
+
* // Get pinned messages
|
254
|
+
* channel.fetchPinnedMessages()
|
255
|
+
* .then(messages => console.log(`Received ${messages.size} messages`))
|
256
|
+
* .catch(console.error);
|
257
|
+
*/
|
258
|
+
fetchPinnedMessages() {
|
259
|
+
return this.client.rest.methods.getChannelPinnedMessages(this).then(data => {
|
260
|
+
const messages = new Collection();
|
261
|
+
for (const message of data) {
|
262
|
+
const msg = new Message(this, message, this.client);
|
263
|
+
messages.set(message.id, msg);
|
264
|
+
this._cacheMessage(msg);
|
265
|
+
}
|
266
|
+
return messages;
|
267
|
+
});
|
268
|
+
}
|
269
|
+
|
270
|
+
/**
|
271
|
+
* @typedef {Object} MessageSearchOptions
|
272
|
+
* @property {string} [content] Message content
|
273
|
+
* @property {Snowflake} [maxID] Maximum ID for the filter
|
274
|
+
* @property {Snowflake} [minID] Minimum ID for the filter
|
275
|
+
* @property {string} [has] One of `link`, `embed`, `file`, `video`, `image`, or `sound`,
|
276
|
+
* or add `-` to negate (e.g. `-file`)
|
277
|
+
* @property {ChannelResolvable} [channel] Channel to limit search to (only for guild search endpoint)
|
278
|
+
* @property {UserResolvable} [author] Author to limit search
|
279
|
+
* @property {string} [authorType] One of `user`, `bot`, `webhook`, or add `-` to negate (e.g. `-webhook`)
|
280
|
+
* @property {string} [sortBy='recent'] `recent` or `relevant`
|
281
|
+
* @property {string} [sortOrder='desc'] `asc` or `desc`
|
282
|
+
* @property {number} [contextSize=2] How many messages to get around the matched message (0 to 2)
|
283
|
+
* @property {number} [limit=25] Maximum number of results to get (1 to 25)
|
284
|
+
* @property {number} [offset=0] Offset the "pages" of results (since you can only see 25 at a time)
|
285
|
+
* @property {UserResolvable} [mentions] Mentioned user filter
|
286
|
+
* @property {boolean} [mentionsEveryone] If everyone is mentioned
|
287
|
+
* @property {string} [linkHostname] Filter links by hostname
|
288
|
+
* @property {string} [embedProvider] The name of an embed provider
|
289
|
+
* @property {string} [embedType] one of `image`, `video`, `url`, `rich`
|
290
|
+
* @property {string} [attachmentFilename] The name of an attachment
|
291
|
+
* @property {string} [attachmentExtension] The extension of an attachment
|
292
|
+
* @property {Date} [before] Date to find messages before
|
293
|
+
* @property {Date} [after] Date to find messages before
|
294
|
+
* @property {Date} [during] Date to find messages during (range of date to date + 24 hours)
|
295
|
+
* @property {boolean} [nsfw=false] Include results from NSFW channels
|
296
|
+
*/
|
297
|
+
|
298
|
+
/**
|
299
|
+
* @typedef {Object} MessageSearchResult
|
300
|
+
* @property {number} totalResults Total result count
|
301
|
+
* @property {Message[][]} messages Array of message results
|
302
|
+
* The message which has triggered the result will have the `hit` property set to `true`
|
303
|
+
*/
|
304
|
+
|
305
|
+
/**
|
306
|
+
* Performs a search within the channel.
|
307
|
+
* <warn>This is only available when using a user account.</warn>
|
308
|
+
* @param {MessageSearchOptions} [options={}] Options to pass to the search
|
309
|
+
* @returns {Promise<MessageSearchResult>}
|
310
|
+
* @deprecated
|
311
|
+
* @example
|
312
|
+
* channel.search({
|
313
|
+
* content: 'discord.js',
|
314
|
+
* before: '2016-11-17'
|
315
|
+
* }).then(res => {
|
316
|
+
* const hit = res.messages[0].find(m => m.hit).content;
|
317
|
+
* console.log(`I found: **${hit}**, total results: ${res.totalResults}`);
|
318
|
+
* }).catch(console.error);
|
319
|
+
*/
|
320
|
+
search(options = {}) {
|
321
|
+
return this.client.rest.methods.search(this, options);
|
322
|
+
}
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Starts a typing indicator in the channel.
|
326
|
+
* @param {number} [count] The number of times startTyping should be considered to have been called
|
327
|
+
* @example
|
328
|
+
* // Start typing in a channel
|
329
|
+
* channel.startTyping();
|
330
|
+
*/
|
331
|
+
startTyping(count) {
|
332
|
+
if (typeof count !== 'undefined' && count < 1) throw new RangeError('Count must be at least 1.');
|
333
|
+
if (this.client.user._typing.has(this.id)) {
|
334
|
+
const entry = this.client.user._typing.get(this.id);
|
335
|
+
entry.count = count || entry.count + 1;
|
336
|
+
return;
|
337
|
+
}
|
338
|
+
|
339
|
+
const entry = {
|
340
|
+
count: count || 1,
|
341
|
+
interval: this.client.setInterval(() => {
|
342
|
+
this.client.rest.methods.sendTyping(this.id).catch(() => {
|
343
|
+
this.client.clearInterval(entry.interval);
|
344
|
+
this.client.user._typing.delete(this.id);
|
345
|
+
});
|
346
|
+
}, 9000),
|
347
|
+
};
|
348
|
+
this.client.rest.methods.sendTyping(this.id).catch(() => {
|
349
|
+
this.client.clearInterval(entry.interval);
|
350
|
+
this.client.user._typing.delete(this.id);
|
351
|
+
});
|
352
|
+
this.client.user._typing.set(this.id, entry);
|
353
|
+
}
|
354
|
+
|
355
|
+
/**
|
356
|
+
* Stops the typing indicator in the channel.
|
357
|
+
* The indicator will only stop if this is called as many times as startTyping().
|
358
|
+
* <info>It can take a few seconds for the client user to stop typing.</info>
|
359
|
+
* @param {boolean} [force=false] Whether or not to reset the call count and force the indicator to stop
|
360
|
+
* @example
|
361
|
+
* // Reduce the typing count by one and stop typing if it reached 0
|
362
|
+
* channel.stopTyping();
|
363
|
+
* @example
|
364
|
+
* // Force typing to fully stop in a channel
|
365
|
+
* channel.stopTyping(true);
|
366
|
+
*/
|
367
|
+
stopTyping(force = false) {
|
368
|
+
if (this.client.user._typing.has(this.id)) {
|
369
|
+
const entry = this.client.user._typing.get(this.id);
|
370
|
+
entry.count--;
|
371
|
+
if (entry.count <= 0 || force) {
|
372
|
+
this.client.clearInterval(entry.interval);
|
373
|
+
this.client.user._typing.delete(this.id);
|
374
|
+
}
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Whether or not the typing indicator is being shown in the channel
|
380
|
+
* @type {boolean}
|
381
|
+
* @readonly
|
382
|
+
*/
|
383
|
+
get typing() {
|
384
|
+
return this.client.user._typing.has(this.id);
|
385
|
+
}
|
386
|
+
|
387
|
+
/**
|
388
|
+
* Number of times `startTyping` has been called
|
389
|
+
* @type {number}
|
390
|
+
* @readonly
|
391
|
+
*/
|
392
|
+
get typingCount() {
|
393
|
+
if (this.client.user._typing.has(this.id)) return this.client.user._typing.get(this.id).count;
|
394
|
+
return 0;
|
395
|
+
}
|
396
|
+
|
397
|
+
/**
|
398
|
+
* The Message object of the last message in the channel, if one was sent
|
399
|
+
* @type {?Message}
|
400
|
+
* @readonly
|
401
|
+
*/
|
402
|
+
get lastMessage() {
|
403
|
+
return this.messages.get(this.lastMessageID) || null;
|
404
|
+
}
|
405
|
+
|
406
|
+
/**
|
407
|
+
* The date when the last pinned message was pinned, if there was one
|
408
|
+
* @type {?Date}
|
409
|
+
* @readonly
|
410
|
+
*/
|
411
|
+
get lastPinAt() {
|
412
|
+
return this.lastPinTimestamp ? new Date(this.lastPinTimestamp) : null;
|
413
|
+
}
|
414
|
+
|
415
|
+
/**
|
416
|
+
* Creates a Message Collector
|
417
|
+
* @param {CollectorFilter} filter The filter to create the collector with
|
418
|
+
* @param {MessageCollectorOptions} [options={}] The options to pass to the collector
|
419
|
+
* @returns {MessageCollector}
|
420
|
+
* @deprecated
|
421
|
+
*/
|
422
|
+
createCollector(filter, options) {
|
423
|
+
return this.createMessageCollector(filter, options);
|
424
|
+
}
|
425
|
+
|
426
|
+
/**
|
427
|
+
* Creates a Message Collector.
|
428
|
+
* @param {CollectorFilter} filter The filter to create the collector with
|
429
|
+
* @param {MessageCollectorOptions} [options={}] The options to pass to the collector
|
430
|
+
* @returns {MessageCollector}
|
431
|
+
* @example
|
432
|
+
* // Create a message collector
|
433
|
+
* const filter = m => m.content.includes('discord');
|
434
|
+
* const collector = channel.createMessageCollector(filter, { time: 15000 });
|
435
|
+
* collector.on('collect', m => console.log(`Collected ${m.content}`));
|
436
|
+
* collector.on('end', collected => console.log(`Collected ${collected.size} items`));
|
437
|
+
*/
|
438
|
+
createMessageCollector(filter, options = {}) {
|
439
|
+
return new MessageCollector(this, filter, options);
|
440
|
+
}
|
441
|
+
|
442
|
+
/**
|
443
|
+
* An object containing the same properties as CollectorOptions, but a few more:
|
444
|
+
* @typedef {MessageCollectorOptions} AwaitMessagesOptions
|
445
|
+
* @property {string[]} [errors] Stop/end reasons that cause the promise to reject
|
446
|
+
*/
|
447
|
+
|
448
|
+
/**
|
449
|
+
* Similar to createCollector but in promise form. Resolves with a collection of messages that pass the specified
|
450
|
+
* filter.
|
451
|
+
* @param {CollectorFilter} filter The filter function to use
|
452
|
+
* @param {AwaitMessagesOptions} [options={}] Optional options to pass to the internal collector
|
453
|
+
* @returns {Promise<Collection<Snowflake, Message>>}
|
454
|
+
* @example
|
455
|
+
* // Await !vote messages
|
456
|
+
* const filter = m => m.content.startsWith('!vote');
|
457
|
+
* // Errors: ['time'] treats ending because of the time limit as an error
|
458
|
+
* channel.awaitMessages(filter, { max: 4, time: 60000, errors: ['time'] })
|
459
|
+
* .then(collected => console.log(collected.size))
|
460
|
+
* .catch(collected => console.log(`After a minute, only ${collected.size} out of 4 voted.`));
|
461
|
+
*/
|
462
|
+
awaitMessages(filter, options = {}) {
|
463
|
+
return new Promise((resolve, reject) => {
|
464
|
+
const collector = this.createCollector(filter, options);
|
465
|
+
collector.once('end', (collection, reason) => {
|
466
|
+
if (options.errors && options.errors.includes(reason)) {
|
467
|
+
reject(collection);
|
468
|
+
} else {
|
469
|
+
resolve(collection);
|
470
|
+
}
|
471
|
+
});
|
472
|
+
});
|
473
|
+
}
|
474
|
+
|
475
|
+
/**
|
476
|
+
* Bulk delete given messages that are newer than two weeks.
|
477
|
+
* <warn>This is only available when using a bot account.</warn>
|
478
|
+
* @param {Collection<Snowflake, Message>|Message[]|Snowflake[]|number} messages
|
479
|
+
* Messages or number of messages to delete
|
480
|
+
* @param {boolean} [filterOld=false] Filter messages to remove those which are older than two weeks automatically
|
481
|
+
* @returns {Promise<Collection<Snowflake, Message>>} Deleted messages
|
482
|
+
* @example
|
483
|
+
* // Bulk delete messages
|
484
|
+
* channel.bulkDelete(5)
|
485
|
+
* .then(messages => console.log(`Bulk deleted ${messages.size} messages`))
|
486
|
+
* .catch(console.error);
|
487
|
+
*/
|
488
|
+
bulkDelete(messages, filterOld = false) {
|
489
|
+
if (messages instanceof Array || messages instanceof Collection) {
|
490
|
+
let messageIDs = messages instanceof Collection ? messages.keyArray() : messages.map(m => m.id || m);
|
491
|
+
if (filterOld) {
|
492
|
+
messageIDs = messageIDs.filter(id => Date.now() - Snowflake.deconstruct(id).date.getTime() < 1209600000);
|
493
|
+
}
|
494
|
+
if (messageIDs.length === 0) return Promise.resolve(new Collection());
|
495
|
+
if (messageIDs.length === 1) {
|
496
|
+
return this.fetchMessage(messageIDs[0]).then(m => m.delete()).then(m => new Collection([[m.id, m]]));
|
497
|
+
}
|
498
|
+
return this.client.rest.methods.bulkDeleteMessages(this, messageIDs);
|
499
|
+
}
|
500
|
+
if (!isNaN(messages)) return this.fetchMessages({ limit: messages }).then(msgs => this.bulkDelete(msgs, filterOld));
|
501
|
+
throw new TypeError('The messages must be an Array, Collection, or number.');
|
502
|
+
}
|
503
|
+
|
504
|
+
/**
|
505
|
+
* Marks all messages in this channel as read.
|
506
|
+
* <warn>This is only available when using a user account.</warn>
|
507
|
+
* @returns {Promise<TextChannel|GroupDMChannel|DMChannel>}
|
508
|
+
* @deprecated
|
509
|
+
*/
|
510
|
+
acknowledge() {
|
511
|
+
if (!this.lastMessageID) return Promise.resolve(this);
|
512
|
+
return this.client.rest.methods.ackTextChannel(this);
|
513
|
+
}
|
514
|
+
|
515
|
+
_cacheMessage(message) {
|
516
|
+
const maxSize = this.client.options.messageCacheMaxSize;
|
517
|
+
if (maxSize === 0) return null;
|
518
|
+
if (this.messages.size >= maxSize && maxSize > 0) this.messages.delete(this.messages.firstKey());
|
519
|
+
this.messages.set(message.id, message);
|
520
|
+
return message;
|
521
|
+
}
|
522
|
+
}
|
523
|
+
|
524
|
+
/** @lends TextBasedChannel.prototype */
|
525
|
+
const Deprecated = {
|
526
|
+
/**
|
527
|
+
* Send a message to this channel.
|
528
|
+
* @param {StringResolvable} [content] Text for the message
|
529
|
+
* @param {MessageOptions} [options={}] Options for the message
|
530
|
+
* @returns {Promise<Message|Message[]>}
|
531
|
+
* @deprecated
|
532
|
+
* @example
|
533
|
+
* // Send a message
|
534
|
+
* channel.sendMessage('hello!')
|
535
|
+
* .then(message => console.log(`Sent message: ${message.content}`))
|
536
|
+
* .catch(console.error);
|
537
|
+
*/
|
538
|
+
sendMessage(content, options) {
|
539
|
+
return this.send(content, options);
|
540
|
+
},
|
541
|
+
|
542
|
+
/**
|
543
|
+
* Send an embed to this channel.
|
544
|
+
* @param {RichEmbed|Object} embed Embed for the message
|
545
|
+
* @param {string} [content] Text for the message
|
546
|
+
* @param {MessageOptions} [options] Options for the message
|
547
|
+
* @returns {Promise<Message>}
|
548
|
+
* @deprecated
|
549
|
+
*/
|
550
|
+
sendEmbed(embed, content, options) {
|
551
|
+
if (!options && typeof content === 'object' && !(content instanceof Array)) {
|
552
|
+
options = content;
|
553
|
+
content = '';
|
554
|
+
} else if (!options) {
|
555
|
+
options = {};
|
556
|
+
}
|
557
|
+
return this.send(content, Object.assign(options, { embed }));
|
558
|
+
},
|
559
|
+
|
560
|
+
/**
|
561
|
+
* Send files to this channel.
|
562
|
+
* @param {FileOptions[]|string[]} files Files to send with the message
|
563
|
+
* @param {StringResolvable} [content] Text for the message
|
564
|
+
* @param {MessageOptions} [options] Options for the message
|
565
|
+
* @returns {Promise<Message>}
|
566
|
+
* @deprecated
|
567
|
+
*/
|
568
|
+
sendFiles(files, content, options = {}) {
|
569
|
+
return this.send(content, Object.assign(options, { files }));
|
570
|
+
},
|
571
|
+
|
572
|
+
/**
|
573
|
+
* Send a file to this channel.
|
574
|
+
* @param {BufferResolvable} attachment File to send
|
575
|
+
* @param {string} [name='file.jpg'] Name and extension of the file
|
576
|
+
* @param {StringResolvable} [content] Text for the message
|
577
|
+
* @param {MessageOptions} [options] Options for the message
|
578
|
+
* @returns {Promise<Message>}
|
579
|
+
* @deprecated
|
580
|
+
*/
|
581
|
+
sendFile(attachment, name, content, options = {}) {
|
582
|
+
return this.send({ files: [{ attachment, name }], content, options });
|
583
|
+
},
|
584
|
+
|
585
|
+
/**
|
586
|
+
* Send a code block to this channel.
|
587
|
+
* @param {string} lang Language for the code block
|
588
|
+
* @param {StringResolvable} content Content of the code block
|
589
|
+
* @param {MessageOptions} [options] Options for the message
|
590
|
+
* @returns {Promise<Message|Message[]>}
|
591
|
+
* @deprecated
|
592
|
+
*/
|
593
|
+
sendCode(lang, content, options = {}) {
|
594
|
+
return this.send(content, Object.assign(options, { code: lang }));
|
595
|
+
},
|
596
|
+
};
|
597
|
+
|
598
|
+
for (const key of Object.keys(Deprecated)) {
|
599
|
+
TextBasedChannel.prototype[key] = util.deprecate(Deprecated[key], `TextChannel#${key}: use TextChannel#send instead`);
|
600
|
+
}
|
601
|
+
|
602
|
+
exports.applyToClass = (structure, full = false, ignore = []) => {
|
603
|
+
const props = ['send', 'sendMessage', 'sendEmbed', 'sendFile', 'sendFiles', 'sendCode'];
|
604
|
+
if (full) {
|
605
|
+
props.push(
|
606
|
+
'_cacheMessage',
|
607
|
+
'acknowledge',
|
608
|
+
'fetchMessages',
|
609
|
+
'fetchMessage',
|
610
|
+
'search',
|
611
|
+
'lastMessage',
|
612
|
+
'lastPinAt',
|
613
|
+
'bulkDelete',
|
614
|
+
'startTyping',
|
615
|
+
'stopTyping',
|
616
|
+
'typing',
|
617
|
+
'typingCount',
|
618
|
+
'fetchPinnedMessages',
|
619
|
+
'createCollector',
|
620
|
+
'createMessageCollector',
|
621
|
+
'awaitMessages'
|
622
|
+
);
|
623
|
+
}
|
624
|
+
for (const prop of props) {
|
625
|
+
if (ignore.includes(prop)) continue;
|
626
|
+
Object.defineProperty(structure.prototype, prop, Object.getOwnPropertyDescriptor(TextBasedChannel.prototype, prop));
|
627
|
+
}
|
628
|
+
};
|
629
|
+
|
630
|
+
TextBasedChannel.prototype.acknowledge = util.deprecate(
|
631
|
+
TextBasedChannel.prototype.acknowledge, 'TextBasedChannel#acknowledge: userbot methods will be removed'
|
632
|
+
);
|
633
|
+
|
634
|
+
TextBasedChannel.prototype.search =
|
635
|
+
util.deprecate(TextBasedChannel.prototype.search, 'TextBasedChannel#search: userbot methods will be removed');
|
@@ -0,0 +1,26 @@
|
|
1
|
+
const Permissions = require('../../util/Permissions');
|
2
|
+
const Collection = require('../../util/Collection');
|
3
|
+
|
4
|
+
module.exports = function resolvePermissions(overwrites, guild) {
|
5
|
+
if (overwrites instanceof Collection || overwrites instanceof Array) {
|
6
|
+
overwrites = overwrites.map(overwrite => {
|
7
|
+
const role = this.client.resolver.resolveRole(guild, overwrite.id);
|
8
|
+
if (role) {
|
9
|
+
overwrite.id = role.id;
|
10
|
+
overwrite.type = 'role';
|
11
|
+
} else {
|
12
|
+
overwrite.id = this.client.resolver.resolveUserID(overwrite.id);
|
13
|
+
overwrite.type = 'member';
|
14
|
+
}
|
15
|
+
|
16
|
+
return {
|
17
|
+
allow: Permissions.resolve(overwrite.allow || overwrite.allowed || 0),
|
18
|
+
deny: Permissions.resolve(overwrite.deny || overwrite.denied || 0),
|
19
|
+
type: overwrite.type,
|
20
|
+
id: overwrite.id,
|
21
|
+
};
|
22
|
+
});
|
23
|
+
}
|
24
|
+
|
25
|
+
return overwrites;
|
26
|
+
};
|