Merge Dev into Main (#2345)

* Simplify SfetchMembers (#2339)

Co-authored-by: meister03

* Create leaveVoiceChannel.ts (#2342)

* Update editFollowupMessage.ts (#2344)

* Update editInteractionResponse.ts (#2343)

* Update editMessage.ts (#2341)

* Update calculateShardId.ts

Fix wrong shardId calculations

* Add Role Icon to Edit (#2346)

Co-authored-by: meister03

* Add mix max length (#2347)

Co-authored-by: meister03

* style: deno fmt

* Fix Disabled Options (#2368)

Co-authored-by: meister03 <meisterpi@gmail.com>

* Add app_permissions (#2369)

Co-authored-by: meister03 <meisterpi@gmail.com>

* thread_id instead of threadId (#2378)

Co-authored-by: Veeti K <veeti@veetik.com>

* feat: Create `ApplicationCommandFlags` enumerator. (#2384)

Co-authored-by: vxern <vxern@wordcollector.co.uk>

* Small Changes in a bulk pr to close the issues (#2370)

* Initial Commit

* Close #2364

* Add preset whitelist to automod #2356 -> Resolve Issue

* Close [api-docs] AutoMod message intent updates (#5083) #2330

* Breaking Channge | [api-docs] Update message type names (#5093)

* message.interaction.name changed attitude | [api-docs] Update Change_Log.md #2333

* #2333 also closes #2316

* Clarify 45 chars length | Add those on permission plugins | [api-docs] text input label has max 45 characters (#4689) #2137

* Clarify webhook naming restrictions (#4625) #2094

* 8th August Webhook new View Channel perm | Closes #2363

* 8th August Webhook new View Channel perm | Closes #2363

* Document thread_name for execute webhook (#5007) #2263

* Close Update create and modify channel documentation (#4867) #2237

* unnecesary nullable tag in Modify Guild Member params (#5164) #2355

* deno fmt

* deno fmt

* Use .includefor disallowed webhook names"

* Add Missing Enums & #2367, #2362, #2361, #2371, #2372. #2349, #2358, #2325 back

* deno fmt :(

Co-authored-by: meister03 <meisterpi@gmail.com>
Co-authored-by: LTS20050703 <87189679+lts20050703@users.noreply.github.com>

Co-authored-by: Tomato6966 <chris.pre03@gmail.com>
Co-authored-by: ITOH <to@itoh.at>
Co-authored-by: meister03 <meisterpi@gmail.com>
Co-authored-by: Veeti K <veeti@veetik.com>
Co-authored-by: vxern <vxern@wordcollector.co.uk>
Co-authored-by: LTS20050703 <87189679+lts20050703@users.noreply.github.com>
This commit is contained in:
meister03
2022-08-23 08:46:01 -04:00
committed by GitHub
co-authored by meister03 meister03 Veeti K vxern LTS20050703 Tomato6966 ITOH
parent 03996c5f58
commit aca0e3cf1b
26 changed files with 329 additions and 32 deletions
+1 -1
View File
@@ -112,7 +112,7 @@ const baseBot = createBot({
console.log("Successfully connected to gateway"); console.log("Successfully connected to gateway");
}, },
messageCreate(bot, message) { messageCreate(bot, message) {
// Process the message with your command handler here // Process the message here with your command handler
}, },
}, },
}); });
+3 -1
View File
@@ -20,6 +20,7 @@ export async function createAutomodRule(bot: Bot, guildId: bigint, options: Crea
trigger_metadata: { trigger_metadata: {
keyword_filter: options.triggerMetadata.keywordFilter, keyword_filter: options.triggerMetadata.keywordFilter,
presets: options.triggerMetadata.presets, presets: options.triggerMetadata.presets,
allow_list: options.triggerMetadata.allowList,
}, },
actions: options.actions.map((action) => ({ actions: options.actions.map((action) => ({
type: action.type, type: action.type,
@@ -48,11 +49,12 @@ export interface CreateAutoModerationRuleOptions {
triggerType: AutoModerationTriggerTypes; triggerType: AutoModerationTriggerTypes;
/** The metadata to use for the trigger. */ /** The metadata to use for the trigger. */
triggerMetadata: { triggerMetadata: {
// TODO: discord is considering renaming this before release
/** The keywords needed to match. Only present when TriggerType.Keyword */ /** The keywords needed to match. Only present when TriggerType.Keyword */
keywordFilter?: string[]; keywordFilter?: string[];
/** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */ /** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */
presets?: DiscordAutoModerationRuleTriggerMetadataPresets[]; presets?: DiscordAutoModerationRuleTriggerMetadataPresets[];
/** The substrings which will exempt from triggering the preset trigger type. Only present when TriggerType.KeywordPreset */
allowList?: string[];
}; };
/** The actions that will trigger for this rule */ /** The actions that will trigger for this rule */
actions: { actions: {
+3 -2
View File
@@ -19,6 +19,7 @@ export async function editAutomodRule(bot: Bot, guildId: bigint, options: Partia
? { ? {
keyword_filter: options.triggerMetadata.keywordFilter, keyword_filter: options.triggerMetadata.keywordFilter,
presets: options.triggerMetadata.presets, presets: options.triggerMetadata.presets,
allow_list: options.triggerMetadata.allowList,
} }
: undefined, : undefined,
actions: options.actions?.map((action) => ({ actions: options.actions?.map((action) => ({
@@ -44,13 +45,13 @@ export interface EditAutoModerationRuleOptions {
eventType: AutoModerationEventTypes; eventType: AutoModerationEventTypes;
/** The metadata to use for the trigger. */ /** The metadata to use for the trigger. */
triggerMetadata: { triggerMetadata: {
// TODO: discord is considering renaming this before release
/** The keywords needed to match. Only present when TriggerType.Keyword */ /** The keywords needed to match. Only present when TriggerType.Keyword */
keywordFilter?: string[]; keywordFilter?: string[];
// TODO: discord is considering renaming this before release
// TODO: This may need a special type or enum // TODO: This may need a special type or enum
/** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */ /** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */
presets?: DiscordAutoModerationRuleTriggerMetadataPresets[]; presets?: DiscordAutoModerationRuleTriggerMetadataPresets[];
/** The substrings which will exempt from triggering the preset trigger type. Only present when TriggerType.KeywordPreset */
allowList?: string[];
}; };
/** The actions that will trigger for this rule */ /** The actions that will trigger for this rule */
actions: { actions: {
@@ -62,6 +62,8 @@ export function makeOptionsForCommand(options: ApplicationCommandOption[]): Disc
autocomplete: option.autocomplete, autocomplete: option.autocomplete,
min_value: option.minValue, min_value: option.minValue,
max_value: option.maxValue, max_value: option.maxValue,
min_length: option.minLength,
max_length: option.maxLength,
})); }));
} }
@@ -62,6 +62,7 @@ export async function editInteractionResponse(
placeholder: subComponent.placeholder, placeholder: subComponent.placeholder,
min_values: subComponent.minValues, min_values: subComponent.minValues,
max_values: subComponent.maxValues, max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
@@ -59,6 +59,7 @@ export async function editFollowupMessage(
placeholder: subComponent.placeholder, placeholder: subComponent.placeholder,
min_values: subComponent.minValues, min_values: subComponent.minValues,
max_values: subComponent.maxValues, max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
@@ -2,7 +2,7 @@ import type { Bot } from "../../bot.ts";
import { Embed } from "../../mod.ts"; import { Embed } from "../../mod.ts";
import { DiscordMessage } from "../../types/discord.ts"; import { DiscordMessage } from "../../types/discord.ts";
import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts"; import { AllowedMentions, FileContent, MessageComponents } from "../../types/discordeno.ts";
import { InteractionResponseTypes, MessageComponentTypes } from "../../types/shared.ts"; import { InteractionResponseTypes } from "../../types/shared.ts";
/** /**
* Send a response to a users application command. The command data will have the id and token necessary to respond. * Send a response to a users application command. The command data will have the id and token necessary to respond.
@@ -99,6 +99,14 @@ export interface InteractionApplicationCommandCallbackData {
choices?: ApplicationCommandOptionChoice[]; choices?: ApplicationCommandOptionChoice[];
} }
/* https://discord.com/developers/docs/resources/channel#message-object-message-flags */
export enum ApplicationCommandFlags {
/* Do not include any embeds when serialising this message */
SuppressEmbeds = 1 << 2,
/** Only visible to the user who invoked the interaction */
Ephemeral = 1 << 6,
}
/** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice */ /** https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice */
export interface ApplicationCommandOptionChoice { export interface ApplicationCommandOptionChoice {
/** 1-100 character choice name */ /** 1-100 character choice name */
+3 -1
View File
@@ -1,5 +1,6 @@
import type { Bot } from "../../bot.ts"; import type { Bot } from "../../bot.ts";
import { GatewayIntents, GatewayOpcodes } from "../../types/shared.ts"; import { GatewayIntents, GatewayOpcodes } from "../../types/shared.ts";
import { calculateShardId } from "../../util/calculateShardId.ts";
/** /**
* Highly recommended to use this function to fetch members instead of getMember from REST. * Highly recommended to use this function to fetch members instead of getMember from REST.
@@ -9,7 +10,6 @@ import { GatewayIntents, GatewayOpcodes } from "../../types/shared.ts";
export function fetchMembers( export function fetchMembers(
bot: Bot, bot: Bot,
guildId: bigint, guildId: bigint,
shardId: number,
options?: Omit<RequestGuildMembers, "guildId">, options?: Omit<RequestGuildMembers, "guildId">,
) { ) {
// You can request 1 member without the intent // You can request 1 member without the intent
@@ -22,6 +22,8 @@ export function fetchMembers(
options.limit = options.userIds.length; options.limit = options.userIds.length;
} }
const shardId = calculateShardId(bot.gateway, guildId);
return new Promise((resolve) => { return new Promise((resolve) => {
const nonce = `${guildId}-${Date.now()}`; const nonce = `${guildId}-${Date.now()}`;
bot.cache.fetchAllMembersProcessingRequests.set(nonce, resolve); bot.cache.fetchAllMembersProcessingRequests.set(nonce, resolve);
+1
View File
@@ -53,6 +53,7 @@ export async function editMessage(bot: Bot, channelId: bigint, messageId: bigint
placeholder: subComponent.placeholder, placeholder: subComponent.placeholder,
min_values: subComponent.minValues, min_values: subComponent.minValues,
max_values: subComponent.maxValues, max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
+1
View File
@@ -45,6 +45,7 @@ export async function sendMessage(bot: Bot, channelId: bigint, content: CreateMe
placeholder: subComponent.placeholder, placeholder: subComponent.placeholder,
min_values: subComponent.minValues, min_values: subComponent.minValues,
max_values: subComponent.maxValues, max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
+5 -1
View File
@@ -13,7 +13,9 @@ export async function editRole(bot: Bot, guildId: bigint, id: bigint, options: E
color: options.color, color: options.color,
hoist: options.hoist, hoist: options.hoist,
mentionable: options.mentionable, mentionable: options.mentionable,
permissions: options.permissions ? bot.utils.calculateBits(options.permissions) : undefined, permissions: bot.utils.calculateBits(options?.permissions || []),
icon: options.icon,
unicode_emoji: options.unicodeEmoji,
}, },
); );
@@ -33,4 +35,6 @@ export interface EditGuildRole {
mentionable?: boolean; mentionable?: boolean;
/** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */ /** The role's unicode emoji (if the guild has the `ROLE_ICONS` feature) */
unicodeEmoji?: string; unicodeEmoji?: string;
/** the role's icon image (if the guild has the `ROLE_ICONS` feature) */
icon?: string;
} }
+24
View File
@@ -0,0 +1,24 @@
import type { Bot } from "../../bot.ts";
import { AtLeastOne, GatewayOpcodes } from "../../types/shared.ts";
/** Connect or join a voice channel inside a guild. By default, the "selfDeaf" option is true. Requires `CONNECT` and `VIEW_CHANNEL` permissions. */
export async function connectToVoiceChannel(
bot: Bot,
guildId: bigint,
) {
const shardId = bot.utils.calculateShardId(bot.gateway, guildId);
const shard = bot.gateway.manager.shards.get(shardId);
if (!shard) {
throw new Error(`Shard (id: ${shardId} not found`);
}
shard.send({
op: GatewayOpcodes.VoiceStateUpdate,
d: {
guild_id: guildId.toString(),
channel_id: null,
self_mute: false,
self_deaf: false,
},
});
}
+1
View File
@@ -62,6 +62,7 @@ export async function editWebhookMessage(
placeholder: subComponent.placeholder, placeholder: subComponent.placeholder,
min_values: subComponent.minValues, min_values: subComponent.minValues,
max_values: subComponent.maxValues, max_values: subComponent.maxValues,
disabled: "disabled" in subComponent ? subComponent.disabled : undefined,
options: subComponent.options.map((option) => ({ options: subComponent.options.map((option) => ({
label: option.label, label: option.label,
value: option.value, value: option.value,
+3
View File
@@ -21,6 +21,7 @@ export async function sendWebhook(bot: Bot, webhookId: bigint, webhookToken: str
{ {
wait: options.wait, wait: options.wait,
thread_id: options.threadId, thread_id: options.threadId,
thread_name: options.threadName,
content: options.content, content: options.content,
username: options.username, username: options.username,
avatar_url: options.avatarUrl, avatar_url: options.avatarUrl,
@@ -42,6 +43,8 @@ export interface ExecuteWebhook {
wait?: boolean; wait?: boolean;
/** Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived. */ /** Send a message to the specified thread within a webhook's channel. The thread will automatically be unarchived. */
threadId?: bigint; threadId?: bigint;
/** Name of the thread to create (target channel has to be type of forum channel) */
threadName?: string;
/** The message contents (up to 2000 characters) */ /** The message contents (up to 2000 characters) */
content?: string; content?: string;
/** Override the default username of the webhook */ /** Override the default username of the webhook */
+49
View File
@@ -140,6 +140,55 @@ export function validateComponents(bot: Bot, components: MessageComponents) {
option.emoji = makeEmojiFromString(option.emoji); option.emoji = makeEmojiFromString(option.emoji);
} }
} }
if (subComponent.type === MessageComponentTypes.InputText) {
// Other buttons must have a customId
if (
!subComponent.customId
) {
throw new Error(
"The text input requires a custom id",
);
}
if (!bot.utils.validateLength(subComponent.label, { max: 45 })) {
throw new Error("The label can not be longer than 45 characters.");
}
if (subComponent.minLength) {
if (subComponent.minLength < 0) {
throw new Error(
"The min length must be more than 0 in a text input component.",
);
}
if (subComponent.minLength > 4000) {
throw new Error(
"The min length must be less than 4000 in a text input component.",
);
}
if (subComponent.maxLength && subComponent.minLength > subComponent.maxLength) {
throw new Error(
"The text input component can not have a higher min length than the max length.",
);
}
}
if (subComponent.maxLength) {
if (subComponent.maxLength < 1) {
throw new Error(
"The max length must be more than 1 in a text input component.",
);
}
if (subComponent.maxLength > 4000) {
throw new Error(
"The max length must be less than 4000 in a text input component.",
);
}
}
}
} }
} }
} }
@@ -5,15 +5,20 @@ export default function createWebhook(bot: BotWithCache) {
const createWebhookOld = bot.helpers.createWebhook; const createWebhookOld = bot.helpers.createWebhook;
bot.helpers.createWebhook = async function (channelId, options) { bot.helpers.createWebhook = async function (channelId, options) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]); requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS", "VIEW_CHANNEL"]);
if ( if (
// Specific usernames that discord does not allow // Specific usernames that discord does not allow
options.name === "clyde" || ["clyde", "everyone", "here"].includes(options.name) ||
options.name.includes("discord") ||
options.name.includes("@") ||
options.name.includes("#") ||
options.name.includes(":") ||
options.name.includes("\/") ||
!bot.utils.validateLength(options.name, { min: 2, max: 32 }) !bot.utils.validateLength(options.name, { min: 2, max: 32 })
) { ) {
throw new Error( throw new Error(
"The webhook name can not be clyde and it must be between 2 and 32 characters long.", "The webhook name can not be clyde, everyone, here or include 'discord, @, #, :, ' and it must be between 2 and 32 characters long.",
); );
} }
@@ -5,7 +5,7 @@ export default function deleteWebhook(bot: BotWithCache) {
const deleteWebhookOld = bot.helpers.deleteWebhook; const deleteWebhookOld = bot.helpers.deleteWebhook;
bot.helpers.deleteWebhook = async function (channelId, options) { bot.helpers.deleteWebhook = async function (channelId, options) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]); requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS", "VIEW_CHANNEL"]);
return await deleteWebhookOld(channelId, options); return await deleteWebhookOld(channelId, options);
}; };
@@ -5,8 +5,8 @@ export default function editWebhook(bot: BotWithCache) {
const editWebhookOld = bot.helpers.editWebhook; const editWebhookOld = bot.helpers.editWebhook;
bot.helpers.editWebhook = async function (webhookId, options, fromChannelId) { bot.helpers.editWebhook = async function (webhookId, options, fromChannelId) {
if (options.channelId) requireBotChannelPermissions(bot, options.channelId, ["MANAGE_WEBHOOKS"]); if (options.channelId) requireBotChannelPermissions(bot, options.channelId, ["MANAGE_WEBHOOKS", "VIEW_CHANNEL"]);
if (fromChannelId) requireBotChannelPermissions(bot, fromChannelId, ["MANAGE_WEBHOOKS"]); if (fromChannelId) requireBotChannelPermissions(bot, fromChannelId, ["MANAGE_WEBHOOKS", "VIEW_CHANNEL"]);
if (options.name) { if (options.name) {
if ( if (
+6 -1
View File
@@ -20,7 +20,8 @@ export function transformApplicationCommandOption(
channelTypes: payload.channel_types, channelTypes: payload.channel_types,
minValue: payload.min_value, minValue: payload.min_value,
maxValue: payload.max_value, maxValue: payload.max_value,
minLength: payload.min_length,
maxLength: payload.max_length,
options: payload.options?.map((option) => bot.transformers.applicationCommandOption(bot, option)), options: payload.options?.map((option) => bot.transformers.applicationCommandOption(bot, option)),
}; };
} }
@@ -52,4 +53,8 @@ export interface ApplicationCommandOption {
minValue?: number; minValue?: number;
/** Maximum number desired. */ /** Maximum number desired. */
maxValue?: number; maxValue?: number;
/** Minimum length desired. */
minLength?: number;
/** Maximum length desired. */
maxLength?: number;
} }
+1
View File
@@ -17,6 +17,7 @@ export function transformAutoModerationRule(bot: Bot, payload: DiscordAutoModera
? { ? {
keywordFilter: payload.trigger_metadata.keyword_filter, keywordFilter: payload.trigger_metadata.keyword_filter,
presets: payload.trigger_metadata.presets, presets: payload.trigger_metadata.presets,
allowList: payload.trigger_metadata.allow_list,
} }
: undefined, : undefined,
actions: payload.actions.map((action) => ({ actions: payload.actions.map((action) => ({
+1
View File
@@ -30,6 +30,7 @@ export function transformInteraction(bot: Bot, payload: DiscordInteraction) {
user, user,
id: bot.transformers.snowflake(payload.id), id: bot.transformers.snowflake(payload.id),
applicationId: bot.transformers.snowflake(payload.application_id), applicationId: bot.transformers.snowflake(payload.application_id),
appPermissions: payload.app_permissions ? bot.transformers.snowflake(payload.app_permissions) : undefined,
message: payload.message ? bot.transformers.message(bot, payload.message) : undefined, message: payload.message ? bot.transformers.message(bot, payload.message) : undefined,
channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined, channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined,
member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, user.id) : undefined, member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId, user.id) : undefined,
+16 -8
View File
@@ -219,7 +219,7 @@ export interface DiscordMember {
premium_since?: string | null; premium_since?: string | null;
/** The permissions this member has in the guild. Only present on interaction events. */ /** The permissions this member has in the guild. Only present on interaction events. */
permissions?: string; permissions?: string;
/** when the user's timeout will expire and the user will be able to communicate in the guild again, null or a time in the past if the user is not timed out */ /** when the user's timeout will expire and the user will be able to communicate in the guild again (set null to remove timeout), null or a time in the past if the user is not timed out */
communication_disabled_until?: string | null; communication_disabled_until?: string | null;
} }
@@ -709,13 +709,13 @@ export interface DiscordChannel {
name?: string; name?: string;
/** The channel topic (0-1024 characters) */ /** The channel topic (0-1024 characters) */
topic?: string | null; topic?: string | null;
/** The bitrate (in bits) of the voice channel */ /** The bitrate (in bits) of the voice or stage channel */
bitrate?: number; bitrate?: number;
/** The user limit of the voice channel */ /** The user limit of the voice or stage channel */
user_limit?: number; user_limit?: number;
/** Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `manage_messages` or `manage_channel`, are unaffected */ /** Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `manage_messages` or `manage_channel`, are unaffected */
rate_limit_per_user?: number; rate_limit_per_user?: number;
/** Voice region id for the voice channel, automatic when set to null */ /** Voice region id for the voice or stage channel, automatic when set to null */
rtc_region?: string | null; rtc_region?: string | null;
/** The camera video quality mode of the voice channel, 1 when not present */ /** The camera video quality mode of the voice channel, 1 when not present */
video_quality_mode?: VideoQualityModes; video_quality_mode?: VideoQualityModes;
@@ -1121,7 +1121,7 @@ export interface DiscordMessageInteraction {
id: string; id: string;
/** The type of interaction */ /** The type of interaction */
type: InteractionTypes; type: InteractionTypes;
/** The name of the ApplicationCommand */ /** The name of the ApplicationCommand including the name of the subcommand/subcommand group*/
name: string; name: string;
/** The user who invoked the interaction */ /** The user who invoked the interaction */
user: DiscordUser; user: DiscordUser;
@@ -1217,7 +1217,7 @@ export interface DiscordInputTextComponent {
style: TextStyles; style: TextStyles;
/** The customId of the InputText */ /** The customId of the InputText */
custom_id: string; custom_id: string;
/** The label of the InputText */ /** The label of the InputText (max 45 characters)*/
label: string; label: string;
/** The placeholder of the InputText */ /** The placeholder of the InputText */
placeholder?: string; placeholder?: string;
@@ -1286,6 +1286,8 @@ export interface DiscordInteraction {
locale?: string; locale?: string;
/** The guild's preferred locale, if invoked in a guild */ /** The guild's preferred locale, if invoked in a guild */
guild_locale?: string; guild_locale?: string;
/** The computed permissions for a bot or app in the context of a specific interaction (including channel overwrites) */
app_permissions: string;
} }
/** https://discord.com/developers/docs/resources/guild#guild-member-object */ /** https://discord.com/developers/docs/resources/guild#guild-member-object */
@@ -1407,7 +1409,7 @@ export interface DiscordAuditLog {
export interface DiscordAutoModerationRule { export interface DiscordAutoModerationRule {
/** The id of this rule */ /** The id of this rule */
id: string; id: string;
/** The guild id */ /** The guild id of the rule */
guild_id: string; guild_id: string;
/** The name of the rule */ /** The name of the rule */
name: string; name: string;
@@ -1447,6 +1449,8 @@ export interface DiscordAutoModerationRuleTriggerMetadata {
keyword_filter?: string[]; keyword_filter?: string[];
/** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */ /** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */
presets?: DiscordAutoModerationRuleTriggerMetadataPresets[]; presets?: DiscordAutoModerationRuleTriggerMetadataPresets[];
/** The substrings which will exempt from triggering the preset trigger type. Only present when TriggerType.KeywordPreset */
allow_list: string[];
} }
export enum DiscordAutoModerationRuleTriggerMetadataPresets { export enum DiscordAutoModerationRuleTriggerMetadataPresets {
@@ -1502,7 +1506,7 @@ export interface DiscordAutoModerationActionExecution {
alert_system_message_id?: string | null; alert_system_message_id?: string | null;
/** The word or phrase that triggerred the rule. */ /** The word or phrase that triggerred the rule. */
matched_keyword: string | null; matched_keyword: string | null;
/** The substring in content that triggered rule */ /** The substring in content that triggered the rule */
matched_content: string | null; matched_content: string | null;
} }
@@ -1862,6 +1866,10 @@ export interface DiscordApplicationCommandOption {
min_value?: number; min_value?: number;
/** If the option type is `ApplicationCommandOptionTypes.Integer` or `ApplicationCommandOptionTypes.Number`, the maximum permitted value */ /** If the option type is `ApplicationCommandOptionTypes.Integer` or `ApplicationCommandOptionTypes.Number`, the maximum permitted value */
max_value?: number; max_value?: number;
/** If the option type is `ApplicationCommandOptionTypes.String`, the minimum permitted length */
min_length?: number;
/** If the option type is `ApplicationCommandOptionTypes.String`, the maximum permitted length */
max_length?: number;
} }
/** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-choice-structure */ /** https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-choice-structure */
+3 -1
View File
@@ -54,6 +54,8 @@ export interface SelectMenuComponent {
maxValues?: number; maxValues?: number;
/** The choices! Maximum of 25 items. */ /** The choices! Maximum of 25 items. */
options: SelectOption[]; options: SelectOption[];
/** Whether or not this select is disabled */
disabled?: boolean;
} }
export interface SelectOption { export interface SelectOption {
@@ -84,7 +86,7 @@ export interface InputTextComponent {
style: TextStyles; style: TextStyles;
/** The customId of the InputText */ /** The customId of the InputText */
customId: string; customId: string;
/** The label of the InputText */ /** The label of the InputText. Maximum 45 characters */
label: string; label: string;
/** The placeholder of the InputText */ /** The placeholder of the InputText */
placeholder?: string; placeholder?: string;
+180 -5
View File
@@ -316,11 +316,11 @@ export enum MessageTypes {
ChannelNameChange, ChannelNameChange,
ChannelIconChange, ChannelIconChange,
ChannelPinnedMessage, ChannelPinnedMessage,
GuildMemberJoin, UserJoin,
UserPremiumGuildSubscription, GuildBoost,
UserPremiumGuildSubscriptionTier1, GuildBoostTier1,
UserPremiumGuildSubscriptionTier2, GuildBoostTier2,
UserPremiumGuildSubscriptionTier3, GuildBoostTier3,
ChannelFollowAdd, ChannelFollowAdd,
GuildDiscoveryDisqualified = 14, GuildDiscoveryDisqualified = 14,
GuildDiscoveryRequalified, GuildDiscoveryRequalified,
@@ -738,6 +738,181 @@ export enum RpcCloseEventCodes {
InvalidEncoding, InvalidEncoding,
} }
/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#json */
export enum JsonErrorCodes {
/** General error (such as a malformed request body, amongst other things) */
GeneralError,
UnknownAccount = 10001,
UnknownApplication,
UnknownChannel,
UnknownGuild,
UnknownIntegration,
UnknownInvite,
UnknownMember,
UnknownMessage,
UnknownPermissionOverwrite,
UnknownProvider,
UnknownRole,
UnknownToken,
UnknownUser,
UnknownEmoji,
UnknownWebhook,
UnknownWebhookService,
UnknownSession = 10020,
UnknownBan = 10026,
UnknownSKU,
UnknownStoreListing,
UnknownEntitlement,
UnknownBuild,
UnknownLobby,
UnknownBranch,
UnknownStoreDirectoryLayout,
UnknownRedistributable = 10036,
UnknownGiftCode = 10038,
UnknownStream = 10049,
UnknownPremiumServerSubscribeCooldown,
UnknownGuildTemplate = 10057,
UnknownDiscoveryCategory = 10059,
UnknownSticker,
UnknownInteraction = 10062,
UnknownApplicationCommand = 10063,
UnknownVoiceState = 10065,
UnknownApplicationCommandPermissions,
UnknownStageInstance,
UnknownGuildMemberVerificationForm,
UnknownGuildWelcomeScreen,
UnknownGuildScheduledEvent,
UnknownGuildScheduledEventUser,
UnknownTag = 10087,
BotsCannotUseThisEndpoint = 20001,
OnlyBotsCanUseThisEndpoint,
ExplicitContentCannotBeSentToTheDesiredRecipient = 20009,
YouAreNotAuthorizedToPerformThisActionOnThisApplication = 20012,
ThisActionCannotBePerformedDueToSlowmodeRateLimit = 20016,
OnlyTheOwnerOfThisAccountCanPerformThisAction = 20018,
ThisMessageCannotBeEditedDueToAnnouncementRateLimits = 20022,
UnderMinimumAge = 20024,
TheChannelYouAreWritingHasHitTheWriteRateLimit = 20028,
TheWriteActionYouArePerformingOnTheServerHasHitTheWriteRateLimit,
YourStageTopicOrServerNameOrServerDescriptionOrChannelNamesContainsWordsThatAreNotAllowedForPublicStages = 20031,
GuildPremiumSubscriptionLevelTooLow = 20035,
MaximumNumberOfGuildsReached = 30001,
MaximumNumberOfFriendsReached,
MaximumNumberOfPinsReachedForTheChannel,
MaximumNumberOfRecipientsReached,
MaximumNumberOfGuildRolesReached,
MaximumNumberOfWebhooksReached = 30007,
MaximumNumberOfEmojisReached,
MaximumNumberOfReactionsReached = 30010,
MaximumNumberOfGuildChannelsReached = 30013,
MaximumNumberOfAttachmentsInAMessageReached = 30015,
MaximumNumberOfInvitesReached,
MaximumNumberOfAnimatedEmojisReached = 30018,
MaximumNumberOfServerMembersReached,
MaximumNumberOfServerCategoriesHasBeenReached = 30030,
GuildAlreadyHasTemplate,
MaximumNumbersOfApplicationCommandsReached,
MaxNumberOfThreadParticipantsHasBeenReached,
MaxNumberOfDailyApplicationCommandCreatesHasBeenReached,
MaximumNumberOfBansForNonGuildMembersHaveBeenExceeded,
MaximumNumberOfBansFetchesHasBeenReached = 30037,
MaximumNumberOfUncompletedGuildScheduledEventsReached = 30038,
MaximumNumberOfStickersReached = 30039,
MaximumNumberOfPruneRequestsHasBeenReachedTryAgainLater,
MaximumNumberOfGuildWidgetSettingsUpdatesHasBeenReachedTryAgainLater = 30042,
MaximumNumberOfEditsToMessagesOlderThan1HourReachedTryAgainLater = 30046,
MaximumNumberOfPinnedThreadsInAForumChannelHasBeenReached,
MaxiumNumberOfTagsInAForumChannelHasBeenReached,
BitrateIsTooHighForChannelOfThisType = 30052,
UnauthorizedProvideAValidTokenAndTryAgain = 40001,
YouNeedToVerifyYourAccountInOrderToPerformThisAction,
YouAreOpeningDirectMessagesTooFast,
SendMessagesHasBeenTemporarilyDisabled,
RequestEntityTooLargeTrySendingSomethingSmallerInSize,
ThisFeatureHasBeenTemporarilyDisabledServerSide,
ThisUserBannedFromThisGuild,
ConnectionHasBeenRevoked = 40012,
TargetUserIsNotConnectedToVoice = 40032,
ThisMessageHasAlreadyBeenCrossposted,
AnApplicationCommandWithThatNameAlreadyExists = 40041,
ApplicationInteractionFailedToSend = 40043,
InteractionHasAlreadyBeenAcknowledged = 40060,
MissingAccess = 50001,
InvalidAccountType,
CannotExecuteActionOnADMChannel,
GuildWidgetDisabled,
CannotEditMessageAuthoredByAnotherUser,
CannotSendAnEmptyMessage,
CannotSendMessagesToThisUser,
CannotSendMessagesInANonTextChannel,
ChannelVerificationLevelIsTooHighForYouToGainAccess,
OAuth2ApplicationDoesNotHaveABot,
OAuth2ApplicationLimitReached,
InvalidOAuth2State,
YouLackPermissionsToPerformThatAction,
InvalidAuthenticationTokenProvided,
NoteWasTooLong,
ProvidedTooFewOrTooManyMessagesToDeleteMustProvideAtLeast2AndFewerThan100MessagesToDelete,
InvalidMFALevel,
AMessageCanOnlyBePinnedInTheChannelItWasSentIn = 50019,
InviteCodeWasEitherInvalidOrTaken,
CannotExecuteActionOnASystemMessage,
CannotExecuteActionOnThisChannelType = 50024,
InvalidOAuth2AccessTokenProvided,
MissingRequiredOAuth2Scope,
InvalidWebhookTokenProvided,
InvalidRole,
InvalidRecipients = 50033,
AMessageProvidedWasTooOldToBulkDelete,
/** Invalid form body (returned for both `application/json` and `multipart/form-data` bodies), or invalid `Content-Type` provided */
InvalidFormBodyOrContentTypeProvided,
AnInviteWasAcceptedToAGuildTheApplicationsBotIsNotIn,
InvalidApiVersionProvided = 50041,
FileUploadedExceedsTheMaximumSize = 50045,
InvalidFileUploaded,
CannotSelfRedeemThisGift = 50054,
InvalidGuild,
InvalidMessageType = 50068,
PaymentSourceRequiredToRedeemGift = 50070,
CannotDeleteAChannelRequiredForCommunityGuilds = 50074,
CannotEditStickersWithinAMessage = 50080,
InvalidStickerSent,
TriedToPerformAnOperationOnAnArchivedThreadSuchAsEditingAMessageOrAddingAUserToTheThread = 50083,
InvalidThreadNotificationSettings,
BeforeValueIsEarlierThanTheThreadCreationDate,
CommunityServerChannelsMustBeTextChannels,
ThisServerIsNotAvailableInYourLocation = 50095,
ThisServerNeedsMonetizationEnabledInOrderToPerformThisAction = 50097,
ThisServerNeedsMoreBoostsToPerformThisAction = 50101,
TheRequestBodyContainsInvalidJSON = 50109,
OwnershipCannotBeTransferredToABotUser = 50132,
FailedToResizeAssetBelowTheMaximumSize = 50138,
UploadedFileNotFound = 50146,
TwoFactorIsRequiredForThisOperation = 60003,
NoUsersWithDiscordTagExist = 80004,
ReactionWasBlocked = 90001,
ApplicationNotYetAvailable = 110001,
ApiResourceIsCurrentlyOverloadedTryAgainALittleLater = 130000,
TheStageIsAlreadyOpen = 150006,
CannotReplyWithoutPermissionToReadMessageHistory = 160002,
AThreadHasAlreadyBeenCreatedForThisMessage = 160004,
ThreadIsLocked = 160005,
MaximumNumberOfActiveThreadsReached = 160006,
MaximumNumberOfActiveAnnouncementThreadsReached = 160007,
InvalidJsonForUploadedLottieFile = 170001,
UploadedLottiesCannotContainRasterizedImagesSuchAsPngOrJpeg,
StickerMaximumFramerateExceeded,
StickerFrameCountExceedsMaximumOf1000Frames,
LottieAnimationMaximumDimensionsExceeded,
StickerFrameRateIsEitherTooSmallOrTooLarge,
StickerAnimationDurationExceedsMaximumOf5Seconds,
CannotUpdateAFinishedEvent = 180000,
FailedToCreateStageNeededForStageEvent = 180002,
MessageWasBlockedByAutomaticModeration = 200000,
TitleWasBlockedByAutomaticModeration,
WebhooksCanOnlyCreateThreadsInForumChannels = 220003,
}
/** https://discord.com/developers/docs/topics/opcodes-and-status-codes#http */ /** https://discord.com/developers/docs/topics/opcodes-and-status-codes#http */
export enum HTTPResponseCodes { export enum HTTPResponseCodes {
/** The request completed successfully. */ /** The request completed successfully. */
+1 -1
View File
@@ -3,5 +3,5 @@ import { GatewayManager } from "../gateway/manager/gatewayManager.ts";
export function calculateShardId(gateway: GatewayManager, guildId: bigint) { export function calculateShardId(gateway: GatewayManager, guildId: bigint) {
if (gateway.manager.totalShards === 1) return 0; if (gateway.manager.totalShards === 1) return 0;
return Number((guildId >> 22n) % BigInt(gateway.manager.totalShards - 1)); return Number((guildId >> 22n) % BigInt(gateway.manager.totalShards));
} }
+3 -3
View File
@@ -370,7 +370,7 @@ export const routes = {
if (options) { if (options) {
if (options?.wait !== undefined) url += `wait=${options.wait}`; if (options?.wait !== undefined) url += `wait=${options.wait}`;
if (options.threadId) url += `threadId=${options.threadId}`; if (options.threadId) url += `thread_id=${options.threadId}`;
} }
return url; return url;
@@ -382,7 +382,7 @@ export const routes = {
let url = `/webhooks/${webhookId}/${token}/messages/${messageId}?`; let url = `/webhooks/${webhookId}/${token}/messages/${messageId}?`;
if (options) { if (options) {
if (options.threadId) url += `threadId=${options.threadId}`; if (options.threadId) url += `thread_id=${options.threadId}`;
} }
return url; return url;
@@ -391,7 +391,7 @@ export const routes = {
let url = `/webhooks/${webhookId}/${token}/messages/@original?`; let url = `/webhooks/${webhookId}/${token}/messages/@original?`;
if (options) { if (options) {
if (options.threadId) url += `threadId=${options.threadId}`; if (options.threadId) url += `thread_id=${options.threadId}`;
} }
return url; return url;