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.

Files changed (188) hide show
  1. package/.dccache +1 -0
  2. package/LICENSE +190 -0
  3. package/README.md +87 -0
  4. package/browser.js +9 -0
  5. package/deploy/deploy-key.enc +0 -0
  6. package/deploy/deploy.sh +90 -0
  7. package/deploy/test.sh +34 -0
  8. package/docs/README.md +1 -0
  9. package/docs/examples/attachments.md +163 -0
  10. package/docs/examples/avatars.js +29 -0
  11. package/docs/examples/embed.js +38 -0
  12. package/docs/examples/greeting.js +30 -0
  13. package/docs/examples/moderation.md +145 -0
  14. package/docs/examples/ping.js +29 -0
  15. package/docs/examples/webhook.js +12 -0
  16. package/docs/general/faq.md +23 -0
  17. package/docs/general/updating.md +181 -0
  18. package/docs/general/welcome.md +95 -0
  19. package/docs/index.yml +30 -0
  20. package/docs/logo.svg +19 -0
  21. package/docs/topics/voice.md +113 -0
  22. package/docs/topics/web.md +38 -0
  23. package/package.json +147 -0
  24. package/src/client/Client.js +564 -0
  25. package/src/client/ClientDataManager.js +150 -0
  26. package/src/client/ClientDataResolver.js +376 -0
  27. package/src/client/ClientManager.js +74 -0
  28. package/src/client/WebhookClient.js +118 -0
  29. package/src/client/actions/Action.js +23 -0
  30. package/src/client/actions/ActionsManager.js +40 -0
  31. package/src/client/actions/ChannelCreate.js +11 -0
  32. package/src/client/actions/ChannelDelete.js +30 -0
  33. package/src/client/actions/ChannelUpdate.js +74 -0
  34. package/src/client/actions/GuildBanRemove.js +13 -0
  35. package/src/client/actions/GuildChannelsPositionUpdate.js +19 -0
  36. package/src/client/actions/GuildDelete.js +57 -0
  37. package/src/client/actions/GuildEmojiCreate.js +17 -0
  38. package/src/client/actions/GuildEmojiDelete.js +18 -0
  39. package/src/client/actions/GuildEmojiUpdate.js +17 -0
  40. package/src/client/actions/GuildEmojisUpdate.js +38 -0
  41. package/src/client/actions/GuildMemberGet.js +10 -0
  42. package/src/client/actions/GuildMemberRemove.js +41 -0
  43. package/src/client/actions/GuildRoleCreate.js +26 -0
  44. package/src/client/actions/GuildRoleDelete.js +42 -0
  45. package/src/client/actions/GuildRoleUpdate.js +41 -0
  46. package/src/client/actions/GuildRolesPositionUpdate.js +19 -0
  47. package/src/client/actions/GuildSync.js +29 -0
  48. package/src/client/actions/GuildUpdate.js +34 -0
  49. package/src/client/actions/MessageCreate.js +53 -0
  50. package/src/client/actions/MessageDelete.js +35 -0
  51. package/src/client/actions/MessageDeleteBulk.js +26 -0
  52. package/src/client/actions/MessageReactionAdd.js +37 -0
  53. package/src/client/actions/MessageReactionRemove.js +37 -0
  54. package/src/client/actions/MessageReactionRemoveAll.js +25 -0
  55. package/src/client/actions/MessageUpdate.js +40 -0
  56. package/src/client/actions/Ready.js +1 -0
  57. package/src/client/actions/Ready.js.bak +65 -0
  58. package/src/client/actions/UserGet.js +11 -0
  59. package/src/client/actions/UserNoteUpdate.js +30 -0
  60. package/src/client/actions/UserUpdate.js +33 -0
  61. package/src/client/rest/APIRequest.js +56 -0
  62. package/src/client/rest/DiscordAPIError.js +60 -0
  63. package/src/client/rest/RESTManager.js +58 -0
  64. package/src/client/rest/RESTMethods.js +1006 -0
  65. package/src/client/rest/RequestHandlers/Burst.js +90 -0
  66. package/src/client/rest/RequestHandlers/RequestHandler.js +54 -0
  67. package/src/client/rest/RequestHandlers/Sequential.js +132 -0
  68. package/src/client/rest/UserAgentManager.js +25 -0
  69. package/src/client/voice/ClientVoiceManager.js +81 -0
  70. package/src/client/voice/VoiceBroadcast.js +366 -0
  71. package/src/client/voice/VoiceConnection.js +530 -0
  72. package/src/client/voice/VoiceUDPClient.js +127 -0
  73. package/src/client/voice/VoiceWebSocket.js +246 -0
  74. package/src/client/voice/dispatcher/StreamDispatcher.js +331 -0
  75. package/src/client/voice/opus/BaseOpusEngine.js +60 -0
  76. package/src/client/voice/opus/NodeOpusEngine.js +40 -0
  77. package/src/client/voice/opus/OpusEngineList.js +28 -0
  78. package/src/client/voice/opus/OpusScriptEngine.js +45 -0
  79. package/src/client/voice/player/AudioPlayer.js +170 -0
  80. package/src/client/voice/receiver/VoiceReadable.js +17 -0
  81. package/src/client/voice/receiver/VoiceReceiver.js +219 -0
  82. package/src/client/voice/util/SecretKey.js +16 -0
  83. package/src/client/voice/util/Secretbox.js +33 -0
  84. package/src/client/voice/util/VolumeInterface.js +86 -0
  85. package/src/client/websocket/WebSocketConnection.js +506 -0
  86. package/src/client/websocket/WebSocketManager.js +90 -0
  87. package/src/client/websocket/packets/WebSocketPacketManager.js +110 -0
  88. package/src/client/websocket/packets/handlers/AbstractHandler.js +11 -0
  89. package/src/client/websocket/packets/handlers/ChannelCreate.js +17 -0
  90. package/src/client/websocket/packets/handlers/ChannelDelete.js +20 -0
  91. package/src/client/websocket/packets/handlers/ChannelPinsUpdate.js +37 -0
  92. package/src/client/websocket/packets/handlers/ChannelUpdate.js +11 -0
  93. package/src/client/websocket/packets/handlers/GuildBanAdd.js +23 -0
  94. package/src/client/websocket/packets/handlers/GuildBanRemove.js +20 -0
  95. package/src/client/websocket/packets/handlers/GuildCreate.js +22 -0
  96. package/src/client/websocket/packets/handlers/GuildDelete.js +19 -0
  97. package/src/client/websocket/packets/handlers/GuildEmojisUpdate.js +11 -0
  98. package/src/client/websocket/packets/handlers/GuildIntegrationsUpdate.js +19 -0
  99. package/src/client/websocket/packets/handlers/GuildMemberAdd.js +17 -0
  100. package/src/client/websocket/packets/handlers/GuildMemberRemove.js +13 -0
  101. package/src/client/websocket/packets/handlers/GuildMemberUpdate.js +18 -0
  102. package/src/client/websocket/packets/handlers/GuildMembersChunk.js +33 -0
  103. package/src/client/websocket/packets/handlers/GuildRoleCreate.js +11 -0
  104. package/src/client/websocket/packets/handlers/GuildRoleDelete.js +11 -0
  105. package/src/client/websocket/packets/handlers/GuildRoleUpdate.js +11 -0
  106. package/src/client/websocket/packets/handlers/GuildSync.js +11 -0
  107. package/src/client/websocket/packets/handlers/GuildUpdate.js +11 -0
  108. package/src/client/websocket/packets/handlers/MessageCreate.js +19 -0
  109. package/src/client/websocket/packets/handlers/MessageDelete.js +19 -0
  110. package/src/client/websocket/packets/handlers/MessageDeleteBulk.js +17 -0
  111. package/src/client/websocket/packets/handlers/MessageReactionAdd.js +11 -0
  112. package/src/client/websocket/packets/handlers/MessageReactionRemove.js +11 -0
  113. package/src/client/websocket/packets/handlers/MessageReactionRemoveAll.js +11 -0
  114. package/src/client/websocket/packets/handlers/MessageUpdate.js +11 -0
  115. package/src/client/websocket/packets/handlers/PresenceUpdate.js +76 -0
  116. package/src/client/websocket/packets/handlers/Ready.js +83 -0
  117. package/src/client/websocket/packets/handlers/RelationshipAdd.js +19 -0
  118. package/src/client/websocket/packets/handlers/RelationshipRemove.js +19 -0
  119. package/src/client/websocket/packets/handlers/Resumed.js +28 -0
  120. package/src/client/websocket/packets/handlers/TypingStart.js +68 -0
  121. package/src/client/websocket/packets/handlers/UserGuildSettingsUpdate.js +21 -0
  122. package/src/client/websocket/packets/handlers/UserNoteUpdate.js +12 -0
  123. package/src/client/websocket/packets/handlers/UserSettingsUpdate.js +18 -0
  124. package/src/client/websocket/packets/handlers/UserUpdate.js +11 -0
  125. package/src/client/websocket/packets/handlers/VoiceServerUpdate.js +19 -0
  126. package/src/client/websocket/packets/handlers/VoiceStateUpdate.js +52 -0
  127. package/src/client/websocket/packets/handlers/WebhooksUpdate.js +19 -0
  128. package/src/index.js +66 -0
  129. package/src/sharding/Shard.js +282 -0
  130. package/src/sharding/ShardClientUtil.js +146 -0
  131. package/src/sharding/ShardingManager.js +220 -0
  132. package/src/structures/Attachment.js +75 -0
  133. package/src/structures/CategoryChannel.js +22 -0
  134. package/src/structures/Channel.js +78 -0
  135. package/src/structures/ClientUser.js +447 -0
  136. package/src/structures/ClientUserChannelOverride.js +30 -0
  137. package/src/structures/ClientUserGuildSettings.js +60 -0
  138. package/src/structures/ClientUserSettings.js +80 -0
  139. package/src/structures/DMChannel.js +76 -0
  140. package/src/structures/Emoji.js +256 -0
  141. package/src/structures/GroupDMChannel.js +246 -0
  142. package/src/structures/Guild.js +1461 -0
  143. package/src/structures/GuildAuditLogs.js +371 -0
  144. package/src/structures/GuildChannel.js +537 -0
  145. package/src/structures/GuildMember.js +613 -0
  146. package/src/structures/Invite.js +164 -0
  147. package/src/structures/Message.js +605 -0
  148. package/src/structures/MessageAttachment.js +68 -0
  149. package/src/structures/MessageCollector.js +100 -0
  150. package/src/structures/MessageEmbed.js +386 -0
  151. package/src/structures/MessageMentions.js +144 -0
  152. package/src/structures/MessageReaction.js +96 -0
  153. package/src/structures/NewsChannel.js +24 -0
  154. package/src/structures/OAuth2Application.js +148 -0
  155. package/src/structures/PartialGuild.js +51 -0
  156. package/src/structures/PartialGuildChannel.js +44 -0
  157. package/src/structures/PermissionOverwrites.js +69 -0
  158. package/src/structures/Presence.js +241 -0
  159. package/src/structures/ReactionCollector.js +85 -0
  160. package/src/structures/ReactionEmoji.js +49 -0
  161. package/src/structures/RichEmbed.js +295 -0
  162. package/src/structures/Role.js +376 -0
  163. package/src/structures/StoreChannel.js +25 -0
  164. package/src/structures/TextChannel.js +154 -0
  165. package/src/structures/User.js +329 -0
  166. package/src/structures/UserConnection.js +48 -0
  167. package/src/structures/UserProfile.js +62 -0
  168. package/src/structures/VoiceChannel.js +146 -0
  169. package/src/structures/VoiceRegion.js +50 -0
  170. package/src/structures/Webhook.js +304 -0
  171. package/src/structures/interfaces/Collector.js +179 -0
  172. package/src/structures/interfaces/TextBasedChannel.js +635 -0
  173. package/src/structures/shared/resolvePermissions.js +26 -0
  174. package/src/util/Collection.js +532 -0
  175. package/src/util/Constants.js +845 -0
  176. package/src/util/Permissions.js +306 -0
  177. package/src/util/Snowflake.js +82 -0
  178. package/src/util/Util.js +221 -0
  179. package/test/random.js +207 -0
  180. package/test/shard.js +31 -0
  181. package/test/sharder.js +7 -0
  182. package/test/voice.js +78 -0
  183. package/test/webpack.html +31 -0
  184. package/tsconfig.json +13 -0
  185. package/tslint.json +62 -0
  186. package/typings/discord.js-test.ts +69 -0
  187. package/typings/index.d.ts +2190 -0
  188. package/webpack.config.js +62 -0
@@ -0,0 +1,1006 @@
1
+ const querystring = require('querystring');
2
+ const long = require('long');
3
+ const Permissions = require('../../util/Permissions');
4
+ const Constants = require('../../util/Constants');
5
+ const Endpoints = Constants.Endpoints;
6
+ const Collection = require('../../util/Collection');
7
+ const Util = require('../../util/Util');
8
+ const resolvePermissions = require('../../structures/shared/resolvePermissions');
9
+
10
+ const RichEmbed = require('../../structures/RichEmbed');
11
+ const User = require('../../structures/User');
12
+ const GuildMember = require('../../structures/GuildMember');
13
+ const Message = require('../../structures/Message');
14
+ const Role = require('../../structures/Role');
15
+ const Invite = require('../../structures/Invite');
16
+ const Webhook = require('../../structures/Webhook');
17
+ const UserProfile = require('../../structures/UserProfile');
18
+ const OAuth2Application = require('../../structures/OAuth2Application');
19
+ const Channel = require('../../structures/Channel');
20
+ const GroupDMChannel = require('../../structures/GroupDMChannel');
21
+ const Guild = require('../../structures/Guild');
22
+ const VoiceRegion = require('../../structures/VoiceRegion');
23
+ const GuildAuditLogs = require('../../structures/GuildAuditLogs');
24
+
25
+ class RESTMethods {
26
+ constructor(restManager) {
27
+ this.rest = restManager;
28
+ this.client = restManager.client;
29
+ this._ackToken = null;
30
+ }
31
+
32
+ login(token = this.client.token) {
33
+ return new Promise((resolve, reject) => {
34
+ if (!token || typeof token !== 'string') throw new Error(Constants.Errors.INVALID_TOKEN);
35
+ token = token.replace(/^Bot\s*/i, '');
36
+ this.client.manager.connectToWebSocket(token, resolve, reject);
37
+ }).catch(e => {
38
+ this.client.destroy();
39
+ return Promise.reject(e);
40
+ });
41
+ }
42
+
43
+ logout() {
44
+ return this.rest.makeRequest('post', Endpoints.logout, true, {});
45
+ }
46
+
47
+ getGateway(bot = false) {
48
+ return this.rest.makeRequest('get', bot ? Endpoints.gateway.bot : Endpoints.gateway, true);
49
+ }
50
+
51
+ fetchVoiceRegions(guildID) {
52
+ let endpoint;
53
+ if (guildID) endpoint = Endpoints.Guild(guildID).voiceRegions;
54
+ else endpoint = Endpoints.voiceRegions;
55
+ return this.rest.makeRequest('get', endpoint, true).then(res => {
56
+ const regions = new Collection();
57
+ for (const region of res) regions.set(region.id, new VoiceRegion(region));
58
+ return regions;
59
+ });
60
+ }
61
+
62
+ fetchEmbed(guildID) {
63
+ return this.rest.makeRequest('get', Endpoints.Guild(guildID).embed, true).then(data => ({
64
+ enabled: data.enabled,
65
+ channel: data.channel_id ? this.client.channels.get(data.channel_id) : null,
66
+ }));
67
+ }
68
+
69
+ sendMessage(channel, content, { tts, nonce, embed, disableEveryone, split, code, reply } = {}, files = null) {
70
+ return new Promise((resolve, reject) => { // eslint-disable-line complexity
71
+ if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content);
72
+
73
+ // The nonce has to be a uint64 :<
74
+ if (typeof nonce !== 'undefined') {
75
+ nonce = parseInt(nonce);
76
+ if (isNaN(nonce) || nonce < 0) throw new RangeError('Message nonce must fit in an unsigned 64-bit integer.');
77
+ }
78
+
79
+ if (content) {
80
+ if (split && typeof split !== 'object') split = {};
81
+
82
+ // Wrap everything in a code block
83
+ if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) {
84
+ content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
85
+ content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``;
86
+ if (split) {
87
+ split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`;
88
+ split.append = '\n```';
89
+ }
90
+ }
91
+
92
+ // Add zero-width spaces to @everyone/@here
93
+ if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) {
94
+ content = content.replace(/@(everyone|here)/g, '@\u200b$1');
95
+ }
96
+
97
+ // Add the reply prefix
98
+ if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
99
+ const id = this.client.resolver.resolveUserID(reply);
100
+ const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
101
+ content = `${mention}${content ? `, ${content}` : ''}`;
102
+ if (split) split.prepend = `${mention}, ${split.prepend || ''}`;
103
+ }
104
+
105
+ // Split the content
106
+ if (split) content = Util.splitMessage(content, split);
107
+ } else if (reply && !(channel instanceof User || channel instanceof GuildMember) && channel.type !== 'dm') {
108
+ const id = this.client.resolver.resolveUserID(reply);
109
+ content = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
110
+ }
111
+
112
+ const send = chan => {
113
+ if (content instanceof Array) {
114
+ const messages = [];
115
+ (function sendChunk(list, index) {
116
+ const options = index === list.length - 1 ? { tts, embed, files } : { tts };
117
+ chan.send(list[index], options).then(message => {
118
+ messages.push(message);
119
+ if (index >= list.length - 1) return resolve(messages);
120
+ return sendChunk(list, ++index);
121
+ }).catch(reject);
122
+ }(content, 0));
123
+ } else {
124
+ this.rest.makeRequest('post', Endpoints.Channel(chan).messages, true, {
125
+ content, tts, nonce, embed,
126
+ }, files).then(data => resolve(this.client.actions.MessageCreate.handle(data).message), reject);
127
+ }
128
+ };
129
+
130
+ if (channel instanceof User || channel instanceof GuildMember) this.createDM(channel).then(send, reject);
131
+ else send(channel);
132
+ });
133
+ }
134
+
135
+ updateMessage(message, content, { embed, code, reply } = {}) {
136
+ if (typeof content !== 'undefined') content = this.client.resolver.resolveString(content);
137
+
138
+ // Wrap everything in a code block
139
+ if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) {
140
+ content = Util.escapeMarkdown(this.client.resolver.resolveString(content), true);
141
+ content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``;
142
+ }
143
+
144
+ // Add the reply prefix
145
+ if (reply && message.channel.type !== 'dm') {
146
+ const id = this.client.resolver.resolveUserID(reply);
147
+ const mention = `<@${reply instanceof GuildMember && reply.nickname ? '!' : ''}${id}>`;
148
+ content = `${mention}${content ? `, ${content}` : ''}`;
149
+ }
150
+
151
+ if (embed instanceof RichEmbed) embed = embed._apiTransform();
152
+
153
+ return this.rest.makeRequest('patch', Endpoints.Message(message), true, {
154
+ content, embed,
155
+ }).then(data => this.client.actions.MessageUpdate.handle(data).updated);
156
+ }
157
+
158
+ deleteMessage(message) {
159
+ return this.rest.makeRequest('delete', Endpoints.Message(message), true)
160
+ .then(() =>
161
+ this.client.actions.MessageDelete.handle({
162
+ id: message.id,
163
+ channel_id: message.channel.id,
164
+ }).message
165
+ );
166
+ }
167
+
168
+ ackMessage(message) {
169
+ return this.rest.makeRequest('post', Endpoints.Message(message).ack, true, { token: this._ackToken }).then(res => {
170
+ if (res.token) this._ackToken = res.token;
171
+ return message;
172
+ });
173
+ }
174
+
175
+ ackTextChannel(channel) {
176
+ return this.rest.makeRequest('post', Endpoints.Channel(channel).Message(channel.lastMessageID).ack, true, {
177
+ token: this._ackToken,
178
+ }).then(res => {
179
+ if (res.token) this._ackToken = res.token;
180
+ return channel;
181
+ });
182
+ }
183
+
184
+ ackGuild(guild) {
185
+ return this.rest.makeRequest('post', Endpoints.Guild(guild).ack, true).then(() => guild);
186
+ }
187
+
188
+ bulkDeleteMessages(channel, messages) {
189
+ return this.rest.makeRequest('post', Endpoints.Channel(channel).messages.bulkDelete, true, {
190
+ messages: messages,
191
+ }).then(() =>
192
+ this.client.actions.MessageDeleteBulk.handle({
193
+ channel_id: channel.id,
194
+ ids: messages,
195
+ }).messages
196
+ );
197
+ }
198
+
199
+ search(target, options) {
200
+ if (typeof options === 'string') options = { content: options };
201
+ if (options.before) {
202
+ if (!(options.before instanceof Date)) options.before = new Date(options.before);
203
+ options.maxID = long.fromNumber(options.before.getTime() - 14200704e5).shiftLeft(22).toString();
204
+ }
205
+ if (options.after) {
206
+ if (!(options.after instanceof Date)) options.after = new Date(options.after);
207
+ options.minID = long.fromNumber(options.after.getTime() - 14200704e5).shiftLeft(22).toString();
208
+ }
209
+ if (options.during) {
210
+ if (!(options.during instanceof Date)) options.during = new Date(options.during);
211
+ const t = options.during.getTime() - 14200704e5;
212
+ options.minID = long.fromNumber(t).shiftLeft(22).toString();
213
+ options.maxID = long.fromNumber(t + 86400000).shiftLeft(22).toString();
214
+ }
215
+ if (options.channel) options.channel = this.client.resolver.resolveChannelID(options.channel);
216
+ if (options.author) options.author = this.client.resolver.resolveUserID(options.author);
217
+ if (options.mentions) options.mentions = this.client.resolver.resolveUserID(options.options.mentions);
218
+ options = {
219
+ content: options.content,
220
+ max_id: options.maxID,
221
+ min_id: options.minID,
222
+ has: options.has,
223
+ channel_id: options.channel,
224
+ author_id: options.author,
225
+ author_type: options.authorType,
226
+ context_size: options.contextSize,
227
+ sort_by: options.sortBy,
228
+ sort_order: options.sortOrder,
229
+ limit: options.limit,
230
+ offset: options.offset,
231
+ mentions: options.mentions,
232
+ mentions_everyone: options.mentionsEveryone,
233
+ link_hostname: options.linkHostname,
234
+ embed_provider: options.embedProvider,
235
+ embed_type: options.embedType,
236
+ attachment_filename: options.attachmentFilename,
237
+ attachment_extension: options.attachmentExtension,
238
+ include_nsfw: options.nsfw,
239
+ };
240
+
241
+ for (const key in options) if (options[key] === undefined) delete options[key];
242
+ const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
243
+
244
+ let endpoint;
245
+ if (target instanceof Channel) {
246
+ endpoint = Endpoints.Channel(target).search;
247
+ } else if (target instanceof Guild) {
248
+ endpoint = Endpoints.Guild(target).search;
249
+ } else {
250
+ throw new TypeError('Target must be a TextChannel, DMChannel, GroupDMChannel, or Guild.');
251
+ }
252
+ return this.rest.makeRequest('get', `${endpoint}?${queryString}`, true).then(body => {
253
+ const messages = body.messages.map(x =>
254
+ x.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client))
255
+ );
256
+ return {
257
+ totalResults: body.total_results,
258
+ messages,
259
+ };
260
+ });
261
+ }
262
+
263
+ createChannel(guild, name, options) {
264
+ const {
265
+ type,
266
+ topic,
267
+ nsfw,
268
+ bitrate,
269
+ userLimit,
270
+ parent,
271
+ permissionOverwrites,
272
+ position,
273
+ rateLimitPerUser,
274
+ reason,
275
+ } = options;
276
+ return this.rest.makeRequest('post', Endpoints.Guild(guild).channels, true, {
277
+ name,
278
+ topic,
279
+ type: type ? Constants.ChannelTypes[type.toUpperCase()] : 'text',
280
+ nsfw,
281
+ bitrate,
282
+ user_limit: userLimit,
283
+ parent_id: parent instanceof Channel ? parent.id : parent,
284
+ permission_overwrites: resolvePermissions.call(this, permissionOverwrites, guild),
285
+ position,
286
+ rate_limit_per_user: rateLimitPerUser,
287
+ },
288
+ undefined,
289
+ reason).then(data => this.client.actions.ChannelCreate.handle(data).channel);
290
+ }
291
+
292
+ createDM(recipient) {
293
+ const dmChannel = this.getExistingDM(recipient);
294
+ if (dmChannel) return Promise.resolve(dmChannel);
295
+ return this.rest.makeRequest('post', Endpoints.User(this.client.user).channels, true, {
296
+ recipient_id: recipient.id,
297
+ }).then(data => this.client.actions.ChannelCreate.handle(data).channel);
298
+ }
299
+
300
+ createGroupDM(options) {
301
+ const data = this.client.user.bot ?
302
+ { access_tokens: options.accessTokens, nicks: options.nicks } :
303
+ { recipients: options.recipients };
304
+ return this.rest.makeRequest('post', Endpoints.User('@me').channels, true, data)
305
+ .then(res => new GroupDMChannel(this.client, res));
306
+ }
307
+
308
+ addUserToGroupDM(channel, options) {
309
+ const data = this.client.user.bot ?
310
+ { nick: options.nick, access_token: options.accessToken } :
311
+ { recipient: options.id };
312
+ return this.rest.makeRequest('put', Endpoints.Channel(channel).Recipient(options.id), true, data)
313
+ .then(() => channel);
314
+ }
315
+
316
+ removeUserFromGroupDM(channel, userId) {
317
+ return this.rest.makeRequest('delete', Endpoints.Channel(channel).Recipient(userId), true)
318
+ .then(() => channel);
319
+ }
320
+
321
+ updateGroupDMChannel(channel, _data) {
322
+ const data = {};
323
+ data.name = _data.name;
324
+ data.icon = _data.icon;
325
+ return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data).then(() => channel);
326
+ }
327
+
328
+ getExistingDM(recipient) {
329
+ return this.client.channels.find(channel =>
330
+ channel.recipient && channel.recipient.id === recipient.id
331
+ );
332
+ }
333
+
334
+ deleteChannel(channel, reason) {
335
+ if (channel instanceof User || channel instanceof GuildMember) channel = this.getExistingDM(channel);
336
+ if (!channel) return Promise.reject(new Error('No channel to delete.'));
337
+ return this.rest.makeRequest('delete', Endpoints.Channel(channel), true, undefined, undefined, reason)
338
+ .then(data => {
339
+ data.id = channel.id;
340
+ return this.client.actions.ChannelDelete.handle(data).channel;
341
+ });
342
+ }
343
+
344
+ updateChannel(channel, _data, reason) {
345
+ const data = {};
346
+ data.name = (_data.name || channel.name).trim();
347
+ data.topic = typeof _data.topic === 'undefined' ? channel.topic : _data.topic;
348
+ data.nsfw = typeof _data.nsfw === 'undefined' ? channel.nsfw : _data.nsfw;
349
+ data.position = _data.position || channel.position;
350
+ data.bitrate = _data.bitrate || (channel.bitrate ? channel.bitrate * 1000 : undefined);
351
+ data.user_limit = typeof _data.userLimit !== 'undefined' ? _data.userLimit : channel.userLimit;
352
+ data.parent_id = _data.parent instanceof Channel ? _data.parent.id : _data.parent;
353
+ data.permission_overwrites = _data.permissionOverwrites ?
354
+ resolvePermissions.call(this, _data.permissionOverwrites, channel.guild) : undefined;
355
+ data.rate_limit_per_user = typeof _data.rateLimitPerUser !== 'undefined' ?
356
+ _data.rateLimitPerUser : channel.rateLimitPerUser;
357
+ return this.rest.makeRequest('patch', Endpoints.Channel(channel), true, data, undefined, reason).then(newData =>
358
+ this.client.actions.ChannelUpdate.handle(newData).updated
359
+ );
360
+ }
361
+
362
+ leaveGuild(guild) {
363
+ if (guild.ownerID === this.client.user.id) return Promise.reject(new Error('Guild is owned by the client.'));
364
+ return this.rest.makeRequest('delete', Endpoints.User('@me').Guild(guild.id), true).then(() =>
365
+ this.client.actions.GuildDelete.handle({ id: guild.id }).guild
366
+ );
367
+ }
368
+
369
+ createGuild(options) {
370
+ options.icon = this.client.resolver.resolveBase64(options.icon) || null;
371
+ options.region = options.region || 'us-central';
372
+ return new Promise((resolve, reject) => {
373
+ this.rest.makeRequest('post', Endpoints.guilds, true, options).then(data => {
374
+ if (this.client.guilds.has(data.id)) return resolve(this.client.guilds.get(data.id));
375
+
376
+ const handleGuild = guild => {
377
+ if (guild.id === data.id) {
378
+ this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild);
379
+ this.client.clearTimeout(timeout);
380
+ resolve(guild);
381
+ }
382
+ };
383
+ this.client.on(Constants.Events.GUILD_CREATE, handleGuild);
384
+
385
+ const timeout = this.client.setTimeout(() => {
386
+ this.client.removeListener(Constants.Events.GUILD_CREATE, handleGuild);
387
+ reject(new Error('Took too long to receive guild data.'));
388
+ }, 10000);
389
+ return undefined;
390
+ }, reject);
391
+ });
392
+ }
393
+
394
+ // Untested but probably will work
395
+ deleteGuild(guild) {
396
+ return this.rest.makeRequest('delete', Endpoints.Guild(guild), true).then(() =>
397
+ this.client.actions.GuildDelete.handle({ id: guild.id }).guild
398
+ );
399
+ }
400
+
401
+ getUser(userID, cache) {
402
+ return this.rest.makeRequest('get', Endpoints.User(userID), true).then(data => {
403
+ if (cache) return this.client.actions.UserGet.handle(data).user;
404
+ else return new User(this.client, data);
405
+ });
406
+ }
407
+
408
+ updateCurrentUser(_data, password) {
409
+ const user = this.client.user;
410
+ const data = {};
411
+ data.username = _data.username || user.username;
412
+ data.avatar = typeof _data.avatar === 'undefined' ? user.avatar : this.client.resolver.resolveBase64(_data.avatar);
413
+ if (!user.bot) {
414
+ data.email = _data.email || user.email;
415
+ data.password = password;
416
+ if (_data.new_password) data.new_password = _data.newPassword;
417
+ }
418
+ return this.rest.makeRequest('patch', Endpoints.User('@me'), true, data).then(newData =>
419
+ this.client.actions.UserUpdate.handle(newData).updated
420
+ );
421
+ }
422
+
423
+ updateGuild(guild, data, reason) {
424
+ return this.rest.makeRequest('patch', Endpoints.Guild(guild), true, data, undefined, reason).then(newData =>
425
+ this.client.actions.GuildUpdate.handle(newData).updated
426
+ );
427
+ }
428
+
429
+ kickGuildMember(guild, member, reason) {
430
+ return this.rest.makeRequest(
431
+ 'delete', Endpoints.Guild(guild).Member(member), true,
432
+ undefined, undefined, reason)
433
+ .then(() => member);
434
+ }
435
+
436
+ createGuildRole(guild, data, reason) {
437
+ if (data.color) data.color = this.client.resolver.resolveColor(data.color);
438
+ if (data.permissions) data.permissions = Permissions.resolve(data.permissions);
439
+ return this.rest.makeRequest('post', Endpoints.Guild(guild).roles, true, data, undefined, reason).then(r => {
440
+ const { role } = this.client.actions.GuildRoleCreate.handle({
441
+ guild_id: guild.id,
442
+ role: r,
443
+ });
444
+ if (data.position) return role.setPosition(data.position, reason);
445
+ return role;
446
+ });
447
+ }
448
+
449
+ deleteGuildRole(role, reason) {
450
+ return this.rest.makeRequest(
451
+ 'delete', Endpoints.Guild(role.guild).Role(role.id), true,
452
+ undefined, undefined, reason)
453
+ .then(() =>
454
+ this.client.actions.GuildRoleDelete.handle({
455
+ guild_id: role.guild.id,
456
+ role_id: role.id,
457
+ }).role
458
+ );
459
+ }
460
+
461
+ setChannelOverwrite(channel, payload) {
462
+ return this.rest.makeRequest('put', `${Endpoints.Channel(channel).permissions}/${payload.id}`, true, payload);
463
+ }
464
+
465
+ deletePermissionOverwrites(overwrite, reason) {
466
+ return this.rest.makeRequest(
467
+ 'delete', `${Endpoints.Channel(overwrite.channel).permissions}/${overwrite.id}`,
468
+ true, undefined, undefined, reason
469
+ ).then(() => overwrite);
470
+ }
471
+
472
+ getChannelMessages(channel, payload = {}) {
473
+ const params = [];
474
+ if (payload.limit) params.push(`limit=${payload.limit}`);
475
+ if (payload.around) params.push(`around=${payload.around}`);
476
+ else if (payload.before) params.push(`before=${payload.before}`);
477
+ else if (payload.after) params.push(`after=${payload.after}`);
478
+
479
+ let endpoint = Endpoints.Channel(channel).messages;
480
+ if (params.length > 0) endpoint += `?${params.join('&')}`;
481
+ return this.rest.makeRequest('get', endpoint, true);
482
+ }
483
+
484
+ getChannelMessage(channel, messageID) {
485
+ const msg = channel.messages.get(messageID);
486
+ if (msg) return Promise.resolve(msg);
487
+ return this.rest.makeRequest('get', Endpoints.Channel(channel).Message(messageID), true);
488
+ }
489
+
490
+ putGuildMember(guild, userID, options) {
491
+ options.access_token = options.accessToken;
492
+ if (options.roles) {
493
+ const roles = options.roles;
494
+ if (roles instanceof Collection || (roles instanceof Array && roles[0] instanceof Role)) {
495
+ options.roles = roles.map(role => role.id);
496
+ }
497
+ }
498
+ return this.rest.makeRequest('put', Endpoints.Guild(guild).Member(userID), true, options)
499
+ .then(data => this.client.actions.GuildMemberGet.handle(guild, data).member);
500
+ }
501
+
502
+ getGuildMember(guild, user, cache) {
503
+ return this.rest.makeRequest('get', Endpoints.Guild(guild).Member(user.id), true).then(data => {
504
+ if (cache) return this.client.actions.GuildMemberGet.handle(guild, data).member;
505
+ else return new GuildMember(guild, data);
506
+ });
507
+ }
508
+
509
+ updateGuildMember(member, data, reason) {
510
+ if (data.channel) {
511
+ const channel = this.client.resolver.resolveChannel(data.channel);
512
+ if (!channel || channel.guild.id !== member.guild.id || channel.type !== 'voice') {
513
+ return Promise.reject(new Error('Could not resolve channel to a guild voice channel.'));
514
+ }
515
+ data.channel_id = channel.id;
516
+ data.channel = undefined;
517
+ } else if (data.channel === null) {
518
+ data.channel_id = null;
519
+ data.channel = undefined;
520
+ }
521
+ if (data.roles) data.roles = data.roles.map(role => role instanceof Role ? role.id : role);
522
+
523
+ let endpoint = Endpoints.Member(member);
524
+ // Fix your endpoints, discord ;-;
525
+ if (member.id === this.client.user.id) {
526
+ const keys = Object.keys(data);
527
+ if (keys.length === 1 && keys[0] === 'nick') {
528
+ endpoint = Endpoints.Member(member).nickname;
529
+ }
530
+ }
531
+
532
+ return this.rest.makeRequest('patch', endpoint, true, data, undefined, reason).then(newData =>
533
+ member.guild._updateMember(member, newData).mem
534
+ );
535
+ }
536
+
537
+ addMemberRole(member, role, reason) {
538
+ return new Promise((resolve, reject) => {
539
+ if (member._roles.includes(role.id)) return resolve(member);
540
+
541
+ const listener = (oldMember, newMember) => {
542
+ if (newMember.id === member.id && !oldMember._roles.includes(role.id) && newMember._roles.includes(role.id)) {
543
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
544
+ resolve(newMember);
545
+ }
546
+ };
547
+
548
+ this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener);
549
+ const timeout = this.client.setTimeout(() => {
550
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
551
+ reject(new Error('Adding the role timed out.'));
552
+ }, 10e3);
553
+
554
+ return this.rest.makeRequest('put', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason)
555
+ .catch(err => {
556
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
557
+ this.client.clearTimeout(timeout);
558
+ reject(err);
559
+ });
560
+ });
561
+ }
562
+
563
+ removeMemberRole(member, role, reason) {
564
+ return new Promise((resolve, reject) => {
565
+ if (!member._roles.includes(role.id)) return resolve(member);
566
+
567
+ const listener = (oldMember, newMember) => {
568
+ if (newMember.id === member.id && oldMember._roles.includes(role.id) && !newMember._roles.includes(role.id)) {
569
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
570
+ resolve(newMember);
571
+ }
572
+ };
573
+
574
+ this.client.on(Constants.Events.GUILD_MEMBER_UPDATE, listener);
575
+ const timeout = this.client.setTimeout(() => {
576
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
577
+ reject(new Error('Removing the role timed out.'));
578
+ }, 10e3);
579
+
580
+ return this.rest.makeRequest('delete', Endpoints.Member(member).Role(role.id), true, undefined, undefined, reason)
581
+ .catch(err => {
582
+ this.client.removeListener(Constants.Events.GUILD_MEMBER_UPDATE, listener);
583
+ this.client.clearTimeout(timeout);
584
+ reject(err);
585
+ });
586
+ });
587
+ }
588
+
589
+ sendTyping(channelID) {
590
+ return this.rest.makeRequest('post', Endpoints.Channel(channelID).typing, true);
591
+ }
592
+
593
+ banGuildMember(guild, member, options) {
594
+ const id = this.client.resolver.resolveUserID(member);
595
+ if (!id) return Promise.reject(new Error('Couldn\'t resolve the user ID to ban.'));
596
+
597
+ const url = `${Endpoints.Guild(guild).bans}/${id}?${querystring.stringify(options)}`;
598
+ return this.rest.makeRequest('put', url, true).then(() => {
599
+ if (member instanceof GuildMember) return member;
600
+ const user = this.client.resolver.resolveUser(id);
601
+ if (user) {
602
+ member = this.client.resolver.resolveGuildMember(guild, user);
603
+ return member || user;
604
+ }
605
+ return id;
606
+ });
607
+ }
608
+
609
+ unbanGuildMember(guild, member, reason) {
610
+ return new Promise((resolve, reject) => {
611
+ const id = this.client.resolver.resolveUserID(member);
612
+ if (!id) throw new Error('Couldn\'t resolve the user ID to unban.');
613
+
614
+ const listener = (eGuild, eUser) => {
615
+ if (eGuild.id === guild.id && eUser.id === id) {
616
+ this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
617
+ this.client.clearTimeout(timeout);
618
+ resolve(eUser);
619
+ }
620
+ };
621
+ this.client.on(Constants.Events.GUILD_BAN_REMOVE, listener);
622
+
623
+ const timeout = this.client.setTimeout(() => {
624
+ this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
625
+ reject(new Error('Took too long to receive the ban remove event.'));
626
+ }, 10000);
627
+
628
+ this.rest.makeRequest('delete', `${Endpoints.Guild(guild).bans}/${id}`, true, undefined, undefined, reason)
629
+ .catch(err => {
630
+ this.client.removeListener(Constants.Events.GUILD_BAN_REMOVE, listener);
631
+ this.client.clearTimeout(timeout);
632
+ reject(err);
633
+ });
634
+ });
635
+ }
636
+
637
+ getGuildBan(guild, user) {
638
+ const id = this.client.resolver.resolveUserID(user);
639
+ return this.rest.makeRequest('get', `${Endpoints.Guild(guild).bans}/${id}`, true).then(ban => ({
640
+ reason: ban.reason,
641
+ user: this.client.dataManager.newUser(ban.user),
642
+ }));
643
+ }
644
+
645
+ getGuildBans(guild) {
646
+ return this.rest.makeRequest('get', Endpoints.Guild(guild).bans, true).then(bans =>
647
+ bans.reduce((collection, ban) => {
648
+ collection.set(ban.user.id, {
649
+ reason: ban.reason,
650
+ user: this.client.dataManager.newUser(ban.user),
651
+ });
652
+ return collection;
653
+ }, new Collection())
654
+ );
655
+ }
656
+
657
+ updateGuildRole(role, _data, reason) {
658
+ const data = {};
659
+ data.name = _data.name || role.name;
660
+ data.position = typeof _data.position !== 'undefined' ? _data.position : role.position;
661
+ data.color = _data.color === null ? null : this.client.resolver.resolveColor(_data.color || role.color);
662
+ data.hoist = typeof _data.hoist !== 'undefined' ? _data.hoist : role.hoist;
663
+ data.mentionable = typeof _data.mentionable !== 'undefined' ? _data.mentionable : role.mentionable;
664
+
665
+ if (typeof _data.permissions !== 'undefined') data.permissions = Permissions.resolve(_data.permissions);
666
+ else data.permissions = role.permissions;
667
+
668
+ return this.rest.makeRequest('patch', Endpoints.Guild(role.guild).Role(role.id), true, data, undefined, reason)
669
+ .then(_role =>
670
+ this.client.actions.GuildRoleUpdate.handle({
671
+ role: _role,
672
+ guild_id: role.guild.id,
673
+ }).updated
674
+ );
675
+ }
676
+
677
+ pinMessage(message) {
678
+ return this.rest.makeRequest('put', Endpoints.Channel(message.channel).Pin(message.id), true)
679
+ .then(() => message);
680
+ }
681
+
682
+ unpinMessage(message) {
683
+ return this.rest.makeRequest('delete', Endpoints.Channel(message.channel).Pin(message.id), true)
684
+ .then(() => message);
685
+ }
686
+
687
+ getChannelPinnedMessages(channel) {
688
+ return this.rest.makeRequest('get', Endpoints.Channel(channel).pins, true);
689
+ }
690
+
691
+ createChannelInvite(channel, options, reason) {
692
+ const payload = {};
693
+ payload.temporary = options.temporary;
694
+ payload.max_age = options.maxAge;
695
+ payload.max_uses = options.maxUses;
696
+ payload.unique = options.unique;
697
+ return this.rest.makeRequest('post', Endpoints.Channel(channel).invites, true, payload, undefined, reason)
698
+ .then(invite => new Invite(this.client, invite));
699
+ }
700
+
701
+ deleteInvite(invite, reason) {
702
+ return this.rest.makeRequest('delete', Endpoints.Invite(invite.code), true, undefined, undefined, reason)
703
+ .then(() => invite);
704
+ }
705
+
706
+ getInvite(code) {
707
+ return this.rest.makeRequest('get', Endpoints.Invite(code), true).then(invite =>
708
+ new Invite(this.client, invite)
709
+ );
710
+ }
711
+
712
+ getGuildInvites(guild) {
713
+ return this.rest.makeRequest('get', Endpoints.Guild(guild).invites, true).then(inviteItems => {
714
+ const invites = new Collection();
715
+ for (const inviteItem of inviteItems) {
716
+ const invite = new Invite(this.client, inviteItem);
717
+ invites.set(invite.code, invite);
718
+ }
719
+ return invites;
720
+ });
721
+ }
722
+
723
+ getGuildVanityCode(guild) {
724
+ return this.rest.makeRequest('get', Endpoints.Guild(guild).vanityURL, true)
725
+ .then(res => res.code);
726
+ }
727
+
728
+ pruneGuildMembers(guild, days, dry, reason) {
729
+ return this.rest.makeRequest(dry ?
730
+ 'get' :
731
+ 'post',
732
+ `${Endpoints.Guild(guild).prune}?days=${days}`, true, undefined, undefined, reason)
733
+ .then(data => data.pruned);
734
+ }
735
+
736
+ createEmoji(guild, image, name, roles, reason) {
737
+ const data = { image, name };
738
+ if (roles) data.roles = roles.map(r => r.id ? r.id : r);
739
+ return this.rest.makeRequest('post', Endpoints.Guild(guild).emojis, true, data, undefined, reason)
740
+ .then(emoji => this.client.actions.GuildEmojiCreate.handle(guild, emoji).emoji);
741
+ }
742
+
743
+ updateEmoji(emoji, _data, reason) {
744
+ const data = {};
745
+ if (_data.name) data.name = _data.name;
746
+ if (_data.roles) data.roles = _data.roles.map(r => r.id ? r.id : r);
747
+ return this.rest.makeRequest('patch', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, data, undefined, reason)
748
+ .then(newEmoji => this.client.actions.GuildEmojiUpdate.handle(emoji, newEmoji).emoji);
749
+ }
750
+
751
+ deleteEmoji(emoji, reason) {
752
+ return this.rest.makeRequest('delete', Endpoints.Guild(emoji.guild).Emoji(emoji.id), true, undefined, reason)
753
+ .then(() => this.client.actions.GuildEmojiDelete.handle(emoji).data);
754
+ }
755
+
756
+ getGuildAuditLogs(guild, options = {}) {
757
+ if (options.before && options.before instanceof GuildAuditLogs.Entry) options.before = options.before.id;
758
+ if (options.after && options.after instanceof GuildAuditLogs.Entry) options.after = options.after.id;
759
+ if (typeof options.type === 'string') options.type = GuildAuditLogs.Actions[options.type];
760
+
761
+ const queryString = (querystring.stringify({
762
+ before: options.before,
763
+ after: options.after,
764
+ limit: options.limit,
765
+ user_id: this.client.resolver.resolveUserID(options.user),
766
+ action_type: options.type,
767
+ }).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
768
+
769
+ return this.rest.makeRequest('get', `${Endpoints.Guild(guild).auditLogs}?${queryString}`, true)
770
+ .then(data => GuildAuditLogs.build(guild, data));
771
+ }
772
+
773
+ getWebhook(id, token) {
774
+ return this.rest.makeRequest('get', Endpoints.Webhook(id, token), !token).then(data =>
775
+ new Webhook(this.client, data)
776
+ );
777
+ }
778
+
779
+ getGuildWebhooks(guild) {
780
+ return this.rest.makeRequest('get', Endpoints.Guild(guild).webhooks, true).then(data => {
781
+ const hooks = new Collection();
782
+ for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
783
+ return hooks;
784
+ });
785
+ }
786
+
787
+ getChannelWebhooks(channel) {
788
+ return this.rest.makeRequest('get', Endpoints.Channel(channel).webhooks, true).then(data => {
789
+ const hooks = new Collection();
790
+ for (const hook of data) hooks.set(hook.id, new Webhook(this.client, hook));
791
+ return hooks;
792
+ });
793
+ }
794
+
795
+ createWebhook(channel, name, avatar, reason) {
796
+ return this.rest.makeRequest('post', Endpoints.Channel(channel).webhooks, true, { name, avatar }, undefined, reason)
797
+ .then(data => new Webhook(this.client, data));
798
+ }
799
+
800
+ editWebhook(webhook, name, avatar) {
801
+ return this.rest.makeRequest('patch', Endpoints.Webhook(webhook.id, webhook.token), false, {
802
+ name,
803
+ avatar,
804
+ }).then(data => {
805
+ webhook.name = data.name;
806
+ webhook.avatar = data.avatar;
807
+ return webhook;
808
+ });
809
+ }
810
+
811
+ deleteWebhook(webhook, reason) {
812
+ return this.rest.makeRequest(
813
+ 'delete', Endpoints.Webhook(webhook.id, webhook.token),
814
+ false, undefined, undefined, reason);
815
+ }
816
+
817
+ sendWebhookMessage(webhook, content, { avatarURL, tts, embeds, username } = {}, files = null) {
818
+ return new Promise((resolve, reject) => {
819
+ username = username || webhook.name;
820
+
821
+ if (content instanceof Array) {
822
+ const messages = [];
823
+ (function sendChunk(list, index) {
824
+ const options = index === list.length - 1 ? { tts, embeds, files } : { tts };
825
+ webhook.send(list[index], options).then(message => {
826
+ messages.push(message);
827
+ if (index >= list.length - 1) return resolve(messages);
828
+ return sendChunk(list, ++index);
829
+ }).catch(reject);
830
+ }(content, 0));
831
+ } else {
832
+ this.rest.makeRequest('post', `${Endpoints.Webhook(webhook.id, webhook.token)}?wait=true`, false, {
833
+ username,
834
+ avatar_url: avatarURL,
835
+ content,
836
+ tts,
837
+ embeds,
838
+ }, files).then(data => {
839
+ if (!this.client.channels) resolve(data);
840
+ else resolve(this.client.actions.MessageCreate.handle(data).message);
841
+ }, reject);
842
+ }
843
+ });
844
+ }
845
+
846
+ sendSlackWebhookMessage(webhook, body) {
847
+ return this.rest.makeRequest(
848
+ 'post', `${Endpoints.Webhook(webhook.id, webhook.token)}/slack?wait=true`, false, body
849
+ );
850
+ }
851
+
852
+ fetchUserProfile(user) {
853
+ return this.rest.makeRequest('get', Endpoints.User(user).profile, true).then(data =>
854
+ new UserProfile(user, data)
855
+ );
856
+ }
857
+
858
+ fetchMentions(options) {
859
+ if (options.guild instanceof Guild) options.guild = options.guild.id;
860
+ Util.mergeDefault({ limit: 25, roles: true, everyone: true, guild: null }, options);
861
+
862
+ return this.rest.makeRequest(
863
+ 'get', Endpoints.User('@me').Mentions(options.limit, options.roles, options.everyone, options.guild), true
864
+ ).then(data => data.map(m => new Message(this.client.channels.get(m.channel_id), m, this.client)));
865
+ }
866
+
867
+ addFriend(user) {
868
+ return this.rest.makeRequest('post', Endpoints.User('@me'), true, {
869
+ username: user.username,
870
+ discriminator: user.discriminator,
871
+ }).then(() => user);
872
+ }
873
+
874
+ removeFriend(user) {
875
+ return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true)
876
+ .then(() => user);
877
+ }
878
+
879
+ blockUser(user) {
880
+ return this.rest.makeRequest('put', Endpoints.User('@me').Relationship(user.id), true, { type: 2 })
881
+ .then(() => user);
882
+ }
883
+
884
+ unblockUser(user) {
885
+ return this.rest.makeRequest('delete', Endpoints.User('@me').Relationship(user.id), true)
886
+ .then(() => user);
887
+ }
888
+
889
+ updateChannelPositions(guildID, channels) {
890
+ const data = new Array(channels.length);
891
+ for (let i = 0; i < channels.length; i++) {
892
+ data[i] = {
893
+ id: this.client.resolver.resolveChannelID(channels[i].channel),
894
+ position: channels[i].position,
895
+ };
896
+ }
897
+
898
+ return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, data).then(() =>
899
+ this.client.actions.GuildChannelsPositionUpdate.handle({
900
+ guild_id: guildID,
901
+ channels,
902
+ }).guild
903
+ );
904
+ }
905
+
906
+ updateEmbed(guildID, embed, reason) {
907
+ return this.rest.makeRequest('patch', Endpoints.Guild(guildID).embed, true, {
908
+ enabled: embed.enabled,
909
+ channel_id: this.client.resolver.resolveChannelID(embed.channel),
910
+ }, undefined, reason);
911
+ }
912
+
913
+ setRolePositions(guildID, roles) {
914
+ return this.rest.makeRequest('patch', Endpoints.Guild(guildID).roles, true, roles).then(() =>
915
+ this.client.actions.GuildRolesPositionUpdate.handle({
916
+ guild_id: guildID,
917
+ roles,
918
+ }).guild
919
+ );
920
+ }
921
+
922
+ setChannelPositions(guildID, channels) {
923
+ return this.rest.makeRequest('patch', Endpoints.Guild(guildID).channels, true, channels).then(() =>
924
+ this.client.actions.GuildChannelsPositionUpdate.handle({
925
+ guild_id: guildID,
926
+ channels,
927
+ }).guild
928
+ );
929
+ }
930
+
931
+ addMessageReaction(message, emoji) {
932
+ return this.rest.makeRequest(
933
+ 'put', Endpoints.Message(message).Reaction(emoji).User('@me'), true
934
+ ).then(() =>
935
+ message._addReaction(Util.parseEmoji(emoji), message.client.user)
936
+ );
937
+ }
938
+
939
+ removeMessageReaction(message, emoji, userID) {
940
+ const endpoint = Endpoints.Message(message).Reaction(emoji).User(userID === this.client.user.id ? '@me' : userID);
941
+ return this.rest.makeRequest('delete', endpoint, true).then(() =>
942
+ this.client.actions.MessageReactionRemove.handle({
943
+ user_id: userID,
944
+ message_id: message.id,
945
+ emoji: Util.parseEmoji(emoji),
946
+ channel_id: message.channel.id,
947
+ }).reaction
948
+ );
949
+ }
950
+
951
+ removeMessageReactions(message) {
952
+ return this.rest.makeRequest('delete', Endpoints.Message(message).reactions, true)
953
+ .then(() => message);
954
+ }
955
+
956
+ getMessageReactionUsers(message, emoji, options) {
957
+ const queryString = (querystring.stringify(options).match(/[^=&?]+=[^=&?]+/g) || []).join('&');
958
+
959
+ return this.rest.makeRequest('get', `${Endpoints.Message(message).Reaction(emoji)}?${queryString}`, true);
960
+ }
961
+
962
+ getApplication(id) {
963
+ return this.rest.makeRequest('get', Endpoints.OAUTH2.Application(id), true).then(app =>
964
+ new OAuth2Application(this.client, app)
965
+ );
966
+ }
967
+
968
+ resetApplication(id) {
969
+ return this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetToken, true)
970
+ .then(() => this.rest.makeRequest('post', Endpoints.OAUTH2.Application(id).resetSecret, true))
971
+ .then(app => new OAuth2Application(this.client, app));
972
+ }
973
+
974
+ setNote(user, note) {
975
+ return this.rest.makeRequest('put', Endpoints.User(user).note, true, { note }).then(() => user);
976
+ }
977
+
978
+ acceptInvite(code) {
979
+ if (code.id) code = code.id;
980
+ return new Promise((resolve, reject) =>
981
+ this.rest.makeRequest('post', Endpoints.Invite(code), true).then(res => {
982
+ const handler = guild => {
983
+ if (guild.id === res.id) {
984
+ resolve(guild);
985
+ this.client.removeListener(Constants.Events.GUILD_CREATE, handler);
986
+ }
987
+ };
988
+ this.client.on(Constants.Events.GUILD_CREATE, handler);
989
+ this.client.setTimeout(() => {
990
+ this.client.removeListener(Constants.Events.GUILD_CREATE, handler);
991
+ reject(new Error('Accepting invite timed out'));
992
+ }, 120e3);
993
+ })
994
+ );
995
+ }
996
+
997
+ patchUserSettings(data) {
998
+ return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').settings, true, data);
999
+ }
1000
+
1001
+ patchClientUserGuildSettings(guildID, data) {
1002
+ return this.rest.makeRequest('patch', Constants.Endpoints.User('@me').Guild(guildID).settings, true, data);
1003
+ }
1004
+ }
1005
+
1006
+ module.exports = RESTMethods;