mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-09 16:13:31 +01:00
feat: recurring scheduled events (#10447)
* feat: recurring scheduled events * fix: nullable on patch * docs: remove unnecessary parenthesis Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com> --------- Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
This commit is contained in:
@@ -7,6 +7,7 @@ const CachedManager = require('./CachedManager');
|
||||
const { DiscordjsTypeError, DiscordjsError, ErrorCodes } = require('../errors');
|
||||
const { GuildScheduledEvent } = require('../structures/GuildScheduledEvent');
|
||||
const { resolveImage } = require('../util/DataResolver');
|
||||
const { _transformGuildScheduledEventRecurrenceRule } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Manages API methods for GuildScheduledEvents and stores their cache.
|
||||
@@ -36,6 +37,21 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
* @typedef {Snowflake|GuildScheduledEvent} GuildScheduledEventResolvable
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options for setting a recurrence rule for a guild scheduled event.
|
||||
* @typedef {Object} GuildScheduledEventRecurrenceRuleOptions
|
||||
* @property {DateResolvable} startAt The time the recurrence rule interval starts at
|
||||
* @property {?DateResolvable} endAt The time the recurrence rule interval ends at
|
||||
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
|
||||
* @property {number} interval The spacing between the events
|
||||
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
|
||||
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
|
||||
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
|
||||
* @property {?number[]} byMonthDay The days within a month to recur on
|
||||
* @property {?number[]} byYearDay The days within a year to recur on
|
||||
* @property {?number} count The total amount of times the event is allowed to recur before stopping
|
||||
*/
|
||||
|
||||
/**
|
||||
* Options used to create a guild scheduled event.
|
||||
* @typedef {Object} GuildScheduledEventCreateOptions
|
||||
@@ -54,6 +70,8 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
* <warn>This is required if `entityType` is {@link GuildScheduledEventEntityType.External}</warn>
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
|
||||
* @property {string} [reason] The reason for creating the guild scheduled event
|
||||
* @property {GuildScheduledEventRecurrenceRuleOptions} [recurrenceRule]
|
||||
* The recurrence rule of the guild scheduled event
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -81,6 +99,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
entityMetadata,
|
||||
reason,
|
||||
image,
|
||||
recurrenceRule,
|
||||
} = options;
|
||||
|
||||
let entity_metadata, channel_id;
|
||||
@@ -104,6 +123,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
entity_type: entityType,
|
||||
entity_metadata,
|
||||
image: image && (await resolveImage(image)),
|
||||
recurrence_rule: recurrenceRule && _transformGuildScheduledEventRecurrenceRule(recurrenceRule),
|
||||
},
|
||||
reason,
|
||||
});
|
||||
@@ -178,6 +198,8 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
* {@link GuildScheduledEventEntityType.External}</warn>
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [image] The cover image of the guild scheduled event
|
||||
* @property {string} [reason] The reason for editing the guild scheduled event
|
||||
* @property {?GuildScheduledEventRecurrenceRuleOptions} [recurrenceRule]
|
||||
* The recurrence rule of the guild scheduled event
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -203,6 +225,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
entityMetadata,
|
||||
reason,
|
||||
image,
|
||||
recurrenceRule,
|
||||
} = options;
|
||||
|
||||
let entity_metadata;
|
||||
@@ -224,6 +247,7 @@ class GuildScheduledEventManager extends CachedManager {
|
||||
status,
|
||||
image: image && (await resolveImage(image)),
|
||||
entity_metadata,
|
||||
recurrence_rule: recurrenceRule && _transformGuildScheduledEventRecurrenceRule(recurrenceRule),
|
||||
},
|
||||
reason,
|
||||
});
|
||||
|
||||
@@ -189,6 +189,56 @@ class GuildScheduledEvent extends Base {
|
||||
} else {
|
||||
this.image ??= null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the recurrence rule for a {@link GuildScheduledEvent}.
|
||||
* @typedef {Object} GuildScheduledEventRecurrenceRule
|
||||
* @property {number} startTimestamp The timestamp the recurrence rule interval starts at
|
||||
* @property {Date} startAt The time the recurrence rule interval starts at
|
||||
* @property {?number} endTimestamp The timestamp the recurrence rule interval ends at
|
||||
* @property {?Date} endAt The time the recurrence rule interval ends at
|
||||
* @property {GuildScheduledEventRecurrenceRuleFrequency} frequency How often the event occurs
|
||||
* @property {number} interval The spacing between the events
|
||||
* @property {?GuildScheduledEventRecurrenceRuleWeekday[]} byWeekday The days within a week to recur on
|
||||
* @property {?GuildScheduledEventRecurrenceRuleNWeekday[]} byNWeekday The days within a week to recur on
|
||||
* @property {?GuildScheduledEventRecurrenceRuleMonth[]} byMonth The months to recur on
|
||||
* @property {?number[]} byMonthDay The days within a month to recur on
|
||||
* @property {?number[]} byYearDay The days within a year to recur on
|
||||
* @property {?number} count The total amount of times the event is allowed to recur before stopping
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} GuildScheduledEventRecurrenceRuleNWeekday
|
||||
* @property {number} n The week to recur on
|
||||
* @property {GuildScheduledEventRecurrenceRuleWeekday} day The day within the week to recur on
|
||||
*/
|
||||
|
||||
if ('recurrence_rule' in data) {
|
||||
/**
|
||||
* The recurrence rule for this scheduled event
|
||||
* @type {?GuildScheduledEventRecurrenceRule}
|
||||
*/
|
||||
this.recurrenceRule = {
|
||||
startTimestamp: Date.parse(data.recurrence_rule.start),
|
||||
get startAt() {
|
||||
return new Date(this.startTimestamp);
|
||||
},
|
||||
endTimestamp: data.recurrence_rule.end && Date.parse(data.recurrence_rule.end),
|
||||
get endAt() {
|
||||
return this.endTimestamp && new Date(this.endTimestamp);
|
||||
},
|
||||
frequency: data.recurrence_rule.frequency,
|
||||
interval: data.recurrence_rule.interval,
|
||||
byWeekday: data.recurrence_rule.by_weekday,
|
||||
byNWeekday: data.recurrence_rule.by_n_weekday,
|
||||
byMonth: data.recurrence_rule.by_month,
|
||||
byMonthDay: data.recurrence_rule.by_month_day,
|
||||
byYearDay: data.recurrence_rule.by_year_day,
|
||||
count: data.recurrence_rule.count,
|
||||
};
|
||||
} else {
|
||||
this.recurrenceRule ??= null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildMember}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APIGuildScheduledEventRecurrenceRule
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/interface/APIGuildScheduledEventRecurrenceRule}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external APIInteraction
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10#APIInteraction}
|
||||
@@ -390,6 +395,21 @@
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventPrivacyLevel}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildScheduledEventRecurrenceRuleFrequency
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleFrequency}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildScheduledEventRecurrenceRuleMonth
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleMonth}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildScheduledEventRecurrenceRuleWeekday
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventRecurrenceRuleWeekday}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @external GuildScheduledEventStatus
|
||||
* @see {@link https://discord-api-types.dev/api/discord-api-types-v10/enum/GuildScheduledEventStatus}
|
||||
|
||||
@@ -54,4 +54,31 @@ function _transformAPIMessageInteractionMetadata(client, messageInteractionMetad
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { toSnakeCase, _transformAPIAutoModerationAction, _transformAPIMessageInteractionMetadata };
|
||||
/**
|
||||
* Transforms a guild scheduled event recurrence rule object to a snake-cased variant.
|
||||
* @param {GuildScheduledEventRecurrenceRuleOptions} recurrenceRule The recurrence rule to transform
|
||||
* @returns {APIGuildScheduledEventRecurrenceRule}
|
||||
* @ignore
|
||||
*/
|
||||
function _transformGuildScheduledEventRecurrenceRule(recurrenceRule) {
|
||||
return {
|
||||
start: new Date(recurrenceRule.startAt).toISOString(),
|
||||
// eslint-disable-next-line eqeqeq
|
||||
end: recurrenceRule.endAt != null ? new Date(recurrenceRule.endAt).toISOString() : recurrenceRule.endAt,
|
||||
frequency: recurrenceRule.frequency,
|
||||
interval: recurrenceRule.interval,
|
||||
by_weekday: recurrenceRule.byWeekday,
|
||||
by_n_weekday: recurrenceRule.byNWeekday,
|
||||
by_month: recurrenceRule.byMonth,
|
||||
by_month_day: recurrenceRule.byMonthDay,
|
||||
by_year_day: recurrenceRule.byYearDay,
|
||||
count: recurrenceRule.count,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
toSnakeCase,
|
||||
_transformAPIAutoModerationAction,
|
||||
_transformAPIMessageInteractionMetadata,
|
||||
_transformGuildScheduledEventRecurrenceRule,
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const { token } = require('./auth.js');
|
||||
const { token, owner } = require('./auth.js');
|
||||
const { Client } = require('../src');
|
||||
const { ChannelType, GatewayIntentBits } = require('discord-api-types/v10');
|
||||
|
||||
@@ -14,6 +14,7 @@ const client = new Client({
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.GuildMessageReactions,
|
||||
GatewayIntentBits.GuildMembers,
|
||||
GatewayIntentBits.MessageContent,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -186,7 +187,7 @@ client.on('messageCreate', msg => {
|
||||
msg.channel.send(`\`\`\`${msg.content}\`\`\``);
|
||||
}
|
||||
|
||||
if (msg.content.startsWith('#eval') && msg.author.id === '66564597481480192') {
|
||||
if (msg.content.startsWith('#eval') && msg.author.id === owner) {
|
||||
try {
|
||||
const com = eval(msg.content.split(' ').slice(1).join(' '));
|
||||
msg.channel.send(`\`\`\`\n${com}\`\`\``);
|
||||
|
||||
41
packages/discord.js/typings/index.d.ts
vendored
41
packages/discord.js/typings/index.d.ts
vendored
@@ -186,6 +186,9 @@ import {
|
||||
ReactionType,
|
||||
APIAuthorizingIntegrationOwnersMap,
|
||||
MessageReferenceType,
|
||||
GuildScheduledEventRecurrenceRuleWeekday,
|
||||
GuildScheduledEventRecurrenceRuleMonth,
|
||||
GuildScheduledEventRecurrenceRuleFrequency,
|
||||
} from 'discord-api-types/v10';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
@@ -1779,6 +1782,7 @@ export class GuildScheduledEvent<Status extends GuildScheduledEventStatus = Guil
|
||||
public entityMetadata: GuildScheduledEventEntityMetadata | null;
|
||||
public userCount: number | null;
|
||||
public creator: User | null;
|
||||
public recurrenceRule: GuildScheduledEventRecurrenceRule | null;
|
||||
public get createdTimestamp(): number;
|
||||
public get createdAt(): Date;
|
||||
public get scheduledStartAt(): Date | null;
|
||||
@@ -1817,6 +1821,26 @@ export class GuildScheduledEvent<Status extends GuildScheduledEventStatus = Guil
|
||||
public isScheduled(): this is GuildScheduledEvent<GuildScheduledEventStatus.Scheduled>;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventRecurrenceRule {
|
||||
startTimestamp: number;
|
||||
get startAt(): Date;
|
||||
endTimestamp: number | null;
|
||||
get endAt(): Date | null;
|
||||
frequency: GuildScheduledEventRecurrenceRuleFrequency;
|
||||
interval: number;
|
||||
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[] | null;
|
||||
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[] | null;
|
||||
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[] | null;
|
||||
byMonthDay: readonly number[] | null;
|
||||
byYearDay: readonly number[] | null;
|
||||
count: number | null;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventRecurrenceRuleNWeekday {
|
||||
n: number;
|
||||
day: GuildScheduledEventRecurrenceRuleWeekday;
|
||||
}
|
||||
|
||||
export class GuildTemplate extends Base {
|
||||
private constructor(client: Client<true>, data: RawGuildTemplateData);
|
||||
public createdTimestamp: number;
|
||||
@@ -6167,14 +6191,29 @@ export interface GuildScheduledEventCreateOptions {
|
||||
entityMetadata?: GuildScheduledEventEntityMetadataOptions;
|
||||
image?: BufferResolvable | Base64Resolvable | null;
|
||||
reason?: string;
|
||||
recurrenceRule?: GuildScheduledEventRecurrenceRuleOptions;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventRecurrenceRuleOptions {
|
||||
startAt: DateResolvable;
|
||||
endAt: DateResolvable;
|
||||
frequency: GuildScheduledEventRecurrenceRuleFrequency;
|
||||
interval: number;
|
||||
byWeekday: readonly GuildScheduledEventRecurrenceRuleWeekday[];
|
||||
byNWeekday: readonly GuildScheduledEventRecurrenceRuleNWeekday[];
|
||||
byMonth: readonly GuildScheduledEventRecurrenceRuleMonth[];
|
||||
byMonthDay: readonly number[];
|
||||
byYearDay: readonly number[];
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventEditOptions<
|
||||
Status extends GuildScheduledEventStatus,
|
||||
AcceptableStatus extends GuildScheduledEventSetStatusArg<Status>,
|
||||
> extends Omit<Partial<GuildScheduledEventCreateOptions>, 'channel'> {
|
||||
> extends Omit<Partial<GuildScheduledEventCreateOptions>, 'channel' | 'recurrenceRule'> {
|
||||
channel?: GuildVoiceChannelResolvable | null;
|
||||
status?: AcceptableStatus;
|
||||
recurrenceRule?: GuildScheduledEventRecurrenceRuleOptions | null;
|
||||
}
|
||||
|
||||
export interface GuildScheduledEventEntityMetadata {
|
||||
|
||||
@@ -209,6 +209,7 @@ import {
|
||||
ApplicationEmoji,
|
||||
ApplicationEmojiManager,
|
||||
StickerPack,
|
||||
GuildScheduledEventManager,
|
||||
SendableChannels,
|
||||
PollData,
|
||||
} from '.';
|
||||
@@ -2618,3 +2619,6 @@ client.on('interactionCreate', interaction => {
|
||||
interaction.channel.send({ embeds: [] });
|
||||
}
|
||||
});
|
||||
|
||||
declare const guildScheduledEventManager: GuildScheduledEventManager;
|
||||
await guildScheduledEventManager.edit(snowflake, { recurrenceRule: null });
|
||||
|
||||
Reference in New Issue
Block a user