Skip to content

Commit

Permalink
feat: add support for GuildScheduledEvent (#6493)
Browse files Browse the repository at this point in the history
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
Co-authored-by: Sugden <28943913+NotSugden@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: GoldenAngel <50855202+GoldenAngel2@users.noreply.github.com>
Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
Co-authored-by: SpaceEEC <spaceeec@yahoo.com>
  • Loading branch information
8 people committed Dec 23, 2021
1 parent aa7c1b2 commit 1316fd4
Show file tree
Hide file tree
Showing 29 changed files with 1,261 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Expand Up @@ -95,6 +95,7 @@ body:
- GUILD_MEMBER
- MESSAGE
- REACTION
- GUILD_SCHEDULED_EVENT
multiple: true
validations:
required: true
Expand Down Expand Up @@ -122,6 +123,7 @@ body:
- DIRECT_MESSAGES
- DIRECT_MESSAGE_REACTIONS
- DIRECT_MESSAGE_TYPING
- GUILD_SCHEDULED_EVENTS
multiple: true
validations:
required: true
Expand Down
14 changes: 12 additions & 2 deletions src/client/Client.js
Expand Up @@ -283,18 +283,28 @@ class Client extends BaseClient {
this.token = null;
}

/**
* Options used when fetching an invite from Discord.
* @typedef {Object} ClientFetchInviteOptions
* @property {Snowflake} [guildScheduledEventId] The id of the guild scheduled event to include with
* the invite
*/

/**
* Obtains an invite from Discord.
* @param {InviteResolvable} invite Invite code or URL
* @param {ClientFetchInviteOptions} [options] Options for fetching the invite
* @returns {Promise<Invite>}
* @example
* client.fetchInvite('https://discord.gg/djs')
* .then(invite => console.log(`Obtained invite with code: ${invite.code}`))
* .catch(console.error);
*/
async fetchInvite(invite) {
async fetchInvite(invite, options) {
const code = DataResolver.resolveInviteCode(invite);
const data = await this.api.invites(code).get({ query: { with_counts: true, with_expiration: true } });
const data = await this.api.invites(code).get({
query: { with_counts: true, with_expiration: true, guild_scheduled_event_id: options?.guildScheduledEventId },
});
return new Invite(this, data);
}

Expand Down
10 changes: 10 additions & 0 deletions src/client/actions/Action.js
Expand Up @@ -100,6 +100,16 @@ class GenericAction {
}
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,
PartialTypes.GUILD_SCHEDULED_EVENT,
);
}
}

module.exports = GenericAction;
5 changes: 5 additions & 0 deletions src/client/actions/ActionsManager.js
Expand Up @@ -22,6 +22,11 @@ class ActionsManager {
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'));
Expand Down
27 changes: 27 additions & 0 deletions src/client/actions/GuildScheduledEventCreate.js
@@ -0,0 +1,27 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

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.GUILD_SCHEDULED_EVENT_CREATE, guildScheduledEvent);

return { guildScheduledEvent };
}

return {};
}
}

module.exports = GuildScheduledEventCreateAction;
31 changes: 31 additions & 0 deletions src/client/actions/GuildScheduledEventDelete.js
@@ -0,0 +1,31 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

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.GUILD_SCHEDULED_EVENT_DELETE, guildScheduledEvent);

return { guildScheduledEvent };
}
}

return {};
}
}

module.exports = GuildScheduledEventDeleteAction;
30 changes: 30 additions & 0 deletions src/client/actions/GuildScheduledEventUpdate.js
@@ -0,0 +1,30 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

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.GUILD_SCHEDULED_EVENT_UPDATE, oldGuildScheduledEvent, newGuildScheduledEvent);

return { oldGuildScheduledEvent, newGuildScheduledEvent };
}

return {};
}
}

module.exports = GuildScheduledEventUpdateAction;
32 changes: 32 additions & 0 deletions src/client/actions/GuildScheduledEventUserAdd.js
@@ -0,0 +1,32 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

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.GUILD_SCHEDULED_EVENT_USER_ADD, guildScheduledEvent, user);

return { guildScheduledEvent, user };
}
}

return {};
}
}

module.exports = GuildScheduledEventUserAddAction;
32 changes: 32 additions & 0 deletions src/client/actions/GuildScheduledEventUserRemove.js
@@ -0,0 +1,32 @@
'use strict';

const Action = require('./Action');
const { Events } = require('../../util/Constants');

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.GUILD_SCHEDULED_EVENT_USER_REMOVE, guildScheduledEvent, user);

return { guildScheduledEvent, user };
}
}

return {};
}
}

module.exports = GuildScheduledEventUserRemoveAction;
5 changes: 5 additions & 0 deletions src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_CREATE.js
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventCreate.handle(packet.d);
};
5 changes: 5 additions & 0 deletions src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_DELETE.js
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventDelete.handle(packet.d);
};
5 changes: 5 additions & 0 deletions src/client/websocket/handlers/GUILD_SCHEDULED_EVENT_UPDATE.js
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventUpdate.handle(packet.d);
};
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventUserAdd.handle(packet.d);
};
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventUserRemove.handle(packet.d);
};
5 changes: 5 additions & 0 deletions src/client/websocket/handlers/index.js
Expand Up @@ -51,6 +51,11 @@ const handlers = Object.fromEntries([
['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')],
['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')],
['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')],
['GUILD_SCHEDULED_EVENT_CREATE', require('./GUILD_SCHEDULED_EVENT_CREATE')],
['GUILD_SCHEDULED_EVENT_UPDATE', require('./GUILD_SCHEDULED_EVENT_UPDATE')],
['GUILD_SCHEDULED_EVENT_DELETE', require('./GUILD_SCHEDULED_EVENT_DELETE')],
['GUILD_SCHEDULED_EVENT_USER_ADD', require('./GUILD_SCHEDULED_EVENT_USER_ADD')],
['GUILD_SCHEDULED_EVENT_USER_REMOVE', require('./GUILD_SCHEDULED_EVENT_USER_REMOVE')],
]);

module.exports = handlers;
3 changes: 3 additions & 0 deletions src/errors/Messages.js
Expand Up @@ -39,6 +39,8 @@ const Messages = {
COLOR_RANGE: 'Color must be within the range 0 - 16777215 (0xFFFFFF).',
COLOR_CONVERT: 'Unable to convert color to a number.',

INVITE_OPTIONS_MISSING_CHANNEL: 'A valid guild channel must be provided when GuildScheduledEvent is EXTERNAL.',

EMBED_TITLE: 'MessageEmbed title must be a string.',
EMBED_FIELD_NAME: 'MessageEmbed field names must be non-empty strings.',
EMBED_FIELD_VALUE: 'MessageEmbed field values must be non-empty strings.',
Expand Down Expand Up @@ -94,6 +96,7 @@ const Messages = {
GUILD_UNCACHED_ME: 'The client user as a member of this guild is uncached.',
CHANNEL_NOT_CACHED: 'Could not find the channel where this message came from in the cache!',
STAGE_CHANNEL_RESOLVE: 'Could not resolve channel to a stage channel.',
GUILD_SCHEDULED_EVENT_RESOLVE: 'Could not resolve the guild scheduled event.',

INVALID_TYPE: (name, expected, an = false) => `Supplied ${name} is not a${an ? 'n' : ''} ${expected}.`,
INVALID_ELEMENT: (type, name, elem) => `Supplied ${type} ${name} includes an invalid element: ${elem}`,
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Expand Up @@ -50,6 +50,7 @@ exports.GuildInviteManager = require('./managers/GuildInviteManager');
exports.GuildManager = require('./managers/GuildManager');
exports.GuildMemberManager = require('./managers/GuildMemberManager');
exports.GuildMemberRoleManager = require('./managers/GuildMemberRoleManager');
exports.GuildScheduledEventManager = require('./managers/GuildScheduledEventManager');
exports.GuildStickerManager = require('./managers/GuildStickerManager');
exports.MessageManager = require('./managers/MessageManager');
exports.PermissionOverwriteManager = require('./managers/PermissionOverwriteManager');
Expand Down Expand Up @@ -99,6 +100,7 @@ exports.GuildEmoji = require('./structures/GuildEmoji');
exports.GuildMember = require('./structures/GuildMember').GuildMember;
exports.GuildPreview = require('./structures/GuildPreview');
exports.GuildPreviewEmoji = require('./structures/GuildPreviewEmoji');
exports.GuildScheduledEvent = require('./structures/GuildScheduledEvent').GuildScheduledEvent;
exports.GuildTemplate = require('./structures/GuildTemplate');
exports.Integration = require('./structures/Integration');
exports.IntegrationApplication = require('./structures/IntegrationApplication');
Expand Down

0 comments on commit 1316fd4

Please sign in to comment.