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,146 @@
|
|
1
|
+
const GuildChannel = require('./GuildChannel');
|
2
|
+
const Collection = require('../util/Collection');
|
3
|
+
const Permissions = require('../util/Permissions');
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Represents a guild voice channel on Discord.
|
7
|
+
* @extends {GuildChannel}
|
8
|
+
*/
|
9
|
+
class VoiceChannel extends GuildChannel {
|
10
|
+
constructor(guild, data) {
|
11
|
+
super(guild, data);
|
12
|
+
|
13
|
+
/**
|
14
|
+
* The members in this voice channel
|
15
|
+
* @type {Collection<Snowflake, GuildMember>}
|
16
|
+
*/
|
17
|
+
this.members = new Collection();
|
18
|
+
|
19
|
+
this.type = 'voice';
|
20
|
+
}
|
21
|
+
|
22
|
+
setup(data) {
|
23
|
+
super.setup(data);
|
24
|
+
|
25
|
+
/**
|
26
|
+
* The bitrate of this voice channel
|
27
|
+
* @type {number}
|
28
|
+
*/
|
29
|
+
this.bitrate = data.bitrate * 0.001;
|
30
|
+
|
31
|
+
/**
|
32
|
+
* The maximum amount of users allowed in this channel - 0 means unlimited.
|
33
|
+
* @type {number}
|
34
|
+
*/
|
35
|
+
this.userLimit = data.user_limit;
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* The voice connection for this voice channel, if the client is connected
|
40
|
+
* @type {?VoiceConnection}
|
41
|
+
* @readonly
|
42
|
+
*/
|
43
|
+
get connection() {
|
44
|
+
const connection = this.guild.voiceConnection;
|
45
|
+
if (connection && connection.channel.id === this.id) return connection;
|
46
|
+
return null;
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Checks if the voice channel is full
|
51
|
+
* @type {boolean}
|
52
|
+
* @readonly
|
53
|
+
*/
|
54
|
+
get full() {
|
55
|
+
return this.userLimit > 0 && this.members.size >= this.userLimit;
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Whether the channel is deletable by the client user
|
60
|
+
* @type {boolean}
|
61
|
+
* @readonly
|
62
|
+
*/
|
63
|
+
get deletable() {
|
64
|
+
return super.deletable && this.permissionsFor(this.client.user).has(Permissions.FLAGS.CONNECT);
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Checks if the client has permission join the voice channel
|
69
|
+
* @type {boolean}
|
70
|
+
* @readonly
|
71
|
+
*/
|
72
|
+
get joinable() {
|
73
|
+
if (this.client.browser) return false;
|
74
|
+
if (!this.permissionsFor(this.client.user).has('CONNECT')) return false;
|
75
|
+
if (this.full && !this.permissionsFor(this.client.user).has('MOVE_MEMBERS')) return false;
|
76
|
+
return true;
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Checks if the client has permission to send audio to the voice channel
|
81
|
+
* @type {boolean}
|
82
|
+
* @readonly
|
83
|
+
*/
|
84
|
+
get speakable() {
|
85
|
+
return this.permissionsFor(this.client.user).has('SPEAK');
|
86
|
+
}
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Sets the bitrate of the channel (in kbps).
|
90
|
+
* @param {number} bitrate The new bitrate
|
91
|
+
* @param {string} [reason] Reason for changing the channel's bitrate
|
92
|
+
* @returns {Promise<VoiceChannel>}
|
93
|
+
* @example
|
94
|
+
* // Set the bitrate of a voice channel
|
95
|
+
* voiceChannel.setBitrate(48)
|
96
|
+
* .then(vc => console.log(`Set bitrate to ${vc.bitrate}kbps for ${vc.name}`))
|
97
|
+
* .catch(console.error);
|
98
|
+
*/
|
99
|
+
setBitrate(bitrate, reason) {
|
100
|
+
bitrate *= 1000;
|
101
|
+
return this.edit({ bitrate }, reason);
|
102
|
+
}
|
103
|
+
|
104
|
+
/**
|
105
|
+
* Sets the user limit of the channel.
|
106
|
+
* @param {number} userLimit The new user limit
|
107
|
+
* @param {string} [reason] Reason for changing the user limit
|
108
|
+
* @returns {Promise<VoiceChannel>}
|
109
|
+
* @example
|
110
|
+
* // Set the user limit of a voice channel
|
111
|
+
* voiceChannel.setUserLimit(42)
|
112
|
+
* .then(vc => console.log(`Set user limit to ${vc.userLimit} for ${vc.name}`))
|
113
|
+
* .catch(console.error);
|
114
|
+
*/
|
115
|
+
setUserLimit(userLimit, reason) {
|
116
|
+
return this.edit({ userLimit }, reason);
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Attempts to join this voice channel.
|
121
|
+
* @returns {Promise<VoiceConnection>}
|
122
|
+
* @example
|
123
|
+
* // Join a voice channel
|
124
|
+
* voiceChannel.join()
|
125
|
+
* .then(connection => console.log('Connected!'))
|
126
|
+
* .catch(console.error);
|
127
|
+
*/
|
128
|
+
join() {
|
129
|
+
if (this.client.browser) return Promise.reject(new Error('Voice connections are not available in browsers.'));
|
130
|
+
return this.client.voice.joinChannel(this);
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Leaves this voice channel.
|
135
|
+
* @example
|
136
|
+
* // Leave a voice channel
|
137
|
+
* voiceChannel.leave();
|
138
|
+
*/
|
139
|
+
leave() {
|
140
|
+
if (this.client.browser) return;
|
141
|
+
const connection = this.client.voice.connections.get(this.guild.id);
|
142
|
+
if (connection && connection.channel.id === this.id) connection.disconnect();
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
module.exports = VoiceChannel;
|
@@ -0,0 +1,50 @@
|
|
1
|
+
/**
|
2
|
+
* Represents a Discord voice region for guilds.
|
3
|
+
*/
|
4
|
+
class VoiceRegion {
|
5
|
+
constructor(data) {
|
6
|
+
/**
|
7
|
+
* The ID of the region
|
8
|
+
* @type {string}
|
9
|
+
*/
|
10
|
+
this.id = data.id;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Name of the region
|
14
|
+
* @type {string}
|
15
|
+
*/
|
16
|
+
this.name = data.name;
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Whether the region is VIP-only
|
20
|
+
* @type {boolean}
|
21
|
+
*/
|
22
|
+
this.vip = data.vip;
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Whether the region is deprecated
|
26
|
+
* @type {boolean}
|
27
|
+
*/
|
28
|
+
this.deprecated = data.deprecated;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Whether the region is optimal
|
32
|
+
* @type {boolean}
|
33
|
+
*/
|
34
|
+
this.optimal = data.optimal;
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Whether the region is custom
|
38
|
+
* @type {boolean}
|
39
|
+
*/
|
40
|
+
this.custom = data.custom;
|
41
|
+
|
42
|
+
/**
|
43
|
+
* A sample hostname for what a connection might look like
|
44
|
+
* @type {string}
|
45
|
+
*/
|
46
|
+
this.sampleHostname = data.sample_hostname;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
module.exports = VoiceRegion;
|
@@ -0,0 +1,304 @@
|
|
1
|
+
const EventEmitter = require('events');
|
2
|
+
const path = require('path');
|
3
|
+
const Util = require('../util/Util');
|
4
|
+
const Attachment = require('./Attachment');
|
5
|
+
const RichEmbed = require('./RichEmbed');
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Represents a webhook.
|
9
|
+
*/
|
10
|
+
class Webhook extends EventEmitter {
|
11
|
+
constructor(client, dataOrID, token) {
|
12
|
+
super();
|
13
|
+
if (client) {
|
14
|
+
/**
|
15
|
+
* The client that instantiated the webhook
|
16
|
+
* @name Webhook#client
|
17
|
+
* @type {Client}
|
18
|
+
* @readonly
|
19
|
+
*/
|
20
|
+
Object.defineProperty(this, 'client', { value: client });
|
21
|
+
if (dataOrID) this.setup(dataOrID);
|
22
|
+
} else {
|
23
|
+
this.id = dataOrID;
|
24
|
+
this.token = token;
|
25
|
+
Object.defineProperty(this, 'client', { value: this });
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
setup(data) {
|
30
|
+
/**
|
31
|
+
* The name of the webhook
|
32
|
+
* @type {string}
|
33
|
+
*/
|
34
|
+
this.name = data.name;
|
35
|
+
|
36
|
+
/**
|
37
|
+
* The token for the webhook
|
38
|
+
* @name Webhook#token
|
39
|
+
* @type {string}
|
40
|
+
*/
|
41
|
+
Object.defineProperty(this, 'token', { value: data.token, writable: true, configurable: true });
|
42
|
+
|
43
|
+
/**
|
44
|
+
* The avatar for the webhook
|
45
|
+
* @type {?string}
|
46
|
+
*/
|
47
|
+
this.avatar = data.avatar;
|
48
|
+
|
49
|
+
/**
|
50
|
+
* The ID of the webhook
|
51
|
+
* @type {Snowflake}
|
52
|
+
*/
|
53
|
+
this.id = data.id;
|
54
|
+
|
55
|
+
/**
|
56
|
+
* The guild the webhook belongs to
|
57
|
+
* @type {Snowflake}
|
58
|
+
*/
|
59
|
+
this.guildID = data.guild_id;
|
60
|
+
|
61
|
+
/**
|
62
|
+
* The channel the webhook belongs to
|
63
|
+
* @type {Snowflake}
|
64
|
+
*/
|
65
|
+
this.channelID = data.channel_id;
|
66
|
+
|
67
|
+
if (data.user) {
|
68
|
+
/**
|
69
|
+
* The owner of the webhook
|
70
|
+
* @type {?User|Object}
|
71
|
+
*/
|
72
|
+
this.owner = this.client.users ? this.client.users.get(data.user.id) : data.user;
|
73
|
+
} else {
|
74
|
+
this.owner = null;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
/**
|
79
|
+
* Options that can be passed into send, sendMessage, sendFile, sendEmbed, and sendCode.
|
80
|
+
* @typedef {Object} WebhookMessageOptions
|
81
|
+
* @property {string} [username=this.name] Username override for the message
|
82
|
+
* @property {string} [avatarURL] Avatar URL override for the message
|
83
|
+
* @property {boolean} [tts=false] Whether or not the message should be spoken aloud
|
84
|
+
* @property {string} [nonce=''] The nonce for the message
|
85
|
+
* @property {Array<RichEmbed|Object>} [embeds] An array of embeds for the message
|
86
|
+
* (see [here](https://discordapp.com/developers/docs/resources/channel#embed-object) for more details)
|
87
|
+
* @property {boolean} [disableEveryone=this.client.options.disableEveryone] Whether or not @everyone and @here
|
88
|
+
* should be replaced with plain-text
|
89
|
+
* @property {FileOptions|BufferResolvable|Attachment} [file] A file to send with the message **(deprecated)**
|
90
|
+
* @property {FileOptions[]|BufferResolvable[]|Attachment[]} [files] Files to send with the message
|
91
|
+
* @property {string|boolean} [code] Language for optional codeblock formatting to apply
|
92
|
+
* @property {boolean|SplitOptions} [split=false] Whether or not the message should be split into multiple messages if
|
93
|
+
* it exceeds the character limit. If an object is provided, these are the options for splitting the message.
|
94
|
+
*/
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Send a message with this webhook.
|
98
|
+
* @param {StringResolvable} content The content to send
|
99
|
+
* @param {WebhookMessageOptions|Attachment|RichEmbed} [options] The options to provide,
|
100
|
+
* can also be just a RichEmbed or Attachment
|
101
|
+
* @returns {Promise<Message|Message[]|Object|Object[]>}
|
102
|
+
* @example
|
103
|
+
* // Send a basic message
|
104
|
+
* webhook.send('hello!')
|
105
|
+
* .then(message => console.log(`Sent message: ${message.content}`))
|
106
|
+
* .catch(console.error);
|
107
|
+
* @example
|
108
|
+
* // Send a remote file
|
109
|
+
* webhook.send({
|
110
|
+
* files: ['https://cdn.discordapp.com/icons/222078108977594368/6e1019b3179d71046e463a75915e7244.png?size=2048']
|
111
|
+
* })
|
112
|
+
* .then(console.log)
|
113
|
+
* .catch(console.error);
|
114
|
+
* @example
|
115
|
+
* // Send a local file
|
116
|
+
* webhook.send({
|
117
|
+
* files: [{
|
118
|
+
* attachment: 'entire/path/to/file.jpg',
|
119
|
+
* name: 'file.jpg'
|
120
|
+
* }]
|
121
|
+
* })
|
122
|
+
* .then(console.log)
|
123
|
+
* .catch(console.error);
|
124
|
+
* @example
|
125
|
+
* // Send an embed with a local image inside
|
126
|
+
* webhook.send('This is an embed', {
|
127
|
+
* embeds: [{
|
128
|
+
* thumbnail: {
|
129
|
+
* url: 'attachment://file.jpg'
|
130
|
+
* }
|
131
|
+
* }],
|
132
|
+
* files: [{
|
133
|
+
* attachment: 'entire/path/to/file.jpg',
|
134
|
+
* name: 'file.jpg'
|
135
|
+
* }]
|
136
|
+
* })
|
137
|
+
* .then(console.log)
|
138
|
+
* .catch(console.error);
|
139
|
+
*/
|
140
|
+
send(content, options) { // eslint-disable-line complexity
|
141
|
+
if (!options && typeof content === 'object' && !(content instanceof Array)) {
|
142
|
+
options = content;
|
143
|
+
content = '';
|
144
|
+
} else if (!options) {
|
145
|
+
options = {};
|
146
|
+
}
|
147
|
+
|
148
|
+
if (options instanceof Attachment) options = { files: [options] };
|
149
|
+
if (options instanceof RichEmbed) options = { embeds: [options] };
|
150
|
+
|
151
|
+
if (content) {
|
152
|
+
content = this.client.resolver.resolveString(content);
|
153
|
+
let { split, code, disableEveryone } = options;
|
154
|
+
if (split && typeof split !== 'object') split = {};
|
155
|
+
if (typeof code !== 'undefined' && (typeof code !== 'boolean' || code === true)) {
|
156
|
+
content = Util.escapeMarkdown(content, true);
|
157
|
+
content = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n${content}\n\`\`\``;
|
158
|
+
if (split) {
|
159
|
+
split.prepend = `\`\`\`${typeof code !== 'boolean' ? code || '' : ''}\n`;
|
160
|
+
split.append = '\n```';
|
161
|
+
}
|
162
|
+
}
|
163
|
+
if (disableEveryone || (typeof disableEveryone === 'undefined' && this.client.options.disableEveryone)) {
|
164
|
+
content = content.replace(/@(everyone|here)/g, '@\u200b$1');
|
165
|
+
}
|
166
|
+
|
167
|
+
if (split) content = Util.splitMessage(content, split);
|
168
|
+
}
|
169
|
+
|
170
|
+
if (options.file) {
|
171
|
+
if (options.files) options.files.push(options.file);
|
172
|
+
else options.files = [options.file];
|
173
|
+
}
|
174
|
+
|
175
|
+
if (options.embeds) {
|
176
|
+
const files = [];
|
177
|
+
for (const embed of options.embeds) {
|
178
|
+
if (embed.file) files.push(embed.file);
|
179
|
+
}
|
180
|
+
if (options.files) options.files.push(...files);
|
181
|
+
else options.files = files;
|
182
|
+
}
|
183
|
+
|
184
|
+
if (options.embeds) options.embeds = options.embeds.map(e => new RichEmbed(e)._apiTransform());
|
185
|
+
|
186
|
+
if (options.files) {
|
187
|
+
for (let i = 0; i < options.files.length; i++) {
|
188
|
+
let file = options.files[i];
|
189
|
+
if (typeof file === 'string' || Buffer.isBuffer(file)) file = { attachment: file };
|
190
|
+
if (!file.name) {
|
191
|
+
if (typeof file.attachment === 'string') {
|
192
|
+
file.name = path.basename(file.attachment);
|
193
|
+
} else if (file.attachment && file.attachment.path) {
|
194
|
+
file.name = path.basename(file.attachment.path);
|
195
|
+
} else if (file instanceof Attachment) {
|
196
|
+
file = { attachment: file.file, name: path.basename(file.file) || 'file.jpg' };
|
197
|
+
} else {
|
198
|
+
file.name = 'file.jpg';
|
199
|
+
}
|
200
|
+
} else if (file instanceof Attachment) {
|
201
|
+
file = file.file;
|
202
|
+
}
|
203
|
+
options.files[i] = file;
|
204
|
+
}
|
205
|
+
|
206
|
+
return Promise.all(options.files.map(file =>
|
207
|
+
this.client.resolver.resolveFile(file.attachment).then(resource => {
|
208
|
+
file.file = resource;
|
209
|
+
return file;
|
210
|
+
})
|
211
|
+
)).then(files => this.client.rest.methods.sendWebhookMessage(this, content, options, files));
|
212
|
+
}
|
213
|
+
|
214
|
+
return this.client.rest.methods.sendWebhookMessage(this, content, options);
|
215
|
+
}
|
216
|
+
|
217
|
+
/**
|
218
|
+
* Send a message with this webhook
|
219
|
+
* @param {StringResolvable} content The content to send
|
220
|
+
* @param {WebhookMessageOptions} [options={}] The options to provide
|
221
|
+
* @returns {Promise<Message|Message[]>}
|
222
|
+
* @deprecated
|
223
|
+
* @example
|
224
|
+
* // Send a message
|
225
|
+
* webhook.sendMessage('hello!')
|
226
|
+
* .then(message => console.log(`Sent message: ${message.content}`))
|
227
|
+
* .catch(console.error);
|
228
|
+
*/
|
229
|
+
sendMessage(content, options = {}) {
|
230
|
+
return this.send(content, options);
|
231
|
+
}
|
232
|
+
|
233
|
+
/**
|
234
|
+
* Send a file with this webhook.
|
235
|
+
* @param {BufferResolvable} attachment The file to send
|
236
|
+
* @param {string} [name='file.jpg'] The name and extension of the file
|
237
|
+
* @param {StringResolvable} [content] Text message to send with the attachment
|
238
|
+
* @param {WebhookMessageOptions} [options] The options to provide
|
239
|
+
* @returns {Promise<Message>}
|
240
|
+
* @deprecated
|
241
|
+
*/
|
242
|
+
sendFile(attachment, name, content, options = {}) {
|
243
|
+
return this.send(content, Object.assign(options, { file: { attachment, name } }));
|
244
|
+
}
|
245
|
+
|
246
|
+
/**
|
247
|
+
* Send a code block with this webhook.
|
248
|
+
* @param {string} lang Language for the code block
|
249
|
+
* @param {StringResolvable} content Content of the code block
|
250
|
+
* @param {WebhookMessageOptions} options The options to provide
|
251
|
+
* @returns {Promise<Message|Message[]>}
|
252
|
+
* @deprecated
|
253
|
+
*/
|
254
|
+
sendCode(lang, content, options = {}) {
|
255
|
+
return this.send(content, Object.assign(options, { code: lang }));
|
256
|
+
}
|
257
|
+
|
258
|
+
/**
|
259
|
+
* Send a raw slack message with this webhook.
|
260
|
+
* @param {Object} body The raw body to send
|
261
|
+
* @returns {Promise}
|
262
|
+
* @example
|
263
|
+
* // Send a slack message
|
264
|
+
* webhook.sendSlackMessage({
|
265
|
+
* 'username': 'Wumpus',
|
266
|
+
* 'attachments': [{
|
267
|
+
* 'pretext': 'this looks pretty cool',
|
268
|
+
* 'color': '#F0F',
|
269
|
+
* 'footer_icon': 'http://snek.s3.amazonaws.com/topSnek.png',
|
270
|
+
* 'footer': 'Powered by sneks',
|
271
|
+
* 'ts': Date.now() / 1000
|
272
|
+
* }]
|
273
|
+
* }).catch(console.error);
|
274
|
+
*/
|
275
|
+
sendSlackMessage(body) {
|
276
|
+
return this.client.rest.methods.sendSlackWebhookMessage(this, body);
|
277
|
+
}
|
278
|
+
|
279
|
+
/**
|
280
|
+
* Edit the webhook.
|
281
|
+
* @param {string} name The new name for the webhook
|
282
|
+
* @param {BufferResolvable} [avatar] The new avatar for the webhook
|
283
|
+
* @returns {Promise<Webhook>}
|
284
|
+
*/
|
285
|
+
edit(name = this.name, avatar) {
|
286
|
+
if (avatar) {
|
287
|
+
return this.client.resolver.resolveImage(avatar).then(data =>
|
288
|
+
this.client.rest.methods.editWebhook(this, name, data)
|
289
|
+
);
|
290
|
+
}
|
291
|
+
return this.client.rest.methods.editWebhook(this, name);
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* Delete the webhook.
|
296
|
+
* @param {string} [reason] Reason for deleting the webhook
|
297
|
+
* @returns {Promise}
|
298
|
+
*/
|
299
|
+
delete(reason) {
|
300
|
+
return this.client.rest.methods.deleteWebhook(this, reason);
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
module.exports = Webhook;
|
@@ -0,0 +1,179 @@
|
|
1
|
+
const Collection = require('../../util/Collection');
|
2
|
+
const EventEmitter = require('events').EventEmitter;
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Filter to be applied to the collector.
|
6
|
+
* @typedef {Function} CollectorFilter
|
7
|
+
* @param {...*} args Any arguments received by the listener
|
8
|
+
* @param {Collection} collection The items collected by this collector
|
9
|
+
* @returns {boolean}
|
10
|
+
*/
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Options to be applied to the collector.
|
14
|
+
* @typedef {Object} CollectorOptions
|
15
|
+
* @property {number} [time] How long to run the collector for
|
16
|
+
*/
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Abstract class for defining a new Collector.
|
20
|
+
* @abstract
|
21
|
+
*/
|
22
|
+
class Collector extends EventEmitter {
|
23
|
+
constructor(client, filter, options = {}) {
|
24
|
+
super();
|
25
|
+
|
26
|
+
/**
|
27
|
+
* The client
|
28
|
+
* @name Collector#client
|
29
|
+
* @type {Client}
|
30
|
+
* @readonly
|
31
|
+
*/
|
32
|
+
Object.defineProperty(this, 'client', { value: client });
|
33
|
+
|
34
|
+
/**
|
35
|
+
* The filter applied to this collector
|
36
|
+
* @type {CollectorFilter}
|
37
|
+
*/
|
38
|
+
this.filter = filter;
|
39
|
+
|
40
|
+
/**
|
41
|
+
* The options of this collector
|
42
|
+
* @type {CollectorOptions}
|
43
|
+
*/
|
44
|
+
this.options = options;
|
45
|
+
|
46
|
+
/**
|
47
|
+
* The items collected by this collector
|
48
|
+
* @type {Collection}
|
49
|
+
*/
|
50
|
+
this.collected = new Collection();
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Whether this collector has finished collecting
|
54
|
+
* @type {boolean}
|
55
|
+
*/
|
56
|
+
this.ended = false;
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Timeout for cleanup
|
60
|
+
* @type {?Timeout}
|
61
|
+
* @private
|
62
|
+
*/
|
63
|
+
this._timeout = null;
|
64
|
+
|
65
|
+
/**
|
66
|
+
* Call this to handle an event as a collectable element
|
67
|
+
* Accepts any event data as parameters
|
68
|
+
* @type {Function}
|
69
|
+
* @private
|
70
|
+
*/
|
71
|
+
this.listener = this._handle.bind(this);
|
72
|
+
if (options.time) this._timeout = this.client.setTimeout(() => this.stop('time'), options.time);
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* @param {...*} args The arguments emitted by the listener
|
77
|
+
* @emits Collector#collect
|
78
|
+
* @private
|
79
|
+
*/
|
80
|
+
_handle(...args) {
|
81
|
+
const collect = this.handle(...args);
|
82
|
+
if (!collect || !this.filter(...args, this.collected)) return;
|
83
|
+
|
84
|
+
this.collected.set(collect.key, collect.value);
|
85
|
+
|
86
|
+
/**
|
87
|
+
* Emitted whenever an element is collected.
|
88
|
+
* @event Collector#collect
|
89
|
+
* @param {*} element The element that got collected
|
90
|
+
* @param {Collector} collector The collector
|
91
|
+
*/
|
92
|
+
this.emit('collect', collect.value, this);
|
93
|
+
|
94
|
+
const post = this.postCheck(...args);
|
95
|
+
if (post) this.stop(post);
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Return a promise that resolves with the next collected element;
|
100
|
+
* rejects with collected elements if the collector finishes without receiving a next element
|
101
|
+
* @type {Promise}
|
102
|
+
* @readonly
|
103
|
+
*/
|
104
|
+
get next() {
|
105
|
+
return new Promise((resolve, reject) => {
|
106
|
+
if (this.ended) {
|
107
|
+
reject(this.collected);
|
108
|
+
return;
|
109
|
+
}
|
110
|
+
|
111
|
+
const cleanup = () => {
|
112
|
+
this.removeListener('collect', onCollect);
|
113
|
+
this.removeListener('end', onEnd);
|
114
|
+
};
|
115
|
+
|
116
|
+
const onCollect = item => {
|
117
|
+
cleanup();
|
118
|
+
resolve(item);
|
119
|
+
};
|
120
|
+
|
121
|
+
const onEnd = () => {
|
122
|
+
cleanup();
|
123
|
+
reject(this.collected); // eslint-disable-line prefer-promise-reject-errors
|
124
|
+
};
|
125
|
+
|
126
|
+
this.on('collect', onCollect);
|
127
|
+
this.on('end', onEnd);
|
128
|
+
});
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Stop this collector and emit the `end` event.
|
133
|
+
* @param {string} [reason='user'] The reason this collector is ending
|
134
|
+
* @emits Collector#end
|
135
|
+
*/
|
136
|
+
stop(reason = 'user') {
|
137
|
+
if (this.ended) return;
|
138
|
+
|
139
|
+
if (this._timeout) this.client.clearTimeout(this._timeout);
|
140
|
+
this.ended = true;
|
141
|
+
this.cleanup();
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Emitted when the collector is finished collecting.
|
145
|
+
* @event Collector#end
|
146
|
+
* @param {Collection} collected The elements collected by the collector
|
147
|
+
* @param {string} reason The reason the collector ended
|
148
|
+
*/
|
149
|
+
this.emit('end', this.collected, reason);
|
150
|
+
}
|
151
|
+
|
152
|
+
/* eslint-disable no-empty-function, valid-jsdoc */
|
153
|
+
/**
|
154
|
+
* Handles incoming events from the `listener` function. Returns null if the event should not be collected,
|
155
|
+
* or returns an object describing the data that should be stored.
|
156
|
+
* @see Collector#listener
|
157
|
+
* @param {...*} args Any args the event listener emits
|
158
|
+
* @returns {?{key: string, value}} Data to insert into collection, if any
|
159
|
+
* @abstract
|
160
|
+
*/
|
161
|
+
handle() {}
|
162
|
+
|
163
|
+
/**
|
164
|
+
* This method runs after collection to see if the collector should finish.
|
165
|
+
* @param {...*} args Any args the event listener emits
|
166
|
+
* @returns {?string} Reason to end the collector, if any
|
167
|
+
* @abstract
|
168
|
+
*/
|
169
|
+
postCheck() {}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Called when the collector is ending.
|
173
|
+
* @abstract
|
174
|
+
*/
|
175
|
+
cleanup() {}
|
176
|
+
/* eslint-enable no-empty-function, valid-jsdoc */
|
177
|
+
}
|
178
|
+
|
179
|
+
module.exports = Collector;
|