Initial commit
This commit is contained in:
115
src/client/actions/Action.js
Normal file
115
src/client/actions/Action.js
Normal file
@@ -0,0 +1,115 @@
|
||||
'use strict';
|
||||
|
||||
const Partials = require('../../util/Partials');
|
||||
|
||||
/*
|
||||
|
||||
ABOUT ACTIONS
|
||||
|
||||
Actions are similar to WebSocket Packet Handlers, but since introducing
|
||||
the REST API methods, in order to prevent rewriting code to handle data,
|
||||
"actions" have been introduced. They're basically what Packet Handlers
|
||||
used to be but they're strictly for manipulating data and making sure
|
||||
that WebSocket events don't clash with REST methods.
|
||||
|
||||
*/
|
||||
|
||||
class GenericAction {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
handle(data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
getPayload(data, manager, id, partialType, cache) {
|
||||
const existing = manager.cache.get(id);
|
||||
if (!existing && this.client.options.partials.includes(partialType)) {
|
||||
return manager._add(data, cache);
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
|
||||
getChannel(data) {
|
||||
const id = data.channel_id ?? data.id;
|
||||
return (
|
||||
data.channel ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
guild_id: data.guild_id,
|
||||
recipients: [data.author ?? data.user ?? { id: data.user_id }],
|
||||
},
|
||||
this.client.channels,
|
||||
id,
|
||||
Partials.Channel,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getMessage(data, channel, cache) {
|
||||
const id = data.message_id ?? data.id;
|
||||
return (
|
||||
data.message ??
|
||||
this.getPayload(
|
||||
{
|
||||
id,
|
||||
channel_id: channel.id,
|
||||
guild_id: data.guild_id ?? channel.guild?.id,
|
||||
},
|
||||
channel.messages,
|
||||
id,
|
||||
Partials.Message,
|
||||
cache,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
getReaction(data, message, user) {
|
||||
const id = data.emoji.id ?? decodeURIComponent(data.emoji.name);
|
||||
return this.getPayload(
|
||||
{
|
||||
emoji: data.emoji,
|
||||
count: message.partial ? null : 0,
|
||||
me: user?.id === this.client.user.id,
|
||||
},
|
||||
message.reactions,
|
||||
id,
|
||||
Partials.Reaction,
|
||||
);
|
||||
}
|
||||
|
||||
getMember(data, guild) {
|
||||
return this.getPayload(data, guild.members, data.user.id, Partials.GuildMember);
|
||||
}
|
||||
|
||||
getUser(data) {
|
||||
const id = data.user_id;
|
||||
return data.user ?? this.getPayload({ id }, this.client.users, id, Partials.User);
|
||||
}
|
||||
|
||||
getUserFromMember(data) {
|
||||
if (data.guild_id && data.member?.user) {
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
return guild.members._add(data.member).user;
|
||||
} else {
|
||||
return this.client.users._add(data.member.user);
|
||||
}
|
||||
}
|
||||
return this.getUser(data);
|
||||
}
|
||||
|
||||
getScheduledEvent(data, guild) {
|
||||
const id = data.guild_scheduled_event_id ?? data.id;
|
||||
return this.getPayload(
|
||||
{ id, guild_id: data.guild_id ?? guild.id },
|
||||
guild.scheduledEvents,
|
||||
id,
|
||||
Partials.GuildScheduledEvent,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenericAction;
|
||||
66
src/client/actions/ActionsManager.js
Normal file
66
src/client/actions/ActionsManager.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
class ActionsManager {
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
|
||||
this.register(require('./ChannelCreate'));
|
||||
this.register(require('./ChannelDelete'));
|
||||
this.register(require('./ChannelUpdate'));
|
||||
this.register(require('./GuildBanAdd'));
|
||||
this.register(require('./GuildBanRemove'));
|
||||
this.register(require('./GuildChannelsPositionUpdate'));
|
||||
this.register(require('./GuildDelete'));
|
||||
this.register(require('./GuildEmojiCreate'));
|
||||
this.register(require('./GuildEmojiDelete'));
|
||||
this.register(require('./GuildEmojiUpdate'));
|
||||
this.register(require('./GuildEmojisUpdate'));
|
||||
this.register(require('./GuildIntegrationsUpdate'));
|
||||
this.register(require('./GuildMemberRemove'));
|
||||
this.register(require('./GuildMemberUpdate'));
|
||||
this.register(require('./GuildRoleCreate'));
|
||||
this.register(require('./GuildRoleDelete'));
|
||||
this.register(require('./GuildRoleUpdate'));
|
||||
this.register(require('./GuildRolesPositionUpdate'));
|
||||
this.register(require('./GuildScheduledEventCreate'));
|
||||
this.register(require('./GuildScheduledEventDelete'));
|
||||
this.register(require('./GuildScheduledEventUpdate'));
|
||||
this.register(require('./GuildScheduledEventUserAdd'));
|
||||
this.register(require('./GuildScheduledEventUserRemove'));
|
||||
this.register(require('./GuildStickerCreate'));
|
||||
this.register(require('./GuildStickerDelete'));
|
||||
this.register(require('./GuildStickerUpdate'));
|
||||
this.register(require('./GuildStickersUpdate'));
|
||||
this.register(require('./GuildUpdate'));
|
||||
this.register(require('./InteractionCreate'));
|
||||
this.register(require('./InviteCreate'));
|
||||
this.register(require('./InviteDelete'));
|
||||
this.register(require('./MessageCreate'));
|
||||
this.register(require('./MessageDelete'));
|
||||
this.register(require('./MessageDeleteBulk'));
|
||||
this.register(require('./MessageReactionAdd'));
|
||||
this.register(require('./MessageReactionRemove'));
|
||||
this.register(require('./MessageReactionRemoveAll'));
|
||||
this.register(require('./MessageReactionRemoveEmoji'));
|
||||
this.register(require('./MessageUpdate'));
|
||||
this.register(require('./PresenceUpdate'));
|
||||
this.register(require('./StageInstanceCreate'));
|
||||
this.register(require('./StageInstanceDelete'));
|
||||
this.register(require('./StageInstanceUpdate'));
|
||||
this.register(require('./ThreadCreate'));
|
||||
this.register(require('./ThreadDelete'));
|
||||
this.register(require('./ThreadListSync'));
|
||||
this.register(require('./ThreadMemberUpdate'));
|
||||
this.register(require('./ThreadMembersUpdate'));
|
||||
this.register(require('./TypingStart'));
|
||||
this.register(require('./UserUpdate'));
|
||||
this.register(require('./VoiceStateUpdate'));
|
||||
this.register(require('./WebhooksUpdate'));
|
||||
}
|
||||
|
||||
register(Action) {
|
||||
this[Action.name.replace(/Action$/, '')] = new Action(this.client);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ActionsManager;
|
||||
23
src/client/actions/ChannelCreate.js
Normal file
23
src/client/actions/ChannelCreate.js
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ChannelCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const existing = client.channels.cache.has(data.id);
|
||||
const channel = client.channels._add(data);
|
||||
if (!existing && channel) {
|
||||
/**
|
||||
* Emitted whenever a guild channel is created.
|
||||
* @event Client#channelCreate
|
||||
* @param {GuildChannel} channel The channel that was created
|
||||
*/
|
||||
client.emit(Events.ChannelCreate, channel);
|
||||
}
|
||||
return { channel };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelCreateAction;
|
||||
23
src/client/actions/ChannelDelete.js
Normal file
23
src/client/actions/ChannelDelete.js
Normal file
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ChannelDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.id);
|
||||
|
||||
if (channel) {
|
||||
client.channels._remove(channel.id);
|
||||
/**
|
||||
* Emitted whenever a channel is deleted.
|
||||
* @event Client#channelDelete
|
||||
* @param {DMChannel|GuildChannel} channel The channel that was deleted
|
||||
*/
|
||||
client.emit(Events.ChannelDelete, channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelDeleteAction;
|
||||
33
src/client/actions/ChannelUpdate.js
Normal file
33
src/client/actions/ChannelUpdate.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const { Channel } = require('../../structures/Channel');
|
||||
|
||||
class ChannelUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
let channel = client.channels.cache.get(data.id);
|
||||
if (channel) {
|
||||
const old = channel._update(data);
|
||||
|
||||
if (channel.type !== data.type) {
|
||||
const newChannel = Channel.create(this.client, data, channel.guild);
|
||||
for (const [id, message] of channel.messages.cache) newChannel.messages.cache.set(id, message);
|
||||
channel = newChannel;
|
||||
this.client.channels.cache.set(channel.id, channel);
|
||||
}
|
||||
|
||||
return {
|
||||
old,
|
||||
updated: channel,
|
||||
};
|
||||
} else {
|
||||
client.channels._add(data);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelUpdateAction;
|
||||
20
src/client/actions/GuildBanAdd.js
Normal file
20
src/client/actions/GuildBanAdd.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildBanAdd extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a member is banned from a guild.
|
||||
* @event Client#guildBanAdd
|
||||
* @param {GuildBan} ban The ban that occurred
|
||||
*/
|
||||
if (guild) client.emit(Events.GuildBanAdd, guild.bans._add(data));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildBanAdd;
|
||||
25
src/client/actions/GuildBanRemove.js
Normal file
25
src/client/actions/GuildBanRemove.js
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const GuildBan = require('../../structures/GuildBan');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildBanRemove extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a member is unbanned from a guild.
|
||||
* @event Client#guildBanRemove
|
||||
* @param {GuildBan} ban The ban that was removed
|
||||
*/
|
||||
if (guild) {
|
||||
const ban = guild.bans.cache.get(data.user.id) ?? new GuildBan(client, data, guild);
|
||||
guild.bans.cache.delete(ban.user.id);
|
||||
client.emit(Events.GuildBanRemove, ban);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildBanRemove;
|
||||
21
src/client/actions/GuildChannelsPositionUpdate.js
Normal file
21
src/client/actions/GuildChannelsPositionUpdate.js
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
|
||||
class GuildChannelsPositionUpdate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
for (const partialChannel of data.channels) {
|
||||
const channel = guild.channels.cache.get(partialChannel.id);
|
||||
if (channel) channel.rawPosition = partialChannel.position;
|
||||
}
|
||||
}
|
||||
|
||||
return { guild };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildChannelsPositionUpdate;
|
||||
44
src/client/actions/GuildDelete.js
Normal file
44
src/client/actions/GuildDelete.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
let guild = client.guilds.cache.get(data.id);
|
||||
if (guild) {
|
||||
if (data.unavailable) {
|
||||
// Guild is unavailable
|
||||
guild.available = false;
|
||||
|
||||
/**
|
||||
* Emitted whenever a guild becomes unavailable, likely due to a server outage.
|
||||
* @event Client#guildUnavailable
|
||||
* @param {Guild} guild The guild that has become unavailable
|
||||
*/
|
||||
client.emit(Events.GuildUnavailable, guild);
|
||||
|
||||
// Stops the GuildDelete packet thinking a guild was actually deleted,
|
||||
// handles emitting of event itself
|
||||
return;
|
||||
}
|
||||
|
||||
for (const channel of guild.channels.cache.values()) this.client.channels._remove(channel.id);
|
||||
client.voice.adapters.get(data.id)?.destroy();
|
||||
|
||||
// Delete guild
|
||||
client.guilds.cache.delete(guild.id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a guild kicks the client or the guild is deleted/left.
|
||||
* @event Client#guildDelete
|
||||
* @param {Guild} guild The guild that was deleted
|
||||
*/
|
||||
client.emit(Events.GuildDelete, guild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildDeleteAction;
|
||||
20
src/client/actions/GuildEmojiCreate.js
Normal file
20
src/client/actions/GuildEmojiCreate.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildEmojiCreateAction extends Action {
|
||||
handle(guild, createdEmoji) {
|
||||
const already = guild.emojis.cache.has(createdEmoji.id);
|
||||
const emoji = guild.emojis._add(createdEmoji);
|
||||
/**
|
||||
* Emitted whenever a custom emoji is created in a guild.
|
||||
* @event Client#emojiCreate
|
||||
* @param {GuildEmoji} emoji The emoji that was created
|
||||
*/
|
||||
if (!already) this.client.emit(Events.GuildEmojiCreate, emoji);
|
||||
return { emoji };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildEmojiCreateAction;
|
||||
19
src/client/actions/GuildEmojiDelete.js
Normal file
19
src/client/actions/GuildEmojiDelete.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildEmojiDeleteAction extends Action {
|
||||
handle(emoji) {
|
||||
emoji.guild.emojis.cache.delete(emoji.id);
|
||||
/**
|
||||
* Emitted whenever a custom emoji is deleted in a guild.
|
||||
* @event Client#emojiDelete
|
||||
* @param {GuildEmoji} emoji The emoji that was deleted
|
||||
*/
|
||||
this.client.emit(Events.GuildEmojiDelete, emoji);
|
||||
return { emoji };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildEmojiDeleteAction;
|
||||
20
src/client/actions/GuildEmojiUpdate.js
Normal file
20
src/client/actions/GuildEmojiUpdate.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildEmojiUpdateAction extends Action {
|
||||
handle(current, data) {
|
||||
const old = current._update(data);
|
||||
/**
|
||||
* Emitted whenever a custom emoji is updated in a guild.
|
||||
* @event Client#emojiUpdate
|
||||
* @param {GuildEmoji} oldEmoji The old emoji
|
||||
* @param {GuildEmoji} newEmoji The new emoji
|
||||
*/
|
||||
this.client.emit(Events.GuildEmojiUpdate, old, current);
|
||||
return { emoji: current };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildEmojiUpdateAction;
|
||||
34
src/client/actions/GuildEmojisUpdate.js
Normal file
34
src/client/actions/GuildEmojisUpdate.js
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
|
||||
class GuildEmojisUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (!guild?.emojis) return;
|
||||
|
||||
const deletions = new Map(guild.emojis.cache);
|
||||
|
||||
for (const emoji of data.emojis) {
|
||||
// Determine type of emoji event
|
||||
const cachedEmoji = guild.emojis.cache.get(emoji.id);
|
||||
if (cachedEmoji) {
|
||||
deletions.delete(emoji.id);
|
||||
if (!cachedEmoji.equals(emoji)) {
|
||||
// Emoji updated
|
||||
this.client.actions.GuildEmojiUpdate.handle(cachedEmoji, emoji);
|
||||
}
|
||||
} else {
|
||||
// Emoji added
|
||||
this.client.actions.GuildEmojiCreate.handle(guild, emoji);
|
||||
}
|
||||
}
|
||||
|
||||
for (const emoji of deletions.values()) {
|
||||
// Emoji deleted
|
||||
this.client.actions.GuildEmojiDelete.handle(emoji);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildEmojisUpdateAction;
|
||||
19
src/client/actions/GuildIntegrationsUpdate.js
Normal file
19
src/client/actions/GuildIntegrationsUpdate.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildIntegrationsUpdate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
/**
|
||||
* Emitted whenever a guild integration is updated
|
||||
* @event Client#guildIntegrationsUpdate
|
||||
* @param {Guild} guild The guild whose integrations were updated
|
||||
*/
|
||||
if (guild) client.emit(Events.GuildIntegrationsUpdate, guild);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildIntegrationsUpdate;
|
||||
30
src/client/actions/GuildMemberRemove.js
Normal file
30
src/client/actions/GuildMemberRemove.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
const Status = require('../../util/Status');
|
||||
|
||||
class GuildMemberRemoveAction extends Action {
|
||||
handle(data, shard) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
let member = null;
|
||||
if (guild) {
|
||||
member = this.getMember({ user: data.user }, guild);
|
||||
guild.memberCount--;
|
||||
if (member) {
|
||||
guild.members.cache.delete(member.id);
|
||||
/**
|
||||
* Emitted whenever a member leaves a guild, or is kicked.
|
||||
* @event Client#guildMemberRemove
|
||||
* @param {GuildMember} member The member that has left/been kicked from the guild
|
||||
*/
|
||||
if (shard.status === Status.Ready) client.emit(Events.GuildMemberRemove, member);
|
||||
}
|
||||
guild.voiceStates.cache.delete(data.user.id);
|
||||
}
|
||||
return { guild, member };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildMemberRemoveAction;
|
||||
44
src/client/actions/GuildMemberUpdate.js
Normal file
44
src/client/actions/GuildMemberUpdate.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
const Status = require('../../util/Status');
|
||||
|
||||
class GuildMemberUpdateAction extends Action {
|
||||
handle(data, shard) {
|
||||
const { client } = this;
|
||||
if (data.user.username) {
|
||||
const user = client.users.cache.get(data.user.id);
|
||||
if (!user) {
|
||||
client.users._add(data.user);
|
||||
} else if (!user._equals(data.user)) {
|
||||
client.actions.UserUpdate.handle(data.user);
|
||||
}
|
||||
}
|
||||
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
const member = this.getMember({ user: data.user }, guild);
|
||||
if (member) {
|
||||
const old = member._update(data);
|
||||
/**
|
||||
* Emitted whenever a guild member changes - i.e. new role, removed role, nickname.
|
||||
* @event Client#guildMemberUpdate
|
||||
* @param {GuildMember} oldMember The member before the update
|
||||
* @param {GuildMember} newMember The member after the update
|
||||
*/
|
||||
if (shard.status === Status.Ready && !member.equals(old)) client.emit(Events.GuildMemberUpdate, old, member);
|
||||
} else {
|
||||
const newMember = guild.members._add(data);
|
||||
/**
|
||||
* Emitted whenever a member becomes available in a large guild.
|
||||
* @event Client#guildMemberAvailable
|
||||
* @param {GuildMember} member The member that became available
|
||||
*/
|
||||
this.client.emit(Events.GuildMemberAvailable, newMember);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildMemberUpdateAction;
|
||||
25
src/client/actions/GuildRoleCreate.js
Normal file
25
src/client/actions/GuildRoleCreate.js
Normal file
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildRoleCreate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
let role;
|
||||
if (guild) {
|
||||
const already = guild.roles.cache.has(data.role.id);
|
||||
role = guild.roles._add(data.role);
|
||||
/**
|
||||
* Emitted whenever a role is created.
|
||||
* @event Client#roleCreate
|
||||
* @param {Role} role The role that was created
|
||||
*/
|
||||
if (!already) client.emit(Events.GuildRoleCreate, role);
|
||||
}
|
||||
return { role };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildRoleCreate;
|
||||
29
src/client/actions/GuildRoleDelete.js
Normal file
29
src/client/actions/GuildRoleDelete.js
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildRoleDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
let role;
|
||||
|
||||
if (guild) {
|
||||
role = guild.roles.cache.get(data.role_id);
|
||||
if (role) {
|
||||
guild.roles.cache.delete(data.role_id);
|
||||
/**
|
||||
* Emitted whenever a guild role is deleted.
|
||||
* @event Client#roleDelete
|
||||
* @param {Role} role The role that was deleted
|
||||
*/
|
||||
client.emit(Events.GuildRoleDelete, role);
|
||||
}
|
||||
}
|
||||
|
||||
return { role };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildRoleDeleteAction;
|
||||
39
src/client/actions/GuildRoleUpdate.js
Normal file
39
src/client/actions/GuildRoleUpdate.js
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildRoleUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
let old = null;
|
||||
|
||||
const role = guild.roles.cache.get(data.role.id);
|
||||
if (role) {
|
||||
old = role._update(data.role);
|
||||
/**
|
||||
* Emitted whenever a guild role is updated.
|
||||
* @event Client#roleUpdate
|
||||
* @param {Role} oldRole The role before the update
|
||||
* @param {Role} newRole The role after the update
|
||||
*/
|
||||
client.emit(Events.GuildRoleUpdate, old, role);
|
||||
}
|
||||
|
||||
return {
|
||||
old,
|
||||
updated: role,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
old: null,
|
||||
updated: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildRoleUpdateAction;
|
||||
21
src/client/actions/GuildRolesPositionUpdate.js
Normal file
21
src/client/actions/GuildRolesPositionUpdate.js
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
|
||||
class GuildRolesPositionUpdate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
for (const partialRole of data.roles) {
|
||||
const role = guild.roles.cache.get(partialRole.id);
|
||||
if (role) role.rawPosition = partialRole.position;
|
||||
}
|
||||
}
|
||||
|
||||
return { guild };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildRolesPositionUpdate;
|
||||
27
src/client/actions/GuildScheduledEventCreate.js
Normal file
27
src/client/actions/GuildScheduledEventCreate.js
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildScheduledEventCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
const guildScheduledEvent = guild.scheduledEvents._add(data);
|
||||
|
||||
/**
|
||||
* Emitted whenever a guild scheduled event is created.
|
||||
* @event Client#guildScheduledEventCreate
|
||||
* @param {GuildScheduledEvent} guildScheduledEvent The created guild scheduled event
|
||||
*/
|
||||
client.emit(Events.GuildScheduledEventCreate, guildScheduledEvent);
|
||||
|
||||
return { guildScheduledEvent };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildScheduledEventCreateAction;
|
||||
31
src/client/actions/GuildScheduledEventDelete.js
Normal file
31
src/client/actions/GuildScheduledEventDelete.js
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildScheduledEventDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
const guildScheduledEvent = this.getScheduledEvent(data, guild);
|
||||
if (guildScheduledEvent) {
|
||||
guild.scheduledEvents.cache.delete(guildScheduledEvent.id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a guild scheduled event is deleted.
|
||||
* @event Client#guildScheduledEventDelete
|
||||
* @param {GuildScheduledEvent} guildScheduledEvent The deleted guild scheduled event
|
||||
*/
|
||||
client.emit(Events.GuildScheduledEventDelete, guildScheduledEvent);
|
||||
|
||||
return { guildScheduledEvent };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildScheduledEventDeleteAction;
|
||||
30
src/client/actions/GuildScheduledEventUpdate.js
Normal file
30
src/client/actions/GuildScheduledEventUpdate.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildScheduledEventUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
const oldGuildScheduledEvent = guild.scheduledEvents.cache.get(data.id)?._clone() ?? null;
|
||||
const newGuildScheduledEvent = guild.scheduledEvents._add(data);
|
||||
|
||||
/**
|
||||
* Emitted whenever a guild scheduled event gets updated.
|
||||
* @event Client#guildScheduledEventUpdate
|
||||
* @param {?GuildScheduledEvent} oldGuildScheduledEvent The guild scheduled event object before the update
|
||||
* @param {GuildScheduledEvent} newGuildScheduledEvent The guild scheduled event object after the update
|
||||
*/
|
||||
client.emit(Events.GuildScheduledEventUpdate, oldGuildScheduledEvent, newGuildScheduledEvent);
|
||||
|
||||
return { oldGuildScheduledEvent, newGuildScheduledEvent };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildScheduledEventUpdateAction;
|
||||
32
src/client/actions/GuildScheduledEventUserAdd.js
Normal file
32
src/client/actions/GuildScheduledEventUserAdd.js
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildScheduledEventUserAddAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
const guildScheduledEvent = this.getScheduledEvent(data, guild);
|
||||
const user = this.getUser(data);
|
||||
|
||||
if (guildScheduledEvent && user) {
|
||||
/**
|
||||
* Emitted whenever a user subscribes to a guild scheduled event
|
||||
* @event Client#guildScheduledEventUserAdd
|
||||
* @param {GuildScheduledEvent} guildScheduledEvent The guild scheduled event
|
||||
* @param {User} user The user who subscribed
|
||||
*/
|
||||
client.emit(Events.GuildScheduledEventUserAdd, guildScheduledEvent, user);
|
||||
|
||||
return { guildScheduledEvent, user };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildScheduledEventUserAddAction;
|
||||
32
src/client/actions/GuildScheduledEventUserRemove.js
Normal file
32
src/client/actions/GuildScheduledEventUserRemove.js
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildScheduledEventUserRemoveAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
|
||||
if (guild) {
|
||||
const guildScheduledEvent = this.getScheduledEvent(data, guild);
|
||||
const user = this.getUser(data);
|
||||
|
||||
if (guildScheduledEvent && user) {
|
||||
/**
|
||||
* Emitted whenever a user unsubscribes from a guild scheduled event
|
||||
* @event Client#guildScheduledEventUserRemove
|
||||
* @param {GuildScheduledEvent} guildScheduledEvent The guild scheduled event
|
||||
* @param {User} user The user who unsubscribed
|
||||
*/
|
||||
client.emit(Events.GuildScheduledEventUserRemove, guildScheduledEvent, user);
|
||||
|
||||
return { guildScheduledEvent, user };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildScheduledEventUserRemoveAction;
|
||||
20
src/client/actions/GuildStickerCreate.js
Normal file
20
src/client/actions/GuildStickerCreate.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildStickerCreateAction extends Action {
|
||||
handle(guild, createdSticker) {
|
||||
const already = guild.stickers.cache.has(createdSticker.id);
|
||||
const sticker = guild.stickers._add(createdSticker);
|
||||
/**
|
||||
* Emitted whenever a custom sticker is created in a guild.
|
||||
* @event Client#stickerCreate
|
||||
* @param {Sticker} sticker The sticker that was created
|
||||
*/
|
||||
if (!already) this.client.emit(Events.GuildStickerCreate, sticker);
|
||||
return { sticker };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildStickerCreateAction;
|
||||
19
src/client/actions/GuildStickerDelete.js
Normal file
19
src/client/actions/GuildStickerDelete.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildStickerDeleteAction extends Action {
|
||||
handle(sticker) {
|
||||
sticker.guild.stickers.cache.delete(sticker.id);
|
||||
/**
|
||||
* Emitted whenever a custom sticker is deleted in a guild.
|
||||
* @event Client#stickerDelete
|
||||
* @param {Sticker} sticker The sticker that was deleted
|
||||
*/
|
||||
this.client.emit(Events.GuildStickerDelete, sticker);
|
||||
return { sticker };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildStickerDeleteAction;
|
||||
20
src/client/actions/GuildStickerUpdate.js
Normal file
20
src/client/actions/GuildStickerUpdate.js
Normal file
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildStickerUpdateAction extends Action {
|
||||
handle(current, data) {
|
||||
const old = current._update(data);
|
||||
/**
|
||||
* Emitted whenever a custom sticker is updated in a guild.
|
||||
* @event Client#stickerUpdate
|
||||
* @param {Sticker} oldSticker The old sticker
|
||||
* @param {Sticker} newSticker The new sticker
|
||||
*/
|
||||
this.client.emit(Events.GuildStickerUpdate, old, current);
|
||||
return { sticker: current };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildStickerUpdateAction;
|
||||
34
src/client/actions/GuildStickersUpdate.js
Normal file
34
src/client/actions/GuildStickersUpdate.js
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
|
||||
class GuildStickersUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (!guild?.stickers) return;
|
||||
|
||||
const deletions = new Map(guild.stickers.cache);
|
||||
|
||||
for (const sticker of data.stickers) {
|
||||
// Determine type of sticker event
|
||||
const cachedSticker = guild.stickers.cache.get(sticker.id);
|
||||
if (cachedSticker) {
|
||||
deletions.delete(sticker.id);
|
||||
if (!cachedSticker.equals(sticker)) {
|
||||
// Sticker updated
|
||||
this.client.actions.GuildStickerUpdate.handle(cachedSticker, sticker);
|
||||
}
|
||||
} else {
|
||||
// Sticker added
|
||||
this.client.actions.GuildStickerCreate.handle(guild, sticker);
|
||||
}
|
||||
}
|
||||
|
||||
for (const sticker of deletions.values()) {
|
||||
// Sticker deleted
|
||||
this.client.actions.GuildStickerDelete.handle(sticker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildStickersUpdateAction;
|
||||
33
src/client/actions/GuildUpdate.js
Normal file
33
src/client/actions/GuildUpdate.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class GuildUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
const guild = client.guilds.cache.get(data.id);
|
||||
if (guild) {
|
||||
const old = guild._update(data);
|
||||
/**
|
||||
* Emitted whenever a guild is updated - e.g. name change.
|
||||
* @event Client#guildUpdate
|
||||
* @param {Guild} oldGuild The guild before the update
|
||||
* @param {Guild} newGuild The guild after the update
|
||||
*/
|
||||
client.emit(Events.GuildUpdate, old, guild);
|
||||
return {
|
||||
old,
|
||||
updated: guild,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
old: null,
|
||||
updated: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildUpdateAction;
|
||||
76
src/client/actions/InteractionCreate.js
Normal file
76
src/client/actions/InteractionCreate.js
Normal file
@@ -0,0 +1,76 @@
|
||||
'use strict';
|
||||
|
||||
const { InteractionType, ComponentType, ApplicationCommandType } = require('discord-api-types/v9');
|
||||
const Action = require('./Action');
|
||||
const AutocompleteInteraction = require('../../structures/AutocompleteInteraction');
|
||||
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
||||
const ChatInputCommandInteraction = require('../../structures/ChatInputCommandInteraction');
|
||||
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
|
||||
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
|
||||
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class InteractionCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
// Resolve and cache partial channels for Interaction#channel getter
|
||||
this.getChannel(data);
|
||||
|
||||
let InteractionClass;
|
||||
switch (data.type) {
|
||||
case InteractionType.ApplicationCommand:
|
||||
switch (data.data.type) {
|
||||
case ApplicationCommandType.ChatInput:
|
||||
InteractionClass = ChatInputCommandInteraction;
|
||||
break;
|
||||
case ApplicationCommandType.User:
|
||||
InteractionClass = UserContextMenuCommandInteraction;
|
||||
break;
|
||||
case ApplicationCommandType.Message:
|
||||
InteractionClass = MessageContextMenuCommandInteraction;
|
||||
break;
|
||||
default:
|
||||
client.emit(
|
||||
Events.Debug,
|
||||
`[INTERACTION] Received application command interaction with unknown type: ${data.data.type}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case InteractionType.MessageComponent:
|
||||
switch (data.data.component_type) {
|
||||
case ComponentType.Button:
|
||||
InteractionClass = ButtonInteraction;
|
||||
break;
|
||||
case ComponentType.SelectMenu:
|
||||
InteractionClass = SelectMenuInteraction;
|
||||
break;
|
||||
default:
|
||||
client.emit(
|
||||
Events.Debug,
|
||||
`[INTERACTION] Received component interaction with unknown type: ${data.data.component_type}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case InteractionType.ApplicationCommandAutocomplete:
|
||||
InteractionClass = AutocompleteInteraction;
|
||||
break;
|
||||
default:
|
||||
client.emit(Events.Debug, `[INTERACTION] Received interaction with unknown type: ${data.type}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const interaction = new InteractionClass(client, data);
|
||||
|
||||
/**
|
||||
* Emitted when an interaction is created.
|
||||
* @event Client#interactionCreate
|
||||
* @param {Interaction} interaction The interaction which was created
|
||||
*/
|
||||
client.emit(Events.InteractionCreate, interaction);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InteractionCreateAction;
|
||||
28
src/client/actions/InviteCreate.js
Normal file
28
src/client/actions/InviteCreate.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class InviteCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.channel_id);
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (!channel) return false;
|
||||
|
||||
const inviteData = Object.assign(data, { channel, guild });
|
||||
const invite = guild.invites._add(inviteData);
|
||||
|
||||
/**
|
||||
* Emitted when an invite is created.
|
||||
* <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild,
|
||||
* or `MANAGE_CHANNELS` permissions for the channel.</info>
|
||||
* @event Client#inviteCreate
|
||||
* @param {Invite} invite The invite that was created
|
||||
*/
|
||||
client.emit(Events.InviteCreate, invite);
|
||||
return { invite };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InviteCreateAction;
|
||||
30
src/client/actions/InviteDelete.js
Normal file
30
src/client/actions/InviteDelete.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Invite = require('../../structures/Invite');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class InviteDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.channel_id);
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (!channel) return false;
|
||||
|
||||
const inviteData = Object.assign(data, { channel, guild });
|
||||
const invite = new Invite(client, inviteData);
|
||||
guild.invites.cache.delete(invite.code);
|
||||
|
||||
/**
|
||||
* Emitted when an invite is deleted.
|
||||
* <info> This event only triggers if the client has `MANAGE_GUILD` permissions for the guild,
|
||||
* or `MANAGE_CHANNELS` permissions for the channel.</info>
|
||||
* @event Client#inviteDelete
|
||||
* @param {Invite} invite The invite that was deleted
|
||||
*/
|
||||
client.emit(Events.InviteDelete, invite);
|
||||
return { invite };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InviteDeleteAction;
|
||||
32
src/client/actions/MessageCreate.js
Normal file
32
src/client/actions/MessageCreate.js
Normal file
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class MessageCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = this.getChannel(data);
|
||||
if (channel) {
|
||||
if (!channel.isTextBased()) return {};
|
||||
|
||||
const existing = channel.messages.cache.get(data.id);
|
||||
if (existing) return { message: existing };
|
||||
const message = channel.messages._add(data);
|
||||
channel.lastMessageId = data.id;
|
||||
|
||||
/**
|
||||
* Emitted whenever a message is created.
|
||||
* @event Client#messageCreate
|
||||
* @param {Message} message The created message
|
||||
*/
|
||||
client.emit(Events.MessageCreate, message);
|
||||
|
||||
return { message };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageCreateAction;
|
||||
30
src/client/actions/MessageDelete.js
Normal file
30
src/client/actions/MessageDelete.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class MessageDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = this.getChannel(data);
|
||||
let message;
|
||||
if (channel) {
|
||||
if (!channel.isTextBased()) return {};
|
||||
|
||||
message = this.getMessage(data, channel);
|
||||
if (message) {
|
||||
channel.messages.cache.delete(message.id);
|
||||
/**
|
||||
* Emitted whenever a message is deleted.
|
||||
* @event Client#messageDelete
|
||||
* @param {Message} message The deleted message
|
||||
*/
|
||||
client.emit(Events.MessageDelete, message);
|
||||
}
|
||||
}
|
||||
|
||||
return { message };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageDeleteAction;
|
||||
44
src/client/actions/MessageDeleteBulk.js
Normal file
44
src/client/actions/MessageDeleteBulk.js
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class MessageDeleteBulkAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.channel_id);
|
||||
|
||||
if (channel) {
|
||||
if (!channel.isTextBased()) return {};
|
||||
|
||||
const ids = data.ids;
|
||||
const messages = new Collection();
|
||||
for (const id of ids) {
|
||||
const message = this.getMessage(
|
||||
{
|
||||
id,
|
||||
guild_id: data.guild_id,
|
||||
},
|
||||
channel,
|
||||
false,
|
||||
);
|
||||
if (message) {
|
||||
messages.set(message.id, message);
|
||||
channel.messages.cache.delete(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted whenever messages are deleted in bulk.
|
||||
* @event Client#messageDeleteBulk
|
||||
* @param {Collection<Snowflake, Message>} messages The deleted messages, mapped by their id
|
||||
*/
|
||||
if (messages.size > 0) client.emit(Events.MessageBulkDelete, messages);
|
||||
return { messages };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageDeleteBulkAction;
|
||||
55
src/client/actions/MessageReactionAdd.js
Normal file
55
src/client/actions/MessageReactionAdd.js
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
const Partials = require('../../util/Partials');
|
||||
|
||||
/*
|
||||
{ user_id: 'id',
|
||||
message_id: 'id',
|
||||
emoji: { name: '<27>', id: null },
|
||||
channel_id: 'id',
|
||||
// If originating from a guild
|
||||
guild_id: 'id',
|
||||
member: { ..., user: { ... } } }
|
||||
*/
|
||||
|
||||
class MessageReactionAdd extends Action {
|
||||
handle(data, fromStructure = false) {
|
||||
if (!data.emoji) return false;
|
||||
|
||||
const user = this.getUserFromMember(data);
|
||||
if (!user) return false;
|
||||
|
||||
// Verify channel
|
||||
const channel = this.getChannel(data);
|
||||
if (!channel?.isTextBased()) return false;
|
||||
|
||||
// Verify message
|
||||
const message = this.getMessage(data, channel);
|
||||
if (!message) return false;
|
||||
|
||||
// Verify reaction
|
||||
const includePartial = this.client.options.partials.includes(Partials.Reaction);
|
||||
if (message.partial && !includePartial) return false;
|
||||
const reaction = message.reactions._add({
|
||||
emoji: data.emoji,
|
||||
count: message.partial ? null : 0,
|
||||
me: user.id === this.client.user.id,
|
||||
});
|
||||
if (!reaction) return false;
|
||||
reaction._add(user);
|
||||
if (fromStructure) return { message, reaction, user };
|
||||
/**
|
||||
* Emitted whenever a reaction is added to a cached message.
|
||||
* @event Client#messageReactionAdd
|
||||
* @param {MessageReaction} messageReaction The reaction object
|
||||
* @param {User} user The user that applied the guild or reaction emoji
|
||||
*/
|
||||
this.client.emit(Events.MessageReactionAdd, reaction, user);
|
||||
|
||||
return { message, reaction, user };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageReactionAdd;
|
||||
45
src/client/actions/MessageReactionRemove.js
Normal file
45
src/client/actions/MessageReactionRemove.js
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
/*
|
||||
{ user_id: 'id',
|
||||
message_id: 'id',
|
||||
emoji: { name: '<27>', id: null },
|
||||
channel_id: 'id',
|
||||
guild_id: 'id' }
|
||||
*/
|
||||
|
||||
class MessageReactionRemove extends Action {
|
||||
handle(data) {
|
||||
if (!data.emoji) return false;
|
||||
|
||||
const user = this.getUser(data);
|
||||
if (!user) return false;
|
||||
|
||||
// Verify channel
|
||||
const channel = this.getChannel(data);
|
||||
if (!channel?.isTextBased()) return false;
|
||||
|
||||
// Verify message
|
||||
const message = this.getMessage(data, channel);
|
||||
if (!message) return false;
|
||||
|
||||
// Verify reaction
|
||||
const reaction = this.getReaction(data, message, user);
|
||||
if (!reaction) return false;
|
||||
reaction._remove(user);
|
||||
/**
|
||||
* Emitted whenever a reaction is removed from a cached message.
|
||||
* @event Client#messageReactionRemove
|
||||
* @param {MessageReaction} messageReaction The reaction object
|
||||
* @param {User} user The user whose emoji or reaction emoji was removed
|
||||
*/
|
||||
this.client.emit(Events.MessageReactionRemove, reaction, user);
|
||||
|
||||
return { message, reaction, user };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageReactionRemove;
|
||||
33
src/client/actions/MessageReactionRemoveAll.js
Normal file
33
src/client/actions/MessageReactionRemoveAll.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class MessageReactionRemoveAll extends Action {
|
||||
handle(data) {
|
||||
// Verify channel
|
||||
const channel = this.getChannel(data);
|
||||
if (!channel?.isTextBased()) return false;
|
||||
|
||||
// Verify message
|
||||
const message = this.getMessage(data, channel);
|
||||
if (!message) return false;
|
||||
|
||||
// Copy removed reactions to emit for the event.
|
||||
const removed = message.reactions.cache.clone();
|
||||
|
||||
message.reactions.cache.clear();
|
||||
this.client.emit(Events.MessageReactionRemoveAll, message, removed);
|
||||
|
||||
return { message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted whenever all reactions are removed from a cached message.
|
||||
* @event Client#messageReactionRemoveAll
|
||||
* @param {Message} message The message the reactions were removed from
|
||||
* @param {Collection<string|Snowflake, MessageReaction>} reactions The cached message reactions that were removed.
|
||||
*/
|
||||
|
||||
module.exports = MessageReactionRemoveAll;
|
||||
28
src/client/actions/MessageReactionRemoveEmoji.js
Normal file
28
src/client/actions/MessageReactionRemoveEmoji.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class MessageReactionRemoveEmoji extends Action {
|
||||
handle(data) {
|
||||
const channel = this.getChannel(data);
|
||||
if (!channel?.isTextBased()) return false;
|
||||
|
||||
const message = this.getMessage(data, channel);
|
||||
if (!message) return false;
|
||||
|
||||
const reaction = this.getReaction(data, message);
|
||||
if (!reaction) return false;
|
||||
if (!message.partial) message.reactions.cache.delete(reaction.emoji.id ?? reaction.emoji.name);
|
||||
|
||||
/**
|
||||
* Emitted when a bot removes an emoji reaction from a cached message.
|
||||
* @event Client#messageReactionRemoveEmoji
|
||||
* @param {MessageReaction} reaction The reaction that was removed
|
||||
*/
|
||||
this.client.emit(Events.MessageReactionRemoveEmoji, reaction);
|
||||
return { reaction };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageReactionRemoveEmoji;
|
||||
26
src/client/actions/MessageUpdate.js
Normal file
26
src/client/actions/MessageUpdate.js
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
|
||||
class MessageUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const channel = this.getChannel(data);
|
||||
if (channel) {
|
||||
if (!channel.isTextBased()) return {};
|
||||
|
||||
const { id, channel_id, guild_id, author, timestamp, type } = data;
|
||||
const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel);
|
||||
if (message) {
|
||||
const old = message._update(data);
|
||||
return {
|
||||
old,
|
||||
updated: message,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MessageUpdateAction;
|
||||
42
src/client/actions/PresenceUpdate.js
Normal file
42
src/client/actions/PresenceUpdate.js
Normal file
@@ -0,0 +1,42 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class PresenceUpdateAction extends Action {
|
||||
handle(data) {
|
||||
let user = this.client.users.cache.get(data.user.id);
|
||||
if (!user && data.user.username) user = this.client.users._add(data.user);
|
||||
if (!user) return;
|
||||
|
||||
if (data.user.username) {
|
||||
if (!user._equals(data.user)) this.client.actions.UserUpdate.handle(data.user);
|
||||
}
|
||||
|
||||
const guild = this.client.guilds.cache.get(data.guild_id);
|
||||
if (!guild) return;
|
||||
|
||||
const oldPresence = guild.presences.cache.get(user.id)?._clone() ?? null;
|
||||
let member = guild.members.cache.get(user.id);
|
||||
if (!member && data.status !== 'offline') {
|
||||
member = guild.members._add({
|
||||
user,
|
||||
deaf: false,
|
||||
mute: false,
|
||||
});
|
||||
this.client.emit(Events.GuildMemberAvailable, member);
|
||||
}
|
||||
const newPresence = guild.presences._add(Object.assign(data, { guild }));
|
||||
if (this.client.listenerCount(Events.PresenceUpdate) && !newPresence.equals(oldPresence)) {
|
||||
/**
|
||||
* Emitted whenever a guild member's presence (e.g. status, activity) is changed.
|
||||
* @event Client#presenceUpdate
|
||||
* @param {?Presence} oldPresence The presence before the update, if one at all
|
||||
* @param {Presence} newPresence The presence after the update
|
||||
*/
|
||||
this.client.emit(Events.PresenceUpdate, oldPresence, newPresence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PresenceUpdateAction;
|
||||
28
src/client/actions/StageInstanceCreate.js
Normal file
28
src/client/actions/StageInstanceCreate.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class StageInstanceCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = this.getChannel(data);
|
||||
|
||||
if (channel) {
|
||||
const stageInstance = channel.guild.stageInstances._add(data);
|
||||
|
||||
/**
|
||||
* Emitted whenever a stage instance is created.
|
||||
* @event Client#stageInstanceCreate
|
||||
* @param {StageInstance} stageInstance The created stage instance
|
||||
*/
|
||||
client.emit(Events.StageInstanceCreate, stageInstance);
|
||||
|
||||
return { stageInstance };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StageInstanceCreateAction;
|
||||
31
src/client/actions/StageInstanceDelete.js
Normal file
31
src/client/actions/StageInstanceDelete.js
Normal file
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class StageInstanceDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = this.getChannel(data);
|
||||
|
||||
if (channel) {
|
||||
const stageInstance = channel.guild.stageInstances._add(data);
|
||||
if (stageInstance) {
|
||||
channel.guild.stageInstances.cache.delete(stageInstance.id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a stage instance is deleted.
|
||||
* @event Client#stageInstanceDelete
|
||||
* @param {StageInstance} stageInstance The deleted stage instance
|
||||
*/
|
||||
client.emit(Events.StageInstanceDelete, stageInstance);
|
||||
|
||||
return { stageInstance };
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StageInstanceDeleteAction;
|
||||
30
src/client/actions/StageInstanceUpdate.js
Normal file
30
src/client/actions/StageInstanceUpdate.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class StageInstanceUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = this.getChannel(data);
|
||||
|
||||
if (channel) {
|
||||
const oldStageInstance = channel.guild.stageInstances.cache.get(data.id)?._clone() ?? null;
|
||||
const newStageInstance = channel.guild.stageInstances._add(data);
|
||||
|
||||
/**
|
||||
* Emitted whenever a stage instance gets updated - e.g. change in topic or privacy level
|
||||
* @event Client#stageInstanceUpdate
|
||||
* @param {?StageInstance} oldStageInstance The stage instance before the update
|
||||
* @param {StageInstance} newStageInstance The stage instance after the update
|
||||
*/
|
||||
client.emit(Events.StageInstanceUpdate, oldStageInstance, newStageInstance);
|
||||
|
||||
return { oldStageInstance, newStageInstance };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StageInstanceUpdateAction;
|
||||
24
src/client/actions/ThreadCreate.js
Normal file
24
src/client/actions/ThreadCreate.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ThreadCreateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const existing = client.channels.cache.has(data.id);
|
||||
const thread = client.channels._add(data);
|
||||
if (!existing && thread) {
|
||||
/**
|
||||
* Emitted whenever a thread is created or when the client user is added to a thread.
|
||||
* @event Client#threadCreate
|
||||
* @param {ThreadChannel} thread The thread that was created
|
||||
* @param {boolean} newlyCreated Whether the thread was newly created
|
||||
*/
|
||||
client.emit(Events.ThreadCreate, thread, data.newly_created ?? false);
|
||||
}
|
||||
return { thread };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadCreateAction;
|
||||
26
src/client/actions/ThreadDelete.js
Normal file
26
src/client/actions/ThreadDelete.js
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ThreadDeleteAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const thread = client.channels.cache.get(data.id);
|
||||
|
||||
if (thread) {
|
||||
client.channels._remove(thread.id);
|
||||
|
||||
/**
|
||||
* Emitted whenever a thread is deleted.
|
||||
* @event Client#threadDelete
|
||||
* @param {ThreadChannel} thread The thread that was deleted
|
||||
*/
|
||||
client.emit(Events.ThreadDelete, thread);
|
||||
}
|
||||
|
||||
return { thread };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadDeleteAction;
|
||||
59
src/client/actions/ThreadListSync.js
Normal file
59
src/client/actions/ThreadListSync.js
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ThreadListSyncAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (!guild) return {};
|
||||
|
||||
if (data.channel_ids) {
|
||||
for (const id of data.channel_ids) {
|
||||
const channel = client.channels.resolve(id);
|
||||
if (channel) this.removeStale(channel);
|
||||
}
|
||||
} else {
|
||||
for (const channel of guild.channels.cache.values()) {
|
||||
this.removeStale(channel);
|
||||
}
|
||||
}
|
||||
|
||||
const syncedThreads = data.threads.reduce((coll, rawThread) => {
|
||||
const thread = client.channels._add(rawThread);
|
||||
return coll.set(thread.id, thread);
|
||||
}, new Collection());
|
||||
|
||||
for (const rawMember of Object.values(data.members)) {
|
||||
// Discord sends the thread id as id in this object
|
||||
const thread = client.channels.cache.get(rawMember.id);
|
||||
if (thread) {
|
||||
thread.members._add(rawMember);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted whenever the client user gains access to a text or news channel that contains threads
|
||||
* @event Client#threadListSync
|
||||
* @param {Collection<Snowflake, ThreadChannel>} threads The threads that were synced
|
||||
*/
|
||||
client.emit(Events.ThreadListSync, syncedThreads);
|
||||
|
||||
return {
|
||||
syncedThreads,
|
||||
};
|
||||
}
|
||||
|
||||
removeStale(channel) {
|
||||
channel.threads?.cache.forEach(thread => {
|
||||
if (!thread.archived) {
|
||||
this.client.channels._remove(thread.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadListSyncAction;
|
||||
30
src/client/actions/ThreadMemberUpdate.js
Normal file
30
src/client/actions/ThreadMemberUpdate.js
Normal file
@@ -0,0 +1,30 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ThreadMemberUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
// Discord sends the thread id as id in this object
|
||||
const thread = client.channels.cache.get(data.id);
|
||||
if (thread) {
|
||||
const member = thread.members.cache.get(data.user_id);
|
||||
if (!member) {
|
||||
const newMember = thread.members._add(data);
|
||||
return { newMember };
|
||||
}
|
||||
const old = member._update(data);
|
||||
/**
|
||||
* Emitted whenever the client user's thread member is updated.
|
||||
* @event Client#threadMemberUpdate
|
||||
* @param {ThreadMember} oldMember The member before the update
|
||||
* @param {ThreadMember} newMember The member after the update
|
||||
*/
|
||||
client.emit(Events.ThreadMemberUpdate, old, member);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadMemberUpdateAction;
|
||||
34
src/client/actions/ThreadMembersUpdate.js
Normal file
34
src/client/actions/ThreadMembersUpdate.js
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class ThreadMembersUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const thread = client.channels.cache.get(data.id);
|
||||
if (thread) {
|
||||
const old = thread.members.cache.clone();
|
||||
thread.memberCount = data.member_count;
|
||||
|
||||
data.added_members?.forEach(rawMember => {
|
||||
thread.members._add(rawMember);
|
||||
});
|
||||
|
||||
data.removed_member_ids?.forEach(memberId => {
|
||||
thread.members.cache.delete(memberId);
|
||||
});
|
||||
|
||||
/**
|
||||
* Emitted whenever members are added or removed from a thread. Requires `GUILD_MEMBERS` privileged intent
|
||||
* @event Client#threadMembersUpdate
|
||||
* @param {Collection<Snowflake, ThreadMember>} oldMembers The members before the update
|
||||
* @param {Collection<Snowflake, ThreadMember>} newMembers The members after the update
|
||||
*/
|
||||
client.emit(Events.ThreadMembersUpdate, old, thread.members.cache);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadMembersUpdateAction;
|
||||
29
src/client/actions/TypingStart.js
Normal file
29
src/client/actions/TypingStart.js
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Typing = require('../../structures/Typing');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class TypingStart extends Action {
|
||||
handle(data) {
|
||||
const channel = this.getChannel(data);
|
||||
if (!channel) return;
|
||||
|
||||
if (!channel.isTextBased()) {
|
||||
this.client.emit(Events.Warn, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const user = this.getUserFromMember(data);
|
||||
if (user) {
|
||||
/**
|
||||
* Emitted whenever a user starts typing in a channel.
|
||||
* @event Client#typingStart
|
||||
* @param {Typing} typing The typing state
|
||||
*/
|
||||
this.client.emit(Events.TypingStart, new Typing(channel, user, data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TypingStart;
|
||||
35
src/client/actions/UserUpdate.js
Normal file
35
src/client/actions/UserUpdate.js
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class UserUpdateAction extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
|
||||
const newUser = data.id === client.user.id ? client.user : client.users.cache.get(data.id);
|
||||
const oldUser = newUser._update(data);
|
||||
|
||||
if (!oldUser.equals(newUser)) {
|
||||
/**
|
||||
* Emitted whenever a user's details (e.g. username) are changed.
|
||||
* Triggered by the Discord gateway events USER_UPDATE, GUILD_MEMBER_UPDATE, and PRESENCE_UPDATE.
|
||||
* @event Client#userUpdate
|
||||
* @param {User} oldUser The user before the update
|
||||
* @param {User} newUser The user after the update
|
||||
*/
|
||||
client.emit(Events.UserUpdate, oldUser, newUser);
|
||||
return {
|
||||
old: oldUser,
|
||||
updated: newUser,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
old: null,
|
||||
updated: null,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserUpdateAction;
|
||||
43
src/client/actions/VoiceStateUpdate.js
Normal file
43
src/client/actions/VoiceStateUpdate.js
Normal file
@@ -0,0 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const VoiceState = require('../../structures/VoiceState');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class VoiceStateUpdate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const guild = client.guilds.cache.get(data.guild_id);
|
||||
if (guild) {
|
||||
// Update the state
|
||||
const oldState =
|
||||
guild.voiceStates.cache.get(data.user_id)?._clone() ?? new VoiceState(guild, { user_id: data.user_id });
|
||||
|
||||
const newState = guild.voiceStates._add(data);
|
||||
|
||||
// Get the member
|
||||
let member = guild.members.cache.get(data.user_id);
|
||||
if (member && data.member) {
|
||||
member._patch(data.member);
|
||||
} else if (data.member?.user && data.member.joined_at) {
|
||||
member = guild.members._add(data.member);
|
||||
}
|
||||
|
||||
// Emit event
|
||||
if (member?.user.id === client.user.id) {
|
||||
client.emit('debug', `[VOICE] received voice state update: ${JSON.stringify(data)}`);
|
||||
client.voice.onVoiceStateUpdate(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Emitted whenever a member changes voice state - e.g. joins/leaves a channel, mutes/unmutes.
|
||||
* @event Client#voiceStateUpdate
|
||||
* @param {VoiceState} oldState The voice state before the update
|
||||
* @param {VoiceState} newState The voice state after the update
|
||||
*/
|
||||
client.emit(Events.VoiceStateUpdate, oldState, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VoiceStateUpdate;
|
||||
19
src/client/actions/WebhooksUpdate.js
Normal file
19
src/client/actions/WebhooksUpdate.js
Normal file
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
const Action = require('./Action');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class WebhooksUpdate extends Action {
|
||||
handle(data) {
|
||||
const client = this.client;
|
||||
const channel = client.channels.cache.get(data.channel_id);
|
||||
/**
|
||||
* Emitted whenever a channel has its webhooks changed.
|
||||
* @event Client#webhookUpdate
|
||||
* @param {TextChannel|NewsChannel} channel The channel that had a webhook update
|
||||
*/
|
||||
if (channel) client.emit(Events.WebhooksUpdate, channel);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WebhooksUpdate;
|
||||
Reference in New Issue
Block a user