Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for GuildScheduledEvent #6493

Merged
merged 102 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
8be8620
feat: add support for GuildEvent
iShibi Aug 21, 2021
469c2ec
fix(GuildEvent): add missing _patch call & rm skus type tag for now
iShibi Aug 21, 2021
41504f8
feat: add GuildEventEntityMetadata class
iShibi Aug 21, 2021
5d27c6f
docs(GuildEvent): add jsdoc type tag for #channelId
iShibi Aug 21, 2021
2d83f6e
docs: use api types in jsdoc for raw data
iShibi Aug 22, 2021
e5c0cb0
fix: name of guild event metadata type
iShibi Aug 22, 2021
ce9fad3
fix(Constants): swap guild event entity and status enum names
iShibi Aug 22, 2021
ce85dfc
feat: add GuildEventManager
iShibi Aug 22, 2021
beca93a
feat(GuildEventManager): add methods for creating & deleting GuildEvent
iShibi Aug 22, 2021
beda8e8
feat(GuildEventManager): add method to edit a guild event
iShibi Aug 23, 2021
2a6b0fb
feat(Permissions): add MANAGE_EVENTS permission flag
iShibi Aug 23, 2021
5af66f8
refactor(GuildEventManager): make id resolution concise in #fetch
iShibi Aug 23, 2021
740567b
refactor(GuildEventManager): let the api validate required values
iShibi Aug 23, 2021
70ea331
feat: add gateway events
iShibi Aug 28, 2021
e8ccd7c
feat(GuildEvent): add deleted property
iShibi Aug 28, 2021
71fc59c
style: correctly name GuildScheduledEventDeleteAction class
iShibi Aug 28, 2021
b52e777
refactor: keep up with the recent upstream changes
iShibi Sep 3, 2021
683de5c
feat(GuildAuditLogs): add guild event related audit logs
iShibi Sep 6, 2021
170977f
feat: add time related stuff for guild scheduled event
iShibi Sep 29, 2021
8f228f2
refactor: change name of GuildEvent class to GuildScheduledEvent
iShibi Sep 29, 2021
ac78ab7
refactor: change GuildEvent filename to GuildScheduledEvent
iShibi Sep 29, 2021
3b9c88b
refactor: rename class to GuildScheduledEventManager & more
iShibi Sep 29, 2021
1d2c752
refactor: rename GuildEventManager filename & related guild prop
iShibi Sep 29, 2021
dbaaf12
refactor: rename GUILD_EVENT target type and error message key
iShibi Sep 29, 2021
1802ffc
feat: add the new upstream changes (Part 1)
iShibi Nov 14, 2021
5fbb11c
feat: add options for setting entity metadata when creating/editing
iShibi Nov 15, 2021
41de48b
feat: add the new upstream changes (Part 2)
iShibi Nov 15, 2021
7ef8244
refactor(GuildScheduledEvent): remove image property
iShibi Nov 16, 2021
bec405d
types: add type definitions
iShibi Nov 16, 2021
c9448d2
docs(Constants): add links to API docs
iShibi Nov 16, 2021
fa8564d
refactor(GuildScheduledEvent): check for nullable fields
iShibi Nov 16, 2021
2af1949
feat: add ability to fetch event data with invite and more
iShibi Nov 16, 2021
803f096
feat: add methods for editing individual props
iShibi Nov 16, 2021
db748d2
docs: add examples
iShibi Nov 17, 2021
ec2c4c0
fix(Invite): assign null to guildScheduledEvent prop correctly
iShibi Nov 17, 2021
ccb8524
refactor(GuildScheduledEvent): remove speakerIds prop
iShibi Nov 17, 2021
b64c8cd
types: add conditional typings for guild event fetch method
iShibi Nov 17, 2021
8920feb
types: add raw data type for scheduled event
iShibi Nov 17, 2021
ef85c3b
fix(Constants): max len error
iShibi Nov 17, 2021
34d1d16
fix: use correct event name in user remove action
iShibi Nov 17, 2021
28127e2
fix: apply suggestions from review
iShibi Nov 17, 2021
7bd91f1
feat: add scheduled end time option
iShibi Nov 17, 2021
45b5c11
fix: assign scheduled event's nullable props correctly
iShibi Nov 17, 2021
4b69d00
refactor: apply suggestions from review
iShibi Nov 18, 2021
9bff63e
refactor: remove speakers field
iShibi Nov 18, 2021
530ad0a
docs: ❄️
iShibi Nov 18, 2021
1769f8b
feat(GuildScheduledEvent): add method for fetching subscribers
iShibi Nov 18, 2021
8c72080
feat: add upstream changes
iShibi Nov 19, 2021
3862fab
refactor: move types to their correct position
iShibi Nov 19, 2021
fe4048e
feat: export manager and structure for scheduled event
iShibi Nov 19, 2021
46ed02b
feat: add new error codes
iShibi Nov 19, 2021
a0e0891
fix(GuildScheduledEventUpdate): add check for uncached event
iShibi Nov 20, 2021
dffe189
chore: delete vscode settings file
iShibi Nov 23, 2021
ab6ea13
docs: apply suggestion from code review
iShibi Nov 24, 2021
8479198
feat: allow endtime to be null and add method to edit it
iShibi Nov 24, 2021
0800bda
feat: add GUILD_SCHEDULED_EVENT partial
iShibi Nov 24, 2021
6006ed1
feat: update scheduled events cache on GUILD_CREATE
iShibi Nov 24, 2021
102b70e
refactor(GuildScheduledEventManager): rm redundant checks for end time
iShibi Nov 24, 2021
edeef81
refactor: make entityMetadata option a nested object
iShibi Nov 27, 2021
72edbb5
refactor: ^._.^ genius Part II
iShibi Nov 27, 2021
52d9d4a
refactor: revert last commit for the sake of future-proofing
iShibi Nov 27, 2021
2f387f2
fix(GuildScheduledEvent): convert time from ISO string to timestamp
iShibi Nov 27, 2021
0ce9967
fix(GuildScheduledEvent): add checks
iShibi Nov 27, 2021
7ad3d7b
feat(GuildScheduledEvent): add url getter and toString method
iShibi Nov 28, 2021
e9d127e
fix(GuildScheduledEvent): typo in createdAt method name
iShibi Nov 28, 2021
0961899
fix: bugs in shortcut methods and add warnings
iShibi Nov 29, 2021
19a5627
fix: gateway events not emitting
iShibi Nov 30, 2021
792aefe
refactor: use script to generate actions & ws handlers
iShibi Nov 30, 2021
b850954
feat: add GuildScheduledEventUser typedef to represent a sub
iShibi Dec 1, 2021
d9c5eb9
feat(GuildScheduledEvent): add type-guards to limit setStatus arg type
iShibi Dec 1, 2021
c43e409
fix: audit log stuff
iShibi Dec 2, 2021
64c2f35
docs(GuildScheduledEvent): remove external link to dapi-docs
iShibi Dec 2, 2021
97c34f2
docs(GuildScheduledEvent): add info tag to setStatus method
iShibi Dec 2, 2021
4270e99
docs(GuildScheduledEvent): update return type of fetchSubscribers
iShibi Dec 3, 2021
dc5fb5a
docs(GuildScheduledEvent): fix link and add some more stuff in jsdoc
iShibi Dec 3, 2021
d1ec086
docs(GuildAuditLogs): set deleted if a scheduled event was deleted
iShibi Dec 3, 2021
d24db6d
chore: remove TODO comment
iShibi Dec 3, 2021
66222ac
chore: remove vscode settings file again
iShibi Dec 4, 2021
c083ea0
docs(GuildScheduledEvent): fix jsdoc examples
iShibi Dec 4, 2021
390cfec
fix: set start time to null if not present
iShibi Dec 4, 2021
d251859
feat(GuildScheduledEvent): add method to create invite url
iShibi Dec 4, 2021
1e2dd39
feat(GuildScheduledEvent): change implementation of createInviteUrl
iShibi Dec 6, 2021
08cca58
refactor: use Endpoints to generate invite url string
iShibi Dec 6, 2021
bd0bbfd
refactor: apply suggestions from code review
iShibi Dec 7, 2021
eedc0a0
refactor(GuildScheduledEvent): use timestampFrom instead of deconstruct
iShibi Dec 7, 2021
86b1627
feat(GuildScheduledEvent): add entityMetadata property
iShibi Dec 7, 2021
6aafd31
types: add scheduled event related audit log types
iShibi Dec 7, 2021
0da63c5
feat: add deleted getter and setter
iShibi Dec 10, 2021
3a36a5e
refactor: use getScheduledEvent in delete action handler
iShibi Dec 12, 2021
73215f8
fix: do not set stuff in create when it is not required
iShibi Dec 13, 2021
56edb25
revert: remove deleted getter & setter
iShibi Dec 13, 2021
3631345
fix: only set entity_metadata when it is provided in edit
iShibi Dec 15, 2021
fe39b76
refactor: rename start and end time property
iShibi Dec 15, 2021
e174eac
docs: fix the example for setLocation
iShibi Dec 15, 2021
9eb9660
feat: add reason field to create and edit options
iShibi Dec 15, 2021
3c3a749
docs(GuildScheduledEvent): use ISO strings in the examples
iShibi Dec 16, 2021
a4fa8ba
refactor(GuildScheduledEvent): do not clone in delete
iShibi Dec 16, 2021
515839b
types: improve typings for guild scheduled event
iShibi Dec 17, 2021
ac83a4a
refactor: apply suggestions from code review
iShibi Dec 22, 2021
b3c86a6
refactor: use enum instead of literal for comparing entity type
iShibi Dec 22, 2021
eb856ee
types: add GuildScheduledEventManager to Caches
iShibi Dec 22, 2021
b5cfe27
refactor: apply suggestions from code review
iShibi Dec 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventCreate.handle(packet.d);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.GuildScheduledEventDelete.handle(packet.d);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

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

module.exports = (client, packet) => {
client.actions.GuildScheduledEventUserAdd.handle(packet.d);
};
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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