From d1498c3ce2eaea11c9946726ef758f7de489253b Mon Sep 17 00:00:00 2001 From: ckohen Date: Wed, 2 Jun 2021 00:06:40 -0700 Subject: [PATCH] feat: api v9 and threads (#133) * feat: api v9 and threads * fix: address review comments --- README.md | 14 +- deno/README.md | 14 +- deno/gateway/mod.ts | 2 +- deno/gateway/v9.ts | 1646 ++++++++++++++++++++++++++++++ deno/payloads/mod.ts | 2 +- deno/payloads/v9/auditLog.ts | 576 +++++++++++ deno/payloads/v9/channel.ts | 1048 +++++++++++++++++++ deno/payloads/v9/emoji.ts | 51 + deno/payloads/v9/gateway.ts | 363 +++++++ deno/payloads/v9/guild.ts | 884 ++++++++++++++++ deno/payloads/v9/interactions.ts | 426 ++++++++ deno/payloads/v9/invite.ts | 100 ++ deno/payloads/v9/mod.ts | 14 + deno/payloads/v9/oauth2.ts | 209 ++++ deno/payloads/v9/permissions.ts | 119 +++ deno/payloads/v9/teams.ts | 62 ++ deno/payloads/v9/template.ts | 65 ++ deno/payloads/v9/user.ts | 157 +++ deno/payloads/v9/voice.ts | 96 ++ deno/payloads/v9/webhook.ts | 75 ++ deno/rest/common.ts | 4 + deno/rest/mod.ts | 2 +- deno/rest/v9/auditLog.ts | 28 + deno/rest/v9/channel.ts | 553 ++++++++++ deno/rest/v9/emoji.ts | 61 ++ deno/rest/v9/gateway.ts | 11 + deno/rest/v9/guild.ts | 780 ++++++++++++++ deno/rest/v9/interactions.ts | 147 +++ deno/rest/v9/invite.ts | 22 + deno/rest/v9/mod.ts | 743 ++++++++++++++ deno/rest/v9/oauth2.ts | 199 ++++ deno/rest/v9/template.ts | 70 ++ deno/rest/v9/user.ts | 90 ++ deno/rest/v9/voice.ts | 6 + deno/rest/v9/webhook.ts | 252 +++++ deno/rpc/mod.ts | 2 +- deno/rpc/v9.ts | 33 + deno/utils/mod.ts | 2 +- deno/utils/v9.ts | 48 + deno/v9.ts | 6 + gateway/index.ts | 2 +- gateway/v9.ts | 1646 ++++++++++++++++++++++++++++++ package.json | 10 +- payloads/index.ts | 2 +- payloads/v9/auditLog.ts | 576 +++++++++++ payloads/v9/channel.ts | 1048 +++++++++++++++++++ payloads/v9/emoji.ts | 51 + payloads/v9/gateway.ts | 363 +++++++ payloads/v9/guild.ts | 884 ++++++++++++++++ payloads/v9/index.ts | 14 + payloads/v9/interactions.ts | 426 ++++++++ payloads/v9/invite.ts | 100 ++ payloads/v9/oauth2.ts | 209 ++++ payloads/v9/permissions.ts | 119 +++ payloads/v9/teams.ts | 62 ++ payloads/v9/template.ts | 65 ++ payloads/v9/user.ts | 157 +++ payloads/v9/voice.ts | 96 ++ payloads/v9/webhook.ts | 75 ++ rest/common.ts | 4 + rest/index.ts | 2 +- rest/v9/auditLog.ts | 28 + rest/v9/channel.ts | 553 ++++++++++ rest/v9/emoji.ts | 61 ++ rest/v9/gateway.ts | 11 + rest/v9/guild.ts | 780 ++++++++++++++ rest/v9/index.ts | 743 ++++++++++++++ rest/v9/interactions.ts | 147 +++ rest/v9/invite.ts | 22 + rest/v9/oauth2.ts | 199 ++++ rest/v9/template.ts | 70 ++ rest/v9/user.ts | 90 ++ rest/v9/voice.ts | 6 + rest/v9/webhook.ts | 252 +++++ rpc/index.ts | 2 +- rpc/v9.ts | 33 + scripts/deno.mjs | 1 + scripts/versions.mjs | 1 + tsconfig.eslint.json | 1 + tsconfig.json | 1 + utils/index.ts | 2 +- utils/v9.ts | 48 + v9.ts | 6 + 83 files changed, 17923 insertions(+), 27 deletions(-) create mode 100644 deno/gateway/v9.ts create mode 100644 deno/payloads/v9/auditLog.ts create mode 100644 deno/payloads/v9/channel.ts create mode 100644 deno/payloads/v9/emoji.ts create mode 100644 deno/payloads/v9/gateway.ts create mode 100644 deno/payloads/v9/guild.ts create mode 100644 deno/payloads/v9/interactions.ts create mode 100644 deno/payloads/v9/invite.ts create mode 100644 deno/payloads/v9/mod.ts create mode 100644 deno/payloads/v9/oauth2.ts create mode 100644 deno/payloads/v9/permissions.ts create mode 100644 deno/payloads/v9/teams.ts create mode 100644 deno/payloads/v9/template.ts create mode 100644 deno/payloads/v9/user.ts create mode 100644 deno/payloads/v9/voice.ts create mode 100644 deno/payloads/v9/webhook.ts create mode 100644 deno/rest/v9/auditLog.ts create mode 100644 deno/rest/v9/channel.ts create mode 100644 deno/rest/v9/emoji.ts create mode 100644 deno/rest/v9/gateway.ts create mode 100644 deno/rest/v9/guild.ts create mode 100644 deno/rest/v9/interactions.ts create mode 100644 deno/rest/v9/invite.ts create mode 100644 deno/rest/v9/mod.ts create mode 100644 deno/rest/v9/oauth2.ts create mode 100644 deno/rest/v9/template.ts create mode 100644 deno/rest/v9/user.ts create mode 100644 deno/rest/v9/voice.ts create mode 100644 deno/rest/v9/webhook.ts create mode 100644 deno/rpc/v9.ts create mode 100644 deno/utils/v9.ts create mode 100644 deno/v9.ts create mode 100644 gateway/v9.ts create mode 100644 payloads/v9/auditLog.ts create mode 100644 payloads/v9/channel.ts create mode 100644 payloads/v9/emoji.ts create mode 100644 payloads/v9/gateway.ts create mode 100644 payloads/v9/guild.ts create mode 100644 payloads/v9/index.ts create mode 100644 payloads/v9/interactions.ts create mode 100644 payloads/v9/invite.ts create mode 100644 payloads/v9/oauth2.ts create mode 100644 payloads/v9/permissions.ts create mode 100644 payloads/v9/teams.ts create mode 100644 payloads/v9/template.ts create mode 100644 payloads/v9/user.ts create mode 100644 payloads/v9/voice.ts create mode 100644 payloads/v9/webhook.ts create mode 100644 rest/v9/auditLog.ts create mode 100644 rest/v9/channel.ts create mode 100644 rest/v9/emoji.ts create mode 100644 rest/v9/gateway.ts create mode 100644 rest/v9/guild.ts create mode 100644 rest/v9/index.ts create mode 100644 rest/v9/interactions.ts create mode 100644 rest/v9/invite.ts create mode 100644 rest/v9/oauth2.ts create mode 100644 rest/v9/template.ts create mode 100644 rest/v9/user.ts create mode 100644 rest/v9/voice.ts create mode 100644 rest/v9/webhook.ts create mode 100644 rpc/v9.ts create mode 100644 utils/v9.ts create mode 100644 v9.ts diff --git a/README.md b/README.md index f446c9db..e0ab3b34 100644 --- a/README.md +++ b/README.md @@ -24,23 +24,23 @@ pnpm add discord-api-types You can only import this module by specifying the API version you want to target. Append `/v*` to the import path, where the `*` represents the API version. Below are some examples ```js -const { APIUser } = require('discord-api-types/v8'); +const { APIUser } = require('discord-api-types/v9'); ``` ```ts // TypeScript/ES Module support -import { APIUser } from 'discord-api-types/v8'; +import { APIUser } from 'discord-api-types/v9'; ``` You may also import just certain parts of the module that you need. The possible values are: `globals`, `gateway`, `gateway/v*`, `payloads`, `payloads/v*`, `rest`, `rest/v*`, `rpc`, `rpc/v*`, `utils`, `utils/v*`, `voice`, and `voice/v*`. Below are some examples ```js -const { GatewayVersion } = require('discord-api-types/gateway/v8'); +const { GatewayVersion } = require('discord-api-types/gateway/v9'); ``` ```ts // TypeScript/ES Module support -import { GatewayVersion } from 'discord-api-types/gateway/v8'; +import { GatewayVersion } from 'discord-api-types/gateway/v9'; ``` > _**Note:** The `v*` exports (`discord-api-type/v*`) include the appropriate version of `gateway`, `payloads`, `rest`, `rpc`, and `utils` you specified, alongside the `globals` exports_ @@ -53,21 +53,21 @@ We also provide typings compatible with the [deno](https://deno.land/) runtime. ```ts // Importing a specific API version -import { APIUser } from 'https://raw.githubusercontent.com/discordjs/discord-api-types/main/deno/v8.ts'; +import { APIUser } from 'https://raw.githubusercontent.com/discordjs/discord-api-types/main/deno/v9.ts'; ``` 2. From [deno.land/x](https://deno.land/x) ```ts // Importing a specific API version -import { APIUser } from 'https://deno.land/x/discord_api_types/v8.ts'; +import { APIUser } from 'https://deno.land/x/discord_api_types/v9.ts'; ``` 3. From [skypack.dev](https://www.skypack.dev/) ```ts // Importing a specific API version -import { APIUser } from 'https://cdn.skypack.dev/discord-api-types/v8?dts'; +import { APIUser } from 'https://cdn.skypack.dev/discord-api-types/v9?dts'; ``` ## Project Structure diff --git a/deno/README.md b/deno/README.md index f446c9db..e0ab3b34 100644 --- a/deno/README.md +++ b/deno/README.md @@ -24,23 +24,23 @@ pnpm add discord-api-types You can only import this module by specifying the API version you want to target. Append `/v*` to the import path, where the `*` represents the API version. Below are some examples ```js -const { APIUser } = require('discord-api-types/v8'); +const { APIUser } = require('discord-api-types/v9'); ``` ```ts // TypeScript/ES Module support -import { APIUser } from 'discord-api-types/v8'; +import { APIUser } from 'discord-api-types/v9'; ``` You may also import just certain parts of the module that you need. The possible values are: `globals`, `gateway`, `gateway/v*`, `payloads`, `payloads/v*`, `rest`, `rest/v*`, `rpc`, `rpc/v*`, `utils`, `utils/v*`, `voice`, and `voice/v*`. Below are some examples ```js -const { GatewayVersion } = require('discord-api-types/gateway/v8'); +const { GatewayVersion } = require('discord-api-types/gateway/v9'); ``` ```ts // TypeScript/ES Module support -import { GatewayVersion } from 'discord-api-types/gateway/v8'; +import { GatewayVersion } from 'discord-api-types/gateway/v9'; ``` > _**Note:** The `v*` exports (`discord-api-type/v*`) include the appropriate version of `gateway`, `payloads`, `rest`, `rpc`, and `utils` you specified, alongside the `globals` exports_ @@ -53,21 +53,21 @@ We also provide typings compatible with the [deno](https://deno.land/) runtime. ```ts // Importing a specific API version -import { APIUser } from 'https://raw.githubusercontent.com/discordjs/discord-api-types/main/deno/v8.ts'; +import { APIUser } from 'https://raw.githubusercontent.com/discordjs/discord-api-types/main/deno/v9.ts'; ``` 2. From [deno.land/x](https://deno.land/x) ```ts // Importing a specific API version -import { APIUser } from 'https://deno.land/x/discord_api_types/v8.ts'; +import { APIUser } from 'https://deno.land/x/discord_api_types/v9.ts'; ``` 3. From [skypack.dev](https://www.skypack.dev/) ```ts // Importing a specific API version -import { APIUser } from 'https://cdn.skypack.dev/discord-api-types/v8?dts'; +import { APIUser } from 'https://cdn.skypack.dev/discord-api-types/v9?dts'; ``` ## Project Structure diff --git a/deno/gateway/mod.ts b/deno/gateway/mod.ts index e7137942..d6ad52a0 100644 --- a/deno/gateway/mod.ts +++ b/deno/gateway/mod.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended gateway version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8.ts'; +export * from './v9.ts'; diff --git a/deno/gateway/v9.ts b/deno/gateway/v9.ts new file mode 100644 index 00000000..720dcda8 --- /dev/null +++ b/deno/gateway/v9.ts @@ -0,0 +1,1646 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/gateway + */ + +import type { Snowflake } from '../globals.ts'; +import type { + APIApplication, + APIApplicationCommand, + APIApplicationCommandInteraction, + APIChannel, + APIEmoji, + APIGuild, + APIGuildIntegration, + APIGuildMember, + APIMessage, + APIRole, + APIThreadMember, + APIUnavailableGuild, + APIUser, + GatewayActivity, + GatewayPresenceUpdate as RawGatewayPresenceUpdate, + GatewayThreadListSync as RawGatewayThreadListSync, + GatewayThreadMembersUpdate as RawGatewayThreadMembersUpdate, + GatewayVoiceState, + InviteTargetType, + PresenceUpdateStatus, +} from '../payloads/v9/mod.ts'; + +export * from './common.ts'; + +export const GatewayVersion = '9'; + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes + */ +export enum GatewayOpcodes { + /** + * An event was dispatched + */ + Dispatch, + /** + * A bidirectional opcode to maintain an active gateway connection. + * Fired periodically by the client, or fired by the gateway to request an immediate heartbeat from the client. + */ + Heartbeat, + /** + * Starts a new session during the initial handshake + */ + Identify, + /** + * Update the client's presence + */ + PresenceUpdate, + /** + * Used to join/leave or move between voice channels + */ + VoiceStateUpdate, + /** + * Resume a previous session that was disconnected + */ + Resume = 6, + /** + * You should attempt to reconnect and resume immediately + */ + Reconnect, + /** + * Request information about offline guild members in a large guild + */ + RequestGuildMembers, + /** + * The session has been invalidated. You should reconnect and identify/resume accordingly + */ + InvalidSession, + /** + * Sent immediately after connecting, contains the `heartbeat_interval` to use + */ + Hello, + /** + * Sent in response to receiving a heartbeat to acknowledge that it has been received + */ + HeartbeatAck, +} + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes + */ +export enum GatewayCloseCodes { + /** + * We're not sure what went wrong. Try reconnecting? + */ + UnknownError = 4000, + /** + * You sent an invalid Gateway opcode or an invalid payload for an opcode. Don't do that! + * + * See https://discord.com/developers/docs/topics/gateway#payloads-and-opcodes + */ + UnknownOpcode, + /** + * You sent an invalid payload to us. Don't do that! + * + * See https://discord.com/developers/docs/topics/gateway#sending-payloads + */ + DecodeError, + /** + * You sent us a payload prior to identifying + * + * See https://discord.com/developers/docs/topics/gateway#identify + */ + NotAuthenticated, + /** + * The account token sent with your identify payload is incorrect + * + * See https://discord.com/developers/docs/topics/gateway#identify + */ + AuthenticationFailed, + /** + * You sent more than one identify payload. Don't do that! + */ + AlreadyAuthenticated, + /** + * The sequence sent when resuming the session was invalid. Reconnect and start a new session + * + * See https://discord.com/developers/docs/topics/gateway#resume + */ + InvalidSeq = 4007, + /** + * Woah nelly! You're sending payloads to us too quickly. Slow it down! You will be disconnected on receiving this + */ + RateLimited, + /** + * Your session timed out. Reconnect and start a new one + */ + SessionTimedOut, + /** + * You sent us an invalid shard when identifying + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + InvalidShard, + /** + * The session would have handled too many guilds - you are required to shard your connection in order to connect + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + ShardingRequired, + /** + * You sent an invalid version for the gateway + */ + InvalidAPIVersion, + /** + * You sent an invalid intent for a Gateway Intent. You may have incorrectly calculated the bitwise value + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + */ + InvalidIntents, + /** + * You sent a disallowed intent for a Gateway Intent. You may have tried to specify an intent that you have not + * enabled or are not whitelisted for + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + * + * See https://discord.com/developers/docs/topics/gateway#privileged-intents + */ + DisallowedIntents, +} + +/** + * https://discord.com/developers/docs/topics/gateway#list-of-intents + */ +export enum GatewayIntentBits { + Guilds = 1 << 0, + GuildMembers = 1 << 1, + GuildBans = 1 << 2, + GuildEmojis = 1 << 3, + GuildIntegrations = 1 << 4, + GuildWebhooks = 1 << 5, + GuildInvites = 1 << 6, + GuildVoiceStates = 1 << 7, + GuildPresences = 1 << 8, + GuildMessages = 1 << 9, + GuildMessageReactions = 1 << 10, + GuildMessageTyping = 1 << 11, + DirectMessages = 1 << 12, + DirectMessageReactions = 1 << 13, + DirectMessageTyping = 1 << 14, +} + +/** + * https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events + */ +export enum GatewayDispatchEvents { + ApplicationCommandCreate = 'APPLICATION_COMMAND_CREATE', + ApplicationCommandDelete = 'APPLICATION_COMMAND_DELETE', + ApplicationCommandUpdate = 'APPLICATION_COMMAND_UPDATE', + ChannelCreate = 'CHANNEL_CREATE', + ChannelDelete = 'CHANNEL_DELETE', + ChannelPinsUpdate = 'CHANNEL_PINS_UPDATE', + ChannelUpdate = 'CHANNEL_UPDATE', + GuildBanAdd = 'GUILD_BAN_ADD', + GuildBanRemove = 'GUILD_BAN_REMOVE', + GuildCreate = 'GUILD_CREATE', + GuildDelete = 'GUILD_DELETE', + GuildEmojisUpdate = 'GUILD_EMOJIS_UPDATE', + GuildIntegrationsUpdate = 'GUILD_INTEGRATIONS_UPDATE', + GuildMemberAdd = 'GUILD_MEMBER_ADD', + GuildMemberRemove = 'GUILD_MEMBER_REMOVE', + GuildMembersChunk = 'GUILD_MEMBERS_CHUNK', + GuildMemberUpdate = 'GUILD_MEMBER_UPDATE', + GuildRoleCreate = 'GUILD_ROLE_CREATE', + GuildRoleDelete = 'GUILD_ROLE_DELETE', + GuildRoleUpdate = 'GUILD_ROLE_UPDATE', + GuildUpdate = 'GUILD_UPDATE', + IntegrationCreate = 'INTEGRATION_CREATE', + IntegrationDelete = 'INTEGRATION_DELETE', + IntegrationUpdate = 'INTEGRATION_UPDATE', + InteractionCreate = 'INTERACTION_CREATE', + InviteCreate = 'INVITE_CREATE', + InviteDelete = 'INVITE_DELETE', + MessageCreate = 'MESSAGE_CREATE', + MessageDelete = 'MESSAGE_DELETE', + MessageDeleteBulk = 'MESSAGE_DELETE_BULK', + MessageReactionAdd = 'MESSAGE_REACTION_ADD', + MessageReactionRemove = 'MESSAGE_REACTION_REMOVE', + MessageReactionRemoveAll = 'MESSAGE_REACTION_REMOVE_ALL', + MessageReactionRemoveEmoji = 'MESSAGE_REACTION_REMOVE_EMOJI', + MessageUpdate = 'MESSAGE_UPDATE', + PresenceUpdate = 'PRESENCE_UPDATE', + Ready = 'READY', + Resumed = 'RESUMED', + ThreadCreate = 'THREAD_CREATE', + ThreadDelete = 'THREAD_DELETE', + ThreadListSync = 'THREAD_LIST_SYNC', + ThreadMembersUpdate = 'THREAD_MEMBERS_UPDATE', + ThreadMemberUpdate = 'THREAD_MEMBER_UPDATE', + ThreadUpdate = 'THREAD_UPDATE', + TypingStart = 'TYPING_START', + UserUpdate = 'USER_UPDATE', + VoiceServerUpdate = 'VOICE_SERVER_UPDATE', + VoiceStateUpdate = 'VOICE_STATE_UPDATE', + WebhooksUpdate = 'WEBHOOKS_UPDATE', +} + +export type GatewaySendPayload = + | GatewayHeartbeat + | GatewayIdentify + | GatewayUpdatePresence + | GatewayVoiceStateUpdate + | GatewayResume + | GatewayRequestGuildMembers; + +export type GatewayReceivePayload = + | GatewayHello + | GatewayHeartbeatRequest + | GatewayHeartbeatAck + | GatewayInvalidSession + | GatewayReconnect + | GatewayDispatchPayload; + +export type GatewayDispatchPayload = + | GatewayChannelModifyDispatch + | GatewayChannelPinsUpdateDispatch + | GatewayGuildBanModifyDispatch + | GatewayGuildDeleteDispatch + | GatewayGuildEmojisUpdateDispatch + | GatewayGuildIntegrationsUpdateDispatch + | GatewayGuildMemberAddDispatch + | GatewayGuildMemberRemoveDispatch + | GatewayGuildMembersChunkDispatch + | GatewayGuildMemberUpdateDispatch + | GatewayGuildModifyDispatch + | GatewayGuildRoleDeleteDispatch + | GatewayGuildRoleModifyDispatch + | GatewayIntegrationCreateDispatch + | GatewayIntegrationDeleteDispatch + | GatewayIntegrationUpdateDispatch + | GatewayInteractionCreateDispatch + | GatewayInviteCreateDispatch + | GatewayInviteDeleteDispatch + | GatewayMessageCreateDispatch + | GatewayMessageDeleteBulkDispatch + | GatewayMessageDeleteDispatch + | GatewayMessageReactionAddDispatch + | GatewayMessageReactionRemoveAllDispatch + | GatewayMessageReactionRemoveDispatch + | GatewayMessageReactionRemoveEmojiDispatch + | GatewayMessageUpdateDispatch + | GatewayPresenceUpdateDispatch + | GatewayReadyDispatch + | GatewayResumedDispatch + | GatewayThreadListSyncDispatch + | GatewayThreadMembersUpdateDispatch + | GatewayThreadMemberUpdateDispatch + | GatewayThreadModifyDispatch + | GatewayTypingStartDispatch + | GatewayUserUpdateDispatch + | GatewayVoiceServerUpdateDispatch + | GatewayVoiceStateUpdateDispatch + | GatewayWebhooksUpdateDispatch; + +// #region Dispatch Payloads + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + * https://discord.com/developers/docs/topics/gateway#application-command-update + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandModifyDispatch = DataPayload< + | GatewayDispatchEvents.ApplicationCommandCreate + | GatewayDispatchEvents.ApplicationCommandUpdate + | GatewayDispatchEvents.ApplicationCommandDelete, + GatewayApplicationCommandModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + * https://discord.com/developers/docs/topics/gateway#application-command-update + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export interface GatewayApplicationCommandModifyDispatchData extends APIApplicationCommand { + guild_id?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + */ +export type GatewayApplicationCommandCreateDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + */ +export type GatewayApplicationCommandCreateDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-update + */ +export type GatewayApplicationCommandUpdateDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-update + */ +export type GatewayApplicationCommandUpdateDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandDeleteDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandDeleteDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#hello + */ +export interface GatewayHello extends NonDispatchPayload { + op: GatewayOpcodes.Hello; + d: GatewayHelloData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#hello + */ +export interface GatewayHelloData { + /** + * The interval (in milliseconds) the client should heartbeat with + */ + heartbeat_interval: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export interface GatewayHeartbeatRequest extends NonDispatchPayload { + op: GatewayOpcodes.Heartbeat; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack + */ +export interface GatewayHeartbeatAck extends NonDispatchPayload { + op: GatewayOpcodes.HeartbeatAck; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invalid-session + */ +export interface GatewayInvalidSession extends NonDispatchPayload { + op: GatewayOpcodes.InvalidSession; + d: GatewayInvalidSessionData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invalid-session + */ +export type GatewayInvalidSessionData = boolean; + +/** + * https://discord.com/developers/docs/topics/gateway#reconnect + */ +export interface GatewayReconnect extends NonDispatchPayload { + op: GatewayOpcodes.Reconnect; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#ready + */ +export type GatewayReadyDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#ready + */ +export interface GatewayReadyDispatchData { + /** + * Gateway version + * + * See https://discord.com/developers/docs/topics/gateway#gateways-gateway-versions + */ + v: number; + /** + * Information about the user including email + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; + /** + * The guilds the user is in + * + * See https://discord.com/developers/docs/resources/guild#unavailable-guild-object + */ + guilds: APIUnavailableGuild[]; + /** + * Used for resuming connections + */ + session_id: string; + /** + * The shard information associated with this session, if sent when identifying + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shard?: [shard_id: number, shard_count: number]; + /** + * Contains `id` and `flags` + * + * See https://discord.com/developers/docs/topics/oauth2#application-object + */ + application: Pick; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resumed + */ +export type GatewayResumedDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + * https://discord.com/developers/docs/topics/gateway#channel-update + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelModifyDispatch = DataPayload< + GatewayDispatchEvents.ChannelCreate | GatewayDispatchEvents.ChannelDelete | GatewayDispatchEvents.ChannelUpdate, + GatewayChannelModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + * https://discord.com/developers/docs/topics/gateway#channel-update + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelModifyDispatchData = APIChannel; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + */ +export type GatewayChannelCreateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + */ +export type GatewayChannelCreateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-update + */ +export type GatewayChannelUpdateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-update + */ +export type GatewayChannelUpdateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelDeleteDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelDeleteDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-pins-update + */ +export type GatewayChannelPinsUpdateDispatch = DataPayload< + GatewayDispatchEvents.ChannelPinsUpdate, + GatewayChannelPinsUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-pins-update + */ +export interface GatewayChannelPinsUpdateDispatchData { + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The time at which the most recent pinned message was pinned + */ + last_pin_timestamp?: string | null; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildCreate | GatewayDispatchEvents.GuildUpdate, + GatewayGuildModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildModifyDispatchData = APIGuild; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + */ +export type GatewayGuildCreateDispatch = GatewayGuildModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + */ +export type GatewayGuildCreateDispatchData = GatewayGuildModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildUpdateDispatch = GatewayGuildModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildUpdateDispatchData = GatewayGuildModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-delete + */ +export type GatewayGuildDeleteDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-delete + */ +export type GatewayGuildDeleteDispatchData = APIUnavailableGuild; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildBanAdd | GatewayDispatchEvents.GuildBanRemove, + GatewayGuildBanModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export interface GatewayGuildBanModifyDispatchData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * The banned user + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + */ +export type GatewayGuildBanAddDispatch = GatewayGuildBanModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + */ +export type GatewayGuildBanAddDispatchData = GatewayGuildBanModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanRemoveDispatch = GatewayGuildBanModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanRemoveDispatchData = GatewayGuildBanModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-emojis-update + */ +export type GatewayGuildEmojisUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildEmojisUpdate, + GatewayGuildEmojisUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-emojis-update + */ +export interface GatewayGuildEmojisUpdateDispatchData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * Array of emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-integrations-update + */ +export type GatewayGuildIntegrationsUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildIntegrationsUpdate, + GatewayGuildIntegrationsUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-integrations-update + */ +export interface GatewayGuildIntegrationsUpdateDispatchData { + /** + * ID of the guild whose integrations were updated + */ + guild_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-add + */ +export type GatewayGuildMemberAddDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberAdd, + GatewayGuildMemberAddDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-add + */ +export interface GatewayGuildMemberAddDispatchData extends APIGuildMember { + /** + * The id of the guild + */ + guild_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-remove + */ +export type GatewayGuildMemberRemoveDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberRemove, + GatewayGuildMemberRemoveDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-remove + */ +export interface GatewayGuildMemberRemoveDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The user who was removed + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-update + */ +export type GatewayGuildMemberUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberUpdate, + GatewayGuildMemberUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-update + */ +export type GatewayGuildMemberUpdateDispatchData = Omit & + Partial> & + Required> & { + /** + * The id of the guild + */ + guild_id: Snowflake; + }; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ +export type GatewayGuildMembersChunkDispatch = DataPayload< + GatewayDispatchEvents.GuildMembersChunk, + GatewayGuildMembersChunkDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ +export interface GatewayGuildMembersChunkDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * Set of guild members + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + members: APIGuildMember[]; + /** + * The chunk index in the expected chunks for this response (`0 <= chunk_index < chunk_count`) + */ + chunk_index?: number; + /** + * The total number of expected chunks for this response + */ + chunk_count?: number; + /** + * If passing an invalid id to `REQUEST_GUILD_MEMBERS`, it will be returned here + */ + not_found?: unknown[]; + /** + * If passing true to `REQUEST_GUILD_MEMBERS`, presences of the returned members will be here + * + * See https://discord.com/developers/docs/topics/gateway#presence + */ + presences?: RawGatewayPresenceUpdate[]; + /** + * The nonce used in the Guild Members Request + * + * See https://discord.com/developers/docs/topics/gateway#request-guild-members + */ + nonce?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildRoleCreate | GatewayDispatchEvents.GuildRoleUpdate, + GatewayGuildRoleModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export interface GatewayGuildRoleModifyDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The role created or updated + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + role: APIRole; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + */ +export type GatewayGuildRoleCreateDispatch = GatewayGuildRoleModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + */ +export type GatewayGuildRoleCreateDispatchData = GatewayGuildRoleModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleUpdateDispatch = GatewayGuildRoleModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleUpdateDispatchData = GatewayGuildRoleModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-delete + */ +export type GatewayGuildRoleDeleteDispatch = DataPayload< + GatewayDispatchEvents.GuildRoleDelete, + GatewayGuildRoleDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-delete + */ +export interface GatewayGuildRoleDeleteDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The id of the role + */ + role_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#integration-create + */ +export type GatewayIntegrationCreateDispatch = DataPayload< + GatewayDispatchEvents.IntegrationCreate, + GatewayIntegrationCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-create + */ +export type GatewayIntegrationCreateDispatchData = APIGuildIntegration & { guild_id: Snowflake }; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationUpdateDispatch = DataPayload< + GatewayDispatchEvents.IntegrationUpdate, + GatewayIntegrationUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationUpdateDispatchData = APIGuildIntegration & { guild_id: Snowflake }; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationDeleteDispatch = DataPayload< + GatewayDispatchEvents.IntegrationDelete, + GatewayIntegrationDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-delete + */ +export interface GatewayIntegrationDeleteDispatchData { + /** + * Integration id + */ + id: Snowflake; + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * ID of the bot/OAuth2 application for this Discord integration + */ + application_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#interaction-create + */ +export type GatewayInteractionCreateDispatch = DataPayload< + GatewayDispatchEvents.InteractionCreate, + GatewayInteractionCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#interaction-create + */ +export type GatewayInteractionCreateDispatchData = APIApplicationCommandInteraction; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-create + */ +export type GatewayInviteCreateDispatch = DataPayload< + GatewayDispatchEvents.InviteCreate, + GatewayInviteCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-create + */ +export interface GatewayInviteCreateDispatchData { + /** + * The channel the invite is for + */ + channel_id: Snowflake; + /** + * The unique invite code + * + * See https://discord.com/developers/docs/resources/invite#invite-object + */ + code: string; + /** + * The time at which the invite was created + */ + created_at: number; + /** + * The guild of the invite + */ + guild_id?: Snowflake; + /** + * The user that created the invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + inviter?: APIUser; + /** + * How long the invite is valid for (in seconds) + */ + max_age: number; + /** + * The maximum number of times the invite can be used + */ + max_uses: number; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ + target_type?: InviteTargetType; + /** + * The user whose stream to display for this voice channel stream invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + target_user?: APIUser; + /** + * The embedded application to open for this voice channel embedded application invite + */ + target_application?: Partial; + /** + * Whether or not the invite is temporary (invited users will be kicked on disconnect unless they're assigned a role) + */ + temporary: boolean; + /** + * How many times the invite has been used (always will be `0`) + */ + uses: 0; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invite-delete + */ +export type GatewayInviteDeleteDispatch = DataPayload< + GatewayDispatchEvents.InviteDelete, + GatewayInviteDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-delete + */ +export interface GatewayInviteDeleteDispatchData { + /** + * The channel of the invite + */ + channel_id: Snowflake; + /** + * The guild of the invite + */ + guild_id?: Snowflake; + /** + * The unique invite code + * + * See https://discord.com/developers/docs/resources/invite#invite-object + */ + code: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-create + */ +export type GatewayMessageCreateDispatch = DataPayload< + GatewayDispatchEvents.MessageCreate, + GatewayMessageCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-create + */ +export type GatewayMessageCreateDispatchData = APIMessage; + +/** + * https://discord.com/developers/docs/topics/gateway#message-update + */ +export type GatewayMessageUpdateDispatch = DataPayload< + GatewayDispatchEvents.MessageUpdate, + GatewayMessageUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-update + */ +export type GatewayMessageUpdateDispatchData = { + id: Snowflake; + channel_id: Snowflake; +} & Partial; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete + */ +export type GatewayMessageDeleteDispatch = DataPayload< + GatewayDispatchEvents.MessageDelete, + GatewayMessageDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete + */ +export interface GatewayMessageDeleteDispatchData { + /** + * The id of the message + */ + id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete-bulk + */ +export type GatewayMessageDeleteBulkDispatch = DataPayload< + GatewayDispatchEvents.MessageDeleteBulk, + GatewayMessageDeleteBulkDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete-bulk + */ +export interface GatewayMessageDeleteBulkDispatchData { + /** + * The ids of the messages + */ + ids: Snowflake[]; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-add + */ +export type GatewayMessageReactionAddDispatch = ReactionData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-add + */ +export type GatewayMessageReactionAddDispatchData = GatewayMessageReactionAddDispatch['d']; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove + */ +export type GatewayMessageReactionRemoveDispatch = ReactionData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove + */ +export type GatewayMessageReactionRemoveDispatchData = GatewayMessageReactionRemoveDispatch['d']; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all + */ +export type GatewayMessageReactionRemoveAllDispatch = DataPayload< + GatewayDispatchEvents.MessageReactionRemoveAll, + GatewayMessageReactionRemoveAllDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all + */ +export type GatewayMessageReactionRemoveAllDispatchData = MessageReactionRemoveData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + */ +export type GatewayMessageReactionRemoveEmojiDispatch = DataPayload< + GatewayDispatchEvents.MessageReactionRemoveEmoji, + GatewayMessageReactionRemoveEmojiDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + */ +export interface GatewayMessageReactionRemoveEmojiDispatchData extends MessageReactionRemoveData { + /** + * The emoji that was removed + */ + emoji: APIEmoji; +} + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update + */ +export type GatewayPresenceUpdateDispatch = DataPayload< + GatewayDispatchEvents.PresenceUpdate, + GatewayPresenceUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update + */ +export type GatewayPresenceUpdateDispatchData = RawGatewayPresenceUpdate; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync + */ +export type GatewayThreadListSyncDispatch = DataPayload< + GatewayDispatchEvents.ThreadListSync, + GatewayThreadListSyncDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync + */ +export type GatewayThreadListSyncDispatchData = RawGatewayThreadListSync; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update + */ +export type GatewayThreadMembersUpdateDispatch = DataPayload< + GatewayDispatchEvents.ThreadMembersUpdate, + GatewayThreadMembersUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update + */ +export type GatewayThreadMembersUpdateDispatchData = RawGatewayThreadMembersUpdate; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-member-update + */ +export type GatewayThreadMemberUpdateDispatch = DataPayload< + GatewayDispatchEvents.ThreadMemberUpdate, + GatewayThreadMemberUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-member-update + */ +export type GatewayThreadMemberUpdateDispatchData = APIThreadMember; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + * https://discord.com/developers/docs/topics/gateway#thread-update + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadModifyDispatch = DataPayload< + GatewayDispatchEvents.ThreadCreate | GatewayDispatchEvents.ThreadDelete | GatewayDispatchEvents.ThreadUpdate, + GatewayChannelModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + */ +export type GatewayThreadCreateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + */ +export type GatewayThreadCreateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-update + */ +export type GatewayThreadUpdateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-update + */ +export type GatewayThreadUpdateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadDeleteDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadDeleteDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#typing-start + */ +export type GatewayTypingStartDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#typing-start + */ +export interface GatewayTypingStartDispatchData { + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The id of the user + */ + user_id: Snowflake; + /** + * Unix time (in seconds) of when the user started typing + */ + timestamp: number; + /** + * The member who started typing if this happened in a guild + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; +} + +/** + * https://discord.com/developers/docs/topics/gateway#user-update + */ +export type GatewayUserUpdateDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#user-update + */ +export type GatewayUserUpdateDispatchData = APIUser; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-state-update + */ +export type GatewayVoiceStateUpdateDispatch = DataPayload< + GatewayDispatchEvents.VoiceStateUpdate, + GatewayVoiceStateUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-state-update + */ +export type GatewayVoiceStateUpdateDispatchData = GatewayVoiceState; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-server-update + */ +export type GatewayVoiceServerUpdateDispatch = DataPayload< + GatewayDispatchEvents.VoiceServerUpdate, + GatewayVoiceServerUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-server-update + */ +export interface GatewayVoiceServerUpdateDispatchData { + /** + * Voice connection token + */ + token: string; + /** + * The guild this voice server update is for + */ + guild_id: Snowflake; + /** + * The voice server host + * + * A `null` endpoint means that the voice server allocated has gone away and is trying to be reallocated. + * You should attempt to disconnect from the currently connected voice server, and not attempt to reconnect + * until a new voice server is allocated + */ + endpoint: string | null; +} + +/** + * https://discord.com/developers/docs/topics/gateway#webhooks-update + */ +export type GatewayWebhooksUpdateDispatch = DataPayload< + GatewayDispatchEvents.WebhooksUpdate, + GatewayWebhooksUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#webhooks-update + */ +export interface GatewayWebhooksUpdateDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; +} + +// #endregion Dispatch Payloads + +// #region Sendable Payloads + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export interface GatewayHeartbeat { + op: GatewayOpcodes.Heartbeat; + d: GatewayHeartbeatData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export type GatewayHeartbeatData = number | null; + +/** + * https://discord.com/developers/docs/topics/gateway#identify + */ +export interface GatewayIdentify { + op: GatewayOpcodes.Identify; + d: GatewayIdentifyData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#identify + */ +export interface GatewayIdentifyData { + /** + * Authentication token + */ + token: string; + /** + * Connection properties + * + * See https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties + */ + properties: GatewayIdentifyProperties; + /** + * Whether this connection supports compression of packets + * + * @default false + */ + compress?: boolean; + /** + * Value between 50 and 250, total number of members where the gateway will stop sending + * offline members in the guild member list + * + * @default 50 + */ + large_threshold?: number; + /** + * Used for Guild Sharding + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shard?: [shard_id: number, shard_count: number]; + /** + * Presence structure for initial presence information + * + * See https://discord.com/developers/docs/topics/gateway#update-status + */ + presence?: GatewayPresenceUpdateData; + /** + * The Gateway Intents you wish to receive + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + */ + intents: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties + */ +export interface GatewayIdentifyProperties { + /** + * Your operating system + */ + $os: string; + /** + * Your library name + */ + $browser: string; + /** + * Your library name + */ + $device: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resume + */ +export interface GatewayResume { + op: GatewayOpcodes.Resume; + d: GatewayResumeData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resume + */ +export interface GatewayResumeData { + /** + * Session token + */ + token: string; + /** + * Session id + */ + session_id: string; + /** + * Last sequence number received + */ + seq: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#request-guild-members + */ +export interface GatewayRequestGuildMembers { + op: GatewayOpcodes.RequestGuildMembers; + d: GatewayRequestGuildMembersData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#request-guild-members + */ +export interface GatewayRequestGuildMembersData { + /** + * ID of the guild to get members for + */ + guild_id: Snowflake; + /** + * String that username starts with, or an empty string to return all members + */ + query?: string; + /** + * Maximum number of members to send matching the `query`; + * a limit of `0` can be used with an empty string `query` to return all members + */ + limit: number; + /** + * Used to specify if we want the presences of the matched members + */ + presences?: boolean; + /** + * Used to specify which users you wish to fetch + */ + user_ids?: Snowflake | Snowflake[]; + /** + * Nonce to identify the Guild Members Chunk response + * + * Nonce can only be up to 32 bytes. If you send an invalid nonce it will be ignored and the reply member_chunk(s) will not have a `nonce` set. + * + * See https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ + nonce?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-voice-state + */ +export interface GatewayVoiceStateUpdate { + op: GatewayOpcodes.VoiceStateUpdate; + d: GatewayVoiceStateUpdateData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-voice-state + */ +export interface GatewayVoiceStateUpdateData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * ID of the voice channel client wants to join (`null` if disconnecting) + */ + channel_id: Snowflake | null; + /** + * Is the client muted + */ + self_mute: boolean; + /** + * Is the client deafened + */ + self_deaf: boolean; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-status + */ +export interface GatewayUpdatePresence { + op: GatewayOpcodes.PresenceUpdate; + d: GatewayPresenceUpdateData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure + */ +export interface GatewayPresenceUpdateData { + /** + * Unix time (in milliseconds) of when the client went idle, or `null` if the client is not idle + */ + since: number | null; + /** + * The user's activities + * + * See https://discord.com/developers/docs/topics/gateway#activity-object + */ + activities: GatewayActivityUpdateData[]; + /** + * The user's new status + * + * See https://discord.com/developers/docs/topics/gateway#update-status-status-types + */ + status: PresenceUpdateStatus; + /** + * Whether or not the client is afk + */ + afk: boolean; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-structure + */ +export type GatewayActivityUpdateData = Pick; + +// #endregion Sendable Payloads + +// #region Shared +interface BasePayload { + /** + * Opcode for the payload + */ + op: GatewayOpcodes; + /** + * Event data + */ + d?: unknown; + /** + * Sequence number, used for resuming sessions and heartbeats + */ + s: number; + /** + * The event name for this payload + */ + t?: string; +} + +type NonDispatchPayload = Omit; + +interface DataPayload extends BasePayload { + op: GatewayOpcodes.Dispatch; + t: Event; + d: D; +} + +type ReactionData = DataPayload< + E, + Omit< + { + /** + * The id of the user + */ + user_id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the message + */ + message_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The member who reacted if this happened in a guild + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * The emoji used to react + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emoji: APIEmoji; + }, + O + > +>; + +interface MessageReactionRemoveData { + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the message + */ + message_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} +// #endregion Shared diff --git a/deno/payloads/mod.ts b/deno/payloads/mod.ts index 8f499952..dee3a16e 100644 --- a/deno/payloads/mod.ts +++ b/deno/payloads/mod.ts @@ -1,4 +1,4 @@ // This file exports all the payloads available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8/mod.ts'; +export * from './v9/mod.ts'; diff --git a/deno/payloads/v9/auditLog.ts b/deno/payloads/v9/auditLog.ts new file mode 100644 index 00000000..ef5f389e --- /dev/null +++ b/deno/payloads/v9/auditLog.ts @@ -0,0 +1,576 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/audit-log + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIOverwrite, ChannelType } from './channel.ts'; +import type { + APIGuildIntegration, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildMFALevel, + GuildVerificationLevel, + IntegrationExpireBehavior, +} from './guild.ts'; +import type { APIRole } from './permissions.ts'; +import type { APIUser } from './user.ts'; +import type { APIWebhook } from './webhook.ts'; + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-object-audit-log-structure + */ +export interface APIAuditLog { + /** + * Webhooks found in the audit log + * + * See https://discord.com/developers/docs/resources/webhook#webhook-object + */ + webhooks: APIWebhook[]; + /** + * Users found in the audit log + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + users: APIUser[]; + /** + * Audit log entries + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object + */ + audit_log_entries: APIAuditLogEntry[]; + /** + * Partial integration objects + * + * See https://discord.com/developers/docs/resources/guild#integration-object + */ + integrations: APIGuildIntegration[]; +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-entry-structure + */ +export interface APIAuditLogEntry { + /** + * ID of the affected entity (webhook, user, role, etc.) + */ + target_id: string | null; + /** + * Changes made to the `target_id` + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-change-object + */ + changes?: APIAuditLogChange[]; + /** + * The user who made the changes + * + * This can be `null` in some cases (webhooks deleting themselves by using their own token, for example) + */ + user_id: Snowflake | null; + /** + * ID of the entry + */ + id: Snowflake; + /** + * Type of action that occurred + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events + */ + action_type: AuditLogEvent; + /** + * Additional info for certain action types + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info + */ + options?: APIAuditLogOptions; + /** + * The reason for the change (0-512 characters) + */ + reason?: string; +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events + */ +export enum AuditLogEvent { + GuildUpdate = 1, + + ChannelCreate = 10, + ChannelUpdate, + ChannelDelete, + ChannelOverwriteCreate, + ChannelOverwriteUpdate, + ChannelOverwriteDelete, + + MemberKick = 20, + MemberPrune, + MemberBanAdd, + MemberBanRemove, + MemberUpdate, + MemberRoleUpdate, + MemberMove, + MemberDisconnect, + BotAdd, + + RoleCreate = 30, + RoleUpdate, + RoleDelete, + + InviteCreate = 40, + InviteUpdate, + InviteDelete, + + WebhookCreate = 50, + WebhookUpdate, + WebhookDelete, + + EmojiCreate = 60, + EmojiUpdate, + EmojiDelete, + + MessageDelete = 72, + MessageBulkDelete, + MessagePin, + MessageUnpin, + + IntegrationCreate = 80, + IntegrationUpdate, + IntegrationDelete, +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info + */ +export interface APIAuditLogOptions { + /** + * Number of days after which inactive members were kicked + * + * Present from: + * - MEMBER_PRUNE + */ + delete_member_days?: string; + /** + * Number of members removed by the prune + * + * Present from: + * - MEMBER_PRUNE + */ + members_removed?: string; + + /** + * Channel in which the entities were targeted + * + * Present from: + * - MEMBER_MOVE + * - MESSAGE_PIN + * - MESSAGE_UNPIN + * - MESSAGE_DELETE + */ + channel_id?: Snowflake; + + /** + * ID of the message that was targeted + * + * Present from: + * - MESSAGE_PIN + * - MESSAGE_UNPIN + */ + message_id?: Snowflake; + + /** + * Number of entities that were targeted + * + * Present from: + * - MESSAGE_DELETE + * - MESSAGE_BULK_DELETE + * - MEMBER_DISCONNECT + * - MEMBER_MOVE + */ + count?: string; + + /** + * ID of the overwritten entity + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + */ + id?: Snowflake; + + /** + * Type of overwritten entity - "0" for "role" or "1" for "member" + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + * + * {@link AuditLogOptionsType} + */ + type?: AuditLogOptionsType; + + /** + * Name of the role + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + * + * **Present only if the {@link APIAuditLogOptions#type entry type} is "0"** + */ + role_name?: string; +} + +export enum AuditLogOptionsType { + Role = '0', + Member = '1', +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure + */ +export type APIAuditLogChange = + | APIAuditLogChangeKeyName + | APIAuditLogChangeKeyDescription + | APIAuditLogChangeKeyIconHash + | APIAuditLogChangeKeySplashHash + | APIAuditLogChangeKeyDiscoverySplashHash + | APIAuditLogChangeKeyBannerHash + | APIAuditLogChangeKeyOwnerID + | APIAuditLogChangeKeyRegion + | APIAuditLogChangeKeyPreferredLocale + | APIAuditLogChangeKeyAFKChannelID + | APIAuditLogChangeKeyAFKTimeout + | APIAuditLogChangeKeyRulesChannelID + | APIAuditLogChangeKeyPublicUpdatesChannelID + | APIAuditLogChangeKeyMFALevel + | APIAuditLogChangeKeyVerificationLevel + | APIAuditLogChangeKeyExplicitContentFilter + | APIAuditLogChangeKeyDefaultMessageNotifications + | APIAuditLogChangeKeyVanityURLCode + | APIAuditLogChangeKey$Add + | APIAuditLogChangeKey$Remove + | APIAuditLogChangeKeyPruneDeleteDays + | APIAuditLogChangeKeyWidgetEnabled + | APIAuditLogChangeKeyWidgetChannelID + | APIAuditLogChangeKeySystemChannelID + | APIAuditLogChangeKeyPosition + | APIAuditLogChangeKeyTopic + | APIAuditLogChangeKeyBitrate + | APIAuditLogChangeKeyPermissionOverwrites + | APIAuditLogChangeKeyNSFW + | APIAuditLogChangeKeyApplicationID + | APIAuditLogChangeKeyRateLimitPerUser + | APIAuditLogChangeKeyPermissions + | APIAuditLogChangeKeyColor + | APIAuditLogChangeKeyHoist + | APIAuditLogChangeKeyMentionable + | APIAuditLogChangeKeyAllow + | APIAuditLogChangeKeyDeny + | APIAuditLogChangeKeyCode + | APIAuditLogChangeKeyChannelID + | APIAuditLogChangeKeyInviterID + | APIAuditLogChangeKeyMaxUses + | APIAuditLogChangeKeyUses + | APIAuditLogChangeKeyMaxAge + | APIAuditLogChangeKeyTemporary + | APIAuditLogChangeKeyDeaf + | APIAuditLogChangeKeyMute + | APIAuditLogChangeKeyNick + | APIAuditLogChangeKeyAvatarHash + | APIAuditLogChangeKeyID + | APIAuditLogChangeKeyType + | APIAuditLogChangeKeyEnableEmoticons + | APIAuditLogChangeKeyExpireBehavior + | APIAuditLogChangeKeyExpireGracePeriod + | APIAuditLogChangeKeyUserLimit; + +/** + * Returned when a guild's name is changed + */ +export type APIAuditLogChangeKeyName = AuditLogChangeData<'name', string>; + +/** + * Returned when a guild's description is changed + */ +export type APIAuditLogChangeKeyDescription = AuditLogChangeData<'description', string>; + +/** + * Returned when a guild's icon is changed + */ +export type APIAuditLogChangeKeyIconHash = AuditLogChangeData<'icon_hash', string>; + +/** + * Returned when a guild's splash is changed + */ +export type APIAuditLogChangeKeySplashHash = AuditLogChangeData<'splash_hash', string>; + +/** + * Returned when a guild's discovery splash is changed + */ +export type APIAuditLogChangeKeyDiscoverySplashHash = AuditLogChangeData<'discovery_splash_hash', string>; + +/** + * Returned when a guild's banner hash is changed + */ +export type APIAuditLogChangeKeyBannerHash = AuditLogChangeData<'banner_hash', string>; + +/** + * Returned when a guild's owner_id is changed + */ +export type APIAuditLogChangeKeyOwnerID = AuditLogChangeData<'owner_id', Snowflake>; + +/** + * Returned when a guild's region is changed + */ +export type APIAuditLogChangeKeyRegion = AuditLogChangeData<'region', string>; + +/** + * Returned when a guild's preferred_locale is changed + */ +export type APIAuditLogChangeKeyPreferredLocale = AuditLogChangeData<'preferred_locale', string>; + +/** + * Returned when a guild's afk_channel_id is changed + */ +export type APIAuditLogChangeKeyAFKChannelID = AuditLogChangeData<'afk_channel_id', Snowflake>; + +/** + * Returned when a guild's afk_timeout is changed + */ +export type APIAuditLogChangeKeyAFKTimeout = AuditLogChangeData<'afk_timeout', number>; + +/** + * Returned when a guild's rules_channel_id is changed + */ +export type APIAuditLogChangeKeyRulesChannelID = AuditLogChangeData<'rules_channel_id', string>; + +/** + * Returned when a guild's public_updates_channel_id is changed + */ +export type APIAuditLogChangeKeyPublicUpdatesChannelID = AuditLogChangeData<'public_updates_channel_id', string>; + +/** + * Returned when a guild's mfa_level is changed + */ +export type APIAuditLogChangeKeyMFALevel = AuditLogChangeData<'mfa_level', GuildMFALevel>; + +/** + * Returned when a guild's verification_level is changed + */ +export type APIAuditLogChangeKeyVerificationLevel = AuditLogChangeData<'verification_level', GuildVerificationLevel>; + +/** + * Returned when a guild's explicit_content_filter is changed + */ +export type APIAuditLogChangeKeyExplicitContentFilter = AuditLogChangeData< + 'explicit_content_filter', + GuildExplicitContentFilter +>; + +/** + * Returned when a guild's default_message_notifications is changed + */ +export type APIAuditLogChangeKeyDefaultMessageNotifications = AuditLogChangeData< + 'default_message_notifications', + GuildDefaultMessageNotifications +>; + +/** + * Returned when a guild's vanity_url_code is changed + */ +export type APIAuditLogChangeKeyVanityURLCode = AuditLogChangeData<'vanity_url_code', string>; + +/** + * Returned when new role(s) are added + */ +export type APIAuditLogChangeKey$Add = AuditLogChangeData<'$add', APIRole[]>; + +/** + * Returned when role(s) are removed + */ +export type APIAuditLogChangeKey$Remove = AuditLogChangeData<'$remove', APIRole[]>; + +/** + * Returned when there is a change in number of days after which inactive and role-unassigned members are kicked + */ +export type APIAuditLogChangeKeyPruneDeleteDays = AuditLogChangeData<'prune_delete_days', number>; + +/** + * Returned when a guild's widget is enabled + */ +export type APIAuditLogChangeKeyWidgetEnabled = AuditLogChangeData<'widget_enabled', boolean>; + +/** + * Returned when a guild's widget_channel_id is changed + */ +export type APIAuditLogChangeKeyWidgetChannelID = AuditLogChangeData<'widget_channel_id', Snowflake>; + +/** + * Returned when a guild's system_channel_id is changed + */ +export type APIAuditLogChangeKeySystemChannelID = AuditLogChangeData<'system_channel_id', Snowflake>; + +/** + * Returned when a channel's position is changed + */ +export type APIAuditLogChangeKeyPosition = AuditLogChangeData<'position', number>; + +/** + * Returned when a channel's topic is changed + */ +export type APIAuditLogChangeKeyTopic = AuditLogChangeData<'topic', string>; + +/** + * Returned when a voice channel's bitrate is changed + */ +export type APIAuditLogChangeKeyBitrate = AuditLogChangeData<'bitrate', number>; + +/** + * Returned when a channel's permission overwrites is changed + */ +export type APIAuditLogChangeKeyPermissionOverwrites = AuditLogChangeData<'permission_overwrites', APIOverwrite[]>; + +/** + * Returned when a channel's NSFW restriction is changed + */ +export type APIAuditLogChangeKeyNSFW = AuditLogChangeData<'nsfw', boolean>; + +/** + * The application ID of the added or removed Webhook or Bot + */ +export type APIAuditLogChangeKeyApplicationID = AuditLogChangeData<'application_id', Snowflake>; + +/** + * Returned when a channel's amount of seconds a user has to wait before sending another message + * is changed + */ +export type APIAuditLogChangeKeyRateLimitPerUser = AuditLogChangeData<'rate_limit_per_user', number>; + +/** + * Returned when a permission bitfield is changed + */ +export type APIAuditLogChangeKeyPermissions = AuditLogChangeData<'permissions', string>; + +/** + * Returned when a role's color is changed + */ +export type APIAuditLogChangeKeyColor = AuditLogChangeData<'color', number>; + +/** + * Returned when a role's hoist status is changed + */ +export type APIAuditLogChangeKeyHoist = AuditLogChangeData<'hoist', boolean>; + +/** + * Returned when a role's mentionable status is changed + */ +export type APIAuditLogChangeKeyMentionable = AuditLogChangeData<'mentionable', boolean>; + +/** + * Returned when an overwrite's allowed permissions bitfield is changed + */ +export type APIAuditLogChangeKeyAllow = AuditLogChangeData<'allow', string>; + +/** + * Returned when an overwrite's denied permissions bitfield is changed + */ +export type APIAuditLogChangeKeyDeny = AuditLogChangeData<'deny', string>; + +/** + * Returned when an invite's code is changed + */ +export type APIAuditLogChangeKeyCode = AuditLogChangeData<'code', string>; + +/** + * Returned when an invite's channel_id is changed + */ +export type APIAuditLogChangeKeyChannelID = AuditLogChangeData<'channel_id', Snowflake>; + +/** + * Returned when an invite's inviter_id is changed + */ +export type APIAuditLogChangeKeyInviterID = AuditLogChangeData<'inviter_id', Snowflake>; + +/** + * Returned when an invite's max_uses is changed + */ +export type APIAuditLogChangeKeyMaxUses = AuditLogChangeData<'max_uses', number>; + +/** + * Returned when an invite's uses is changed + */ +export type APIAuditLogChangeKeyUses = AuditLogChangeData<'uses', number>; + +/** + * Returned when an invite's max_age is changed + */ +export type APIAuditLogChangeKeyMaxAge = AuditLogChangeData<'max_age', number>; + +/** + * Returned when an invite's temporary status is changed + */ +export type APIAuditLogChangeKeyTemporary = AuditLogChangeData<'temporary', boolean>; + +/** + * Returned when a user's deaf status is changed + */ +export type APIAuditLogChangeKeyDeaf = AuditLogChangeData<'deaf', boolean>; + +/** + * Returned when a user's mute status is changed + */ +export type APIAuditLogChangeKeyMute = AuditLogChangeData<'mute', boolean>; + +/** + * Returned when a user's nick is changed + */ +export type APIAuditLogChangeKeyNick = AuditLogChangeData<'mute', boolean>; + +/** + * Returned when a user's avatar_hash is changed + */ +export type APIAuditLogChangeKeyAvatarHash = AuditLogChangeData<'avatar_hash', string>; + +/** + * The ID of the changed entity - sometimes used in conjunction with other keys + */ +export type APIAuditLogChangeKeyID = AuditLogChangeData<'id', Snowflake>; + +/** + * The type of entity created + */ +export type APIAuditLogChangeKeyType = AuditLogChangeData<'type', ChannelType | string>; + +/** + * Returned when an integration's enable_emoticons is changed + */ +export type APIAuditLogChangeKeyEnableEmoticons = AuditLogChangeData<'enable_emoticons', boolean>; + +/** + * Returned when an integration's expire_behavior is changed + */ +export type APIAuditLogChangeKeyExpireBehavior = AuditLogChangeData<'expire_behavior', IntegrationExpireBehavior>; + +/** + * Returned when an integration's expire_grace_period is changed + */ +export type APIAuditLogChangeKeyExpireGracePeriod = AuditLogChangeData<'expire_grace_period', number>; + +/** + * Returned when a voice channel's user_limit is changed + */ +export type APIAuditLogChangeKeyUserLimit = AuditLogChangeData<'user_limit', number>; + +interface AuditLogChangeData { + key: K; + /** + * The new value + * + * If `new_value` is not present in the change object, while `old_value` is, + * that means the property that was changed has been reset, or set to `null` + */ + new_value?: D; + old_value?: D; +} diff --git a/deno/payloads/v9/channel.ts b/deno/payloads/v9/channel.ts new file mode 100644 index 00000000..184abdfb --- /dev/null +++ b/deno/payloads/v9/channel.ts @@ -0,0 +1,1048 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/channel + */ + +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { APIPartialEmoji } from './emoji.ts'; +import type { APIGuildMember } from './guild.ts'; +import type { APIMessageInteraction } from './interactions.ts'; +import { APIApplication } from './oauth2.ts'; +import type { APIRole } from './permissions.ts'; +import type { APIUser } from './user.ts'; + +/** + * Not documented, but partial only includes id, name, and type + */ +export interface APIPartialChannel { + /** + * The id of the channel + */ + id: Snowflake; + /** + * The type of the channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ + type: ChannelType; + /** + * The name of the channel (2-100 characters) + */ + name?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object-channel-structure + */ +export interface APIChannel extends APIPartialChannel { + /** + * The id of the guild (may be missing for some channel objects received over gateway guild dispatches) + */ + guild_id?: Snowflake; + /** + * Sorting position of the channel + */ + position?: number; + /** + * Explicit permission overwrites for members and roles + * + * See https://discord.com/developers/docs/resources/channel#overwrite-object + */ + permission_overwrites?: APIOverwrite[]; + /** + * The channel topic (0-1024 characters) + */ + topic?: string | null; + /** + * Whether the channel is nsfw + */ + nsfw?: boolean; + /** + * The id of the last message sent in this channel (may not point to an existing or valid message) + */ + last_message_id?: Snowflake | null; + /** + * The bitrate (in bits) of the voice channel + */ + bitrate?: number; + /** + * The user limit of the voice channel + */ + 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_CHANNELS`, are unaffected + */ + rate_limit_per_user?: number; + /** + * The recipients of the DM + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + recipients?: APIUser[]; + /** + * Icon hash + */ + icon?: string | null; + /** + * ID of the DM creator or thread creator + */ + owner_id?: Snowflake; + /** + * Application id of the group DM creator if it is bot-created + */ + application_id?: Snowflake; + /** + * ID of the parent category for a channel (each parent category can contain up to 50 channels) + * + * OR + * + * ID of the parent channel for a thread + */ + parent_id?: Snowflake | null; + /** + * When the last pinned message was pinned. + * This may be `null` in events such as `GUILD_CREATE` when a message is not pinned + */ + last_pin_timestamp?: string | null; + /** + * Voice region id for the voice or stage channel, automatic when set to `null` + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + rtc_region?: string | null; + /** + * The camera video quality mode of the voice channel, `1` when not present + * + * See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes + */ + video_quality_mode?: VideoQualityMode; + /** + * The approximate message count of the thread, does not count above 50 even if there are more messages + */ + message_count?: number; + /** + * The approximate member count of the thread, does not count above 50 even if there are more members + */ + member_count?: number; + /** + * The metadata for a thread channel not shared by other channels + */ + thread_metadata?: APIThreadMetadata; + /** + * The client users member for the thread, only included in select endpoints + */ + member?: APIThreadMember; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ +export enum ChannelType { + /** + * A text channel within a guild + */ + GuildText, + /** + * A direct message between users + */ + DM, + /** + * A voice channel within a guild + */ + GuildVoice, + /** + * A direct message between multiple users + */ + GroupDM, + /** + * An organizational category that contains up to 50 channels + * + * See https://support.discord.com/hc/en-us/articles/115001580171-Channel-Categories-101 + */ + GuildCategory, + /** + * A channel that users can follow and crosspost into their own guild + * + * See https://support.discord.com/hc/en-us/articles/360032008192 + */ + GuildNews, + /** + * A channel in which game developers can sell their game on Discord + * + * See https://discord.com/developers/docs/game-and-server-management/special-channels + */ + GuildStore, + /** + * A thread channel (public) within a Guild News channel + */ + GuildNewsThread = 10, + /** + * A public thread channel within a Guild Text channel + */ + GuildPublicThread, + /** + * A private thread channel within a Guild Text channel + */ + GuildPrivateThread, + /** + * A voice channel for hosting events with an audience + * + * See https://support.discord.com/hc/en-us/articles/1500005513722 + */ + GuildStageVoice, +} + +export enum VideoQualityMode { + /** + * Discord chooses the quality for optimal performance + */ + Auto = 1, + /** + * 720p + */ + Full, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-structure + */ +export interface APIMessage { + /** + * ID of the message + */ + id: Snowflake; + /** + * ID of the channel the message was sent in + */ + channel_id: Snowflake; + /** + * ID of the guild the message was sent in + */ + guild_id?: Snowflake; + /** + * The author of this message (only a valid user in the case where the message is generated by a user or bot user) + * + * If the message is generated by a webhook, the author object corresponds to the webhook's id, + * username, and avatar. You can tell if a message is generated by a webhook by checking for the `webhook_id` property + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + author: APIUser; + /** + * Member properties for this message's author + * + * The member object exists in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events + * from text-based guild channels + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * Contents of the message + */ + content: string; + /** + * When this message was sent + */ + timestamp: string; + /** + * When this message was edited (or null if never) + */ + edited_timestamp: string | null; + /** + * Whether this was a TTS message + */ + tts: boolean; + /** + * Whether this message mentions everyone + */ + mention_everyone: boolean; + /** + * Users specifically mentioned in the message + * + * The `member` field is only present in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events + * from text-based guild channels + * + * See https://discord.com/developers/docs/resources/user#user-object + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + mentions: (APIUser & { member?: Omit })[]; + /** + * Roles specifically mentioned in this message + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + mention_roles: APIRole['id'][]; + /** + * Channels specifically mentioned in this message + * + * Not all channel mentions in a message will appear in `mention_channels`. + * - Only textual channels that are visible to everyone in a lurkable guild will ever be included + * - Only crossposted messages (via Channel Following) currently include `mention_channels` at all + * + * If no mentions in the message meet these requirements, this field will not be sent + * + * See https://discord.com/developers/docs/resources/channel#channel-mention-object + */ + mention_channels?: APIChannelMention[]; + /** + * Any attached files + * + * See https://discord.com/developers/docs/resources/channel#attachment-object + */ + attachments: APIAttachment[]; + /** + * Any embedded content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embeds: APIEmbed[]; + /** + * Reactions to the message + * + * See https://discord.com/developers/docs/resources/channel#reaction-object + */ + reactions?: APIReaction[]; + /** + * A nonce that can be used for optimistic message sending (up to 25 characters) + * + * **You will not receive this from further fetches. This is received only once from a `MESSAGE_CREATE` + * event to ensure it got sent** + */ + nonce?: string | number; + /** + * Whether this message is pinned + */ + pinned: boolean; + /** + * If the message is generated by a webhook, this is the webhook's id + */ + webhook_id?: Snowflake; + /** + * Type of message + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-types + */ + type: MessageType; + /** + * Sent with Rich Presence-related chat embeds + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-activity-structure + */ + activity?: APIMessageActivity; + /** + * Sent with Rich Presence-related chat embeds + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-application-structure + */ + application?: Partial; + /** + * Reference data sent with crossposted messages, replies, pins, and thread starter messages + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ + message_reference?: APIMessageReference; + /** + * Message flags combined as a bitfield + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags?: MessageFlags; + /** + * The stickers sent with the message (bots currently can only receive messages with stickers, not send) + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-sticker-structure + */ + stickers?: APISticker[]; + /** + * The message associated with the `message_reference` + * + * This field is only returned for messages with a `type` of `19` (REPLY). + * + * If the message is a reply but the `referenced_message` field is not present, + * the backend did not attempt to fetch the message that was being replied to, + * so its state is unknown. + * + * If the field exists but is `null`, the referenced message was deleted + * + * See https://discord.com/developers/docs/resources/channel#message-object + */ + referenced_message?: APIMessage | null; + /** + * Sent if the message is a response to an Interaction + */ + interaction?: APIMessageInteraction; + /** + * Sent if a thread was started from this message + */ + thread?: APIChannel; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-types + */ +export enum MessageType { + Default, + RecipientAdd, + RecipientRemove, + Call, + ChannelNameChange, + ChannelIconChange, + ChannelPinnedMessage, + GuildMemberJoin, + UserPremiumGuildSubscription, + UserPremiumGuildSubscriptionTier1, + UserPremiumGuildSubscriptionTier2, + UserPremiumGuildSubscriptionTier3, + ChannelFollowAdd, + GuildDiscoveryDisqualified = 14, + GuildDiscoveryRequalified, + GuildDiscoveryGracePeriodInitialWarning, + GuildDiscoveryGracePeriodFinalWarning, + ThreadCreated, + Reply, + ApplicationCommand, + ThreadStarterMessage, + GuildInviteReminder, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-activity-structure + */ +export interface APIMessageActivity { + /** + * Type of message activity + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-activity-types + */ + type: MessageActivityType; + /** + * `party_id` from a Rich Presence event + * + * See https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields + */ + party_id?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ +export interface APIMessageReference { + /** + * ID of the originating message + */ + message_id?: Snowflake; + /** + * ID of the originating message's channel + */ + channel_id: Snowflake; + /** + * ID of the originating message's guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-activity-types + */ +export enum MessageActivityType { + Join = 1, + Spectate, + Listen, + JoinRequest = 5, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-flags + */ +export enum MessageFlags { + /** + * This message has been published to subscribed channels (via Channel Following) + */ + Crossposted = 1 << 0, + /** + * This message originated from a message in another channel (via Channel Following) + */ + IsCrosspost = 1 << 1, + /** + * Do not include any embeds when serializing this message + */ + SuppressEmbeds = 1 << 2, + /** + * The source message for this crosspost has been deleted (via Channel Following) + */ + SourceMessageDeleted = 1 << 3, + /** + * This message came from the urgent message system + */ + Urgent = 1 << 4, + /** + * This message has an associated thread, which shares its id + */ + HasThread = 1 << 5, + /** + * This message is only visible to the user who invoked the Interaction + */ + Ephemeral = 1 << 6, + /** + * This message is an Interaction Response and the bot is "thinking" + */ + Loading = 1 << 7, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-sticker-structure + */ +export interface APISticker { + /** + * ID of the sticker + */ + id: Snowflake; + /** + * ID of the pack the sticker is from + */ + pack_id: Snowflake; + /** + * Name of the sticker + */ + name: string; + /** + * Description of the sticker + */ + description: string; + /** + * A comma-separated list of tags for the sticker + */ + tags?: string; + /** + * Sticker asset hash + */ + asset: string; + /** + * Type of sticker format + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-sticker-format-types + */ + format_type: StickerFormatType; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-sticker-format-types + */ +export enum StickerFormatType { + PNG = 1, + APNG, + LOTTIE, +} + +/** + * https://discord.com/developers/docs/resources/channel#followed-channel-object + */ +export interface APIFollowedChannel { + /** + * Source channel id + */ + channel_id: Snowflake; + /** + * Created target webhook id + */ + webhook_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#reaction-object-reaction-structure + */ +export interface APIReaction { + /** + * Times this emoji has been used to react + */ + count: number; + /** + * Whether the current user reacted using this emoji + */ + me: boolean; + /** + * Emoji information + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emoji: APIPartialEmoji; +} + +/** + * https://discord.com/developers/docs/resources/channel#overwrite-object-overwrite-structure + */ +export interface APIOverwrite { + /** + * Role or user id + */ + id: Snowflake; + /** + * Either 0 (role) or 1 (member) + * + * {@link OverwriteType} + */ + type: OverwriteType; + /** + * Permission bit set + * + * See https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + allow: Permissions; + /** + * Permission bit set + * + * See https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + deny: Permissions; +} + +export enum OverwriteType { + Role, + Member, +} + +/** + * https://discord.com/developers/docs/resources/channel#thread-metadata-object-thread-metadata-structure + */ +export interface APIThreadMetadata { + /** + * Whether the thread is archived + */ + archived: boolean; + /** + * ID of the user that last archived or unarchived the thread + */ + archiver_id?: Snowflake; + /** + * Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080 + */ + auto_archive_duration: ThreadAutoArchiveDuration; + /** + * An ISO8601 timestamp when the thread's archive status was last changed, used for calculating recent activity + */ + archive_timestamp: string; + /** + * When a thread is locked, only users with MANAGE_THREADS can unarchive it + */ + locked?: boolean; +} + +export enum ThreadAutoArchiveDuration { + OneHour = 60, + OneDay = 1440, + ThreeDays = 4320, + OneWeek = 10080, +} + +/** + * https://discord.com/developers/docs/resources/channel#thread-member-object-thread-member-structure + */ +export interface APIThreadMember { + /** + * The id of the thread + */ + id: Snowflake; + /** + * The id of the member + */ + user_id: Snowflake; + /** + * An ISO8601 timestamp for when the member last joined + */ + join_timestamp: string; + /** + * Member flags combined as a bitfield + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags: ThreadMemberFlags; +} + +export enum ThreadMemberFlags {} + +export interface APIThreadList { + /** + * The threads that were fetched + */ + threads: APIChannel[]; + /** + * The members for the client user in each of the fetched threads + */ + members: APIThreadMember[]; + /** + * Whether there are potentially additional threads + */ + has_more?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-structure + * + * Length limit: 6000 characters + */ +export interface APIEmbed { + /** + * Title of embed + * + * Length limit: 256 characters + */ + title?: string; + /** + * Type of embed (always "rich" for webhook embeds) + * + * @deprecated *Embed types should be considered deprecated and might be removed in a future API version* + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-types + */ + type?: EmbedType; + /** + * Description of embed + * + * Length limit: 2048 characters + */ + description?: string; + /** + * URL of embed + */ + url?: string; + /** + * Timestamp of embed content + */ + timestamp?: string; + /** + * Color code of the embed + */ + color?: number; + /** + * Footer information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure + */ + footer?: APIEmbedFooter; + /** + * Image information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure + */ + image?: APIEmbedImage; + /** + * Thumbnail information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure + */ + thumbnail?: APIEmbedThumbnail; + /** + * Video information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure + */ + video?: APIEmbedVideo; + /** + * Provider information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure + */ + provider?: APIEmbedProvider; + /** + * Author information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure + */ + author?: APIEmbedAuthor; + /** + * Fields information + * + * Length limit: 25 field objects + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure + */ + fields?: APIEmbedField[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-types + * @deprecated *Embed types should be considered deprecated and might be removed in a future API version* + */ +export enum EmbedType { + /** + * Generic embed rendered from embed attributes + */ + Rich = 'rich', + /** + * Image embed + */ + Image = 'image', + /** + * Video embed + */ + Video = 'video', + /** + * Animated gif image embed rendered as a video embed + */ + GIFV = 'gifv', + /** + * Article embed + */ + Article = 'article', + /** + * Link embed + */ + Link = 'link', +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure + */ +export interface APIEmbedThumbnail { + /** + * Source url of thumbnail (only supports http(s) and attachments) + */ + url?: string; + /** + * A proxied url of the thumbnail + */ + proxy_url?: string; + /** + * Height of thumbnail + */ + height?: number; + /** + * Width of thumbnail + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure + */ +export interface APIEmbedVideo { + /** + * Source url of video + */ + url?: string; + /** + * Height of video + */ + height?: number; + /** + * Width of video + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure + */ +export interface APIEmbedImage { + /** + * Source url of image (only supports http(s) and attachments) + */ + url?: string; + /** + * A proxied url of the image + */ + proxy_url?: string; + /** + * Height of image + */ + height?: number; + /** + * Width of image + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure + */ +export interface APIEmbedProvider { + /** + * Name of provider + */ + name?: string; + /** + * URL of provider + */ + url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure + */ +export interface APIEmbedAuthor { + /** + * Name of author + * + * Length limit: 256 characters + */ + name?: string; + /** + * URL of author + */ + url?: string; + /** + * URL of author icon (only supports http(s) and attachments) + */ + icon_url?: string; + /** + * A proxied url of author icon + */ + proxy_icon_url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure + */ +export interface APIEmbedFooter { + /** + * Footer text + * + * Length limit: 2048 characters + */ + text: string; + /** + * URL of footer icon (only supports http(s) and attachments) + */ + icon_url?: string; + /** + * A proxied url of footer icon + */ + proxy_icon_url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure + */ +export interface APIEmbedField { + /** + * Name of the field + * + * Length limit: 256 characters + */ + name: string; + /** + * Value of the field + * + * Length limit: 1024 characters + */ + value: string; + /** + * Whether or not this field should display inline + */ + inline?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#attachment-object-attachment-structure + */ +export interface APIAttachment { + /** + * Attachment id + */ + id: Snowflake; + /** + * Name of file attached + */ + filename: string; + /** + * The attachment's media type + * + * See https://en.wikipedia.org/wiki/Media_type + */ + content_type?: string; + /** + * Size of file in bytes + */ + size: number; + /** + * Source url of file + */ + url: string; + /** + * A proxied url of file + */ + proxy_url: string; + /** + * Height of file (if image) + */ + height?: number | null; + /** + * Width of file (if image) + */ + width?: number | null; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-mention-object-channel-mention-structure + */ +export interface APIChannelMention { + /** + * ID of the channel + */ + id: Snowflake; + /** + * ID of the guild containing the channel + */ + guild_id: Snowflake; + /** + * The type of channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ + type: ChannelType; + /** + * The name of the channel + */ + name: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types + */ +export enum AllowedMentionsTypes { + /** + * Controls @everyone and @here mentions + */ + Everyone = 'everyone', + /** + * Controls role mentions + */ + Role = 'roles', + /** + * Controls user mentions + */ + User = 'users', +} + +/** + * https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mentions-structure + */ +export interface APIAllowedMentions { + /** + * An array of allowed mention types to parse from the content + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types + */ + parse?: AllowedMentionsTypes[]; + /** + * Array of role_ids to mention (Max size of 100) + */ + roles?: Snowflake[]; + /** + * Array of user_ids to mention (Max size of 100) + */ + users?: Snowflake[]; + /** + * For replies, whether to mention the author of the message being replied to (default false) + * + * @default false + */ + replied_user?: boolean; +} diff --git a/deno/payloads/v9/emoji.ts b/deno/payloads/v9/emoji.ts new file mode 100644 index 00000000..583a5428 --- /dev/null +++ b/deno/payloads/v9/emoji.ts @@ -0,0 +1,51 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/emoji + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIRole } from './permissions.ts'; +import type { APIUser } from './user.ts'; + +/** + * Not documented but mentioned + */ +export interface APIPartialEmoji { + /** + * Emoji id + */ + id: Snowflake | null; + /** + * Emoji name (can be null only in reaction emoji objects) + */ + name: string | null; + /** + * Whether this emoji is animated + */ + animated?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure + */ +export interface APIEmoji extends APIPartialEmoji { + /** + * Roles this emoji is whitelisted to + */ + roles?: APIRole['id'][]; + /** + * User that created this emoji + */ + user?: APIUser; + /** + * Whether this emoji must be wrapped in colons + */ + require_colons?: boolean; + /** + * Whether this emoji is managed + */ + managed?: boolean; + /** + * Whether this emoji can be used, may be false due to loss of Server Boosts + */ + available?: boolean; +} diff --git a/deno/payloads/v9/gateway.ts b/deno/payloads/v9/gateway.ts new file mode 100644 index 00000000..d944528b --- /dev/null +++ b/deno/payloads/v9/gateway.ts @@ -0,0 +1,363 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/gateway + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIChannel, APIThreadMember } from './channel.ts'; +import type { APIEmoji } from './emoji.ts'; +import type { APIUser } from './user.ts'; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway + */ +export interface APIGatewayInfo { + /** + * The WSS URL that can be used for connecting to the gateway + */ + url: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway-bot + */ +export interface APIGatewayBotInfo extends APIGatewayInfo { + /** + * The recommended number of shards to use when connecting + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shards: number; + /** + * Information on the current session start limit + * + * See https://discord.com/developers/docs/topics/gateway#session-start-limit-object + */ + session_start_limit: APIGatewaySessionStartLimit; +} + +/** + * https://discord.com/developers/docs/topics/gateway#session-start-limit-object + */ +export interface APIGatewaySessionStartLimit { + /** + * The total number of session starts the current user is allowed + */ + total: number; + /** + * The remaining number of session starts the current user is allowed + */ + remaining: number; + /** + * The number of milliseconds after which the limit resets + */ + reset_after: number; + /** + * The number of identify requests allowed per 5 seconds + */ + max_concurrency: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update-presence-update-event-fields + */ +export interface GatewayPresenceUpdate { + /** + * The user presence is being updated for + * + * **The user object within this event can be partial, the only field which must be sent is the `id` field, + * everything else is optional.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: Partial & Pick; + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * Either "idle", "dnd", "online", or "offline" + */ + status?: PresenceUpdateStatus; + /** + * User's current activities + * + * See https://discord.com/developers/docs/topics/gateway#activity-object + */ + activities?: GatewayActivity[]; + /** + * User's platform-dependent status + * + * See https://discord.com/developers/docs/topics/gateway#client-status-object + */ + client_status?: GatewayPresenceClientStatus; +} + +export enum PresenceUpdateStatus { + Online = 'online', + DoNotDisturb = 'dnd', + Idle = 'idle', + /** + * Invisible and shown as offline + */ + Invisible = 'invisible', + Offline = 'offline', +} + +/** + * https://discord.com/developers/docs/topics/gateway#client-status-object + */ +export interface GatewayPresenceClientStatus { + /** + * The user's status set for an active desktop (Windows, Linux, Mac) application session + */ + desktop?: PresenceUpdateStatus; + /** + * The user's status set for an active mobile (iOS, Android) application session + */ + mobile?: PresenceUpdateStatus; + /** + * The user's status set for an active web (browser, bot account) application session + */ + web?: PresenceUpdateStatus; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-structure + */ +export interface GatewayActivity { + /** + * The activity's id + */ + id: string; + /** + * The activity's name + */ + name: string; + /** + * Activity type + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-types + */ + type: ActivityType; + /** + * Stream url, is validated when type is `1` + */ + url?: string | null; + /** + * Unix timestamp of when the activity was added to the user's session + */ + created_at: number; + /** + * Unix timestamps for start and/or end of the game + */ + timestamps?: GatewayActivityTimestamps; + sync_id?: string; + platform?: ActivityPlatform; + /** + * Application id for the game + */ + application_id?: Snowflake; + /** + * What the player is currently doing + */ + details?: string | null; + /** + * The user's current party status + */ + state?: string | null; + /** + * The emoji used for a custom status + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji + */ + emoji?: GatewayActivityEmoji; + session_id?: string; + /** + * Information for the current party of the player + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-party + */ + party?: GatewayActivityParty; + /** + * Images for the presence and their hover texts + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets + */ + assets?: GatewayActivityAssets; + /** + * Secrets for Rich Presence joining and spectating + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets + */ + secrets?: GatewayActivitySecrets; + /** + * Whether or not the activity is an instanced game session + */ + instance?: boolean; + /** + * Activity flags `OR`d together, describes what the payload includes + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags?: ActivityFlags; + /** + * The custom buttons shown in the Rich Presence (max 2) + */ + buttons?: string[] | GatewayActivityButton[]; +} + +export enum ActivityPlatform { + Desktop = 'desktop', + Samsung = 'samsung', + Xbox = 'xbox', +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-types + */ +export enum ActivityType { + /** + * Playing {game} + */ + Game, + /** + * Streaming {details} + */ + Streaming, + /** + * Listening to {name} + */ + Listening, + /** + * Watching {details} + */ + Watching, + /** + * {emoji} {details} + */ + Custom, + /** + * Competing in {name} + */ + Competing, +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-timestamps + */ +export interface GatewayActivityTimestamps { + /** + * Unix time (in milliseconds) of when the activity started + */ + start?: number; + /** + * Unix time (in milliseconds) of when the activity ends + */ + end?: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji + */ +export type GatewayActivityEmoji = Partial> & Pick; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-party + */ +export interface GatewayActivityParty { + /** + * The id of the party + */ + id?: string; + /** + * Used to show the party's current and maximum size + */ + size?: [current_size: number, max_size: number]; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets + */ +export type GatewayActivityAssets = Partial< + Record<'large_image' | 'large_text' | 'small_image' | 'small_text', string> +>; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets + */ +export type GatewayActivitySecrets = Partial>; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags + */ +export enum ActivityFlags { + Instance = 1 << 0, + Join = 1 << 1, + Spectate = 1 << 2, + JoinRequest = 1 << 3, + Sync = 1 << 4, + Play = 1 << 5, +} + +export interface GatewayActivityButton { + /** + * The text shown on the button (1-32 characters) + */ + label: string; + /** + * The url opened when clicking the button (1-512 characters) + */ + url: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync-thread-list-sync-event-fields + */ +export interface GatewayThreadListSync { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * The ids of all the parent channels whose threads are being synced, otherwise the entire guild + */ + channel_ids?: Snowflake[]; + /** + * Array of the synced threads + */ + threads: APIChannel[]; + /** + * The member objects for the client user in each joined thread that was synced + */ + members: Record; +} + +export type GatewayThreadListSyncMember = Omit; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update-thread-members-update-event-fields + */ +export interface GatewayThreadMembersUpdate { + /** + * The id of the thread for which members are being synced + */ + id: Snowflake; + /** + * The id of the guild that the thread is in + */ + guild_id: Snowflake; + /** + * The approximate member count of the thread, does not count above 50 even if there are more members + */ + member_count: number; + /** + * The members that were added to the thread + */ + added_members?: APIThreadMember[]; + /** + * The ids of the members that were removed from the thread + */ + removed_member_ids?: Snowflake[]; +} diff --git a/deno/payloads/v9/guild.ts b/deno/payloads/v9/guild.ts new file mode 100644 index 00000000..0546a48e --- /dev/null +++ b/deno/payloads/v9/guild.ts @@ -0,0 +1,884 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/guild + */ + +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { APIChannel } from './channel.ts'; +import type { APIEmoji } from './emoji.ts'; +import type { GatewayPresenceUpdate, PresenceUpdateStatus } from './gateway.ts'; +import type { APIRole } from './permissions.ts'; +import type { APIUser } from './user.ts'; +import type { GatewayVoiceState } from './voice.ts'; + +/** + * https://discord.com/developers/docs/resources/guild#unavailable-guild-object + */ +export interface APIUnavailableGuild { + /** + * Guild id + */ + id: Snowflake; + /** + * `true` if this guild is unavailable due to an outage + */ + unavailable: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-structure + */ +export interface APIPartialGuild extends Omit, Pick { + /** + * Guild name (2-100 characters, excluding trailing and leading whitespace) + */ + name: string; + /** + * Icon hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * Splash hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + splash: string | null; + /** + * Banner hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + banner?: string | null; + /** + * The description for the guild, if the guild is discoverable + */ + description?: string | null; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features?: GuildFeature[]; + /** + * Verification level required for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel; + /** + * The vanity url code for the guild + */ + vanity_url_code?: string | null; + /** + * `true` if this guild is unavailable due to an outage + */ + unavailable?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-structure + */ +export interface APIGuild extends APIPartialGuild { + /** + * Icon hash, returned when in the template object + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon_hash?: string | null; + /** + * Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + discovery_splash: string | null; + /** + * `true` if the user is the owner of the guild + * + * **This field is only received from https://discord.com/developers/docs/resources/user#get-current-user-guilds** + */ + owner?: boolean; + /** + * ID of owner + */ + owner_id: Snowflake; + /** + * Total permissions for the user in the guild (excludes overrides) + * + * **This field is only received from https://discord.com/developers/docs/resources/user#get-current-user-guilds** + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + permissions?: Permissions; + /** + * Voice region id for the guild + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + * @deprecated This field has been deprecated in favor of `rtc_region` on the channel. + */ + region: string; + /** + * ID of afk channel + */ + afk_channel_id: Snowflake | null; + /** + * afk timeout in seconds + */ + afk_timeout: number; + /** + * `true` if the guild widget is enabled + */ + widget_enabled?: boolean; + /** + * The channel id that the widget will generate an invite to, or `null` if set to no invite + */ + widget_channel_id?: Snowflake | null; + /** + * Verification level required for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level: GuildVerificationLevel; + /** + * Default message notifications level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications: GuildDefaultMessageNotifications; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter: GuildExplicitContentFilter; + /** + * Roles in the guild + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles: APIRole[]; + /** + * Custom guild emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features: GuildFeature[]; + /** + * Required MFA level for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-mfa-level + */ + mfa_level: GuildMFALevel; + /** + * Application id of the guild creator if it is bot-created + */ + application_id: Snowflake | null; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id: Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags: GuildSystemChannelFlags; + /** + * The id of the channel where Community guilds can display rules and/or guidelines + */ + rules_channel_id: Snowflake | null; + /** + * When this guild was joined at + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + joined_at?: string; + /** + * `true` if this is considered a large guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + large?: boolean; + /** + * Total number of members in this guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + member_count?: number; + /** + * States of members currently in voice channels; lacks the `guild_id` key + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/voice#voice-state-object + */ + voice_states?: Omit[]; + /** + * Users in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + members?: APIGuildMember[]; + /** + * Channels in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channels?: APIChannel[]; + /** + * Threads in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + threads?: APIChannel[]; + /** + * Presences of the members in the guild, will only include non-offline members if the size is greater than `large_threshold` + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/topics/gateway#presence-update + */ + presences?: GatewayPresenceUpdate[]; + /** + * The maximum number of presences for the guild (the default value, currently 25000, is in effect when `null` is returned) + */ + max_presences?: number | null; + /** + * The maximum number of members for the guild + */ + max_members?: number; + /** + * The vanity url code for the guild + */ + vanity_url_code: string | null; + /** + * The description for the guild, if the guild is discoverable + */ + description: string | null; + /** + * Banner hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + banner: string | null; + /** + * Premium tier (Server Boost level) + * + * See https://discord.com/developers/docs/resources/guild#guild-object-premium-tier + */ + premium_tier: GuildPremiumTier; + /** + * The number of boosts this guild currently has + */ + premium_subscription_count?: number; + /** + * The preferred locale of a Community guild; used in guild discovery and notices from Discord; defaults to "en-US" + * + * @default "en-US" + */ + preferred_locale: string; + /** + * The id of the channel where admins and moderators of Community guilds receive notices from Discord + */ + public_updates_channel_id: Snowflake | null; + /** + * The maximum amount of users in a video channel + */ + max_video_channel_users?: number; + /** + * **This field is only received from https://discord.com/developers/docs/resources/guild#get-guild with the `with_counts` query parameter set to `true`** + */ + approximate_member_count?: number; + /** + * **This field is only received from https://discord.com/developers/docs/resources/guild#get-guild with the `with_counts` query parameter set to `true`** + */ + approximate_presence_count?: number; + /** + * The welcome screen of a Community guild, shown to new members + * + * Returned in the invite object + */ + welcome_screen?: APIGuildWelcomeScreen; + /** + * `true` if this guild is designated as NSFW + * + * See https://support.discord.com/hc/en-us/articles/1500005389362-NSFW-Server-Designation + */ + nsfw: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ +export enum GuildDefaultMessageNotifications { + AllMessages, + OnlyMentions, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ +export enum GuildExplicitContentFilter { + Disabled, + MembersWithoutRoles, + AllMembers, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-mfa-level + */ +export enum GuildMFALevel { + None, + Elevated, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ +export enum GuildVerificationLevel { + /** + * Unrestricted + */ + None, + /** + * Must have verified email on account + */ + Low, + /** + * Must be registered on Discord for longer than 5 minutes + */ + Medium, + /** + * Must be a member of the guild for longer than 10 minutes + */ + High, + /** + * Must have a verified phone number + */ + VeryHigh, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-premium-tier + */ +export enum GuildPremiumTier { + None, + Tier1, + Tier2, + Tier3, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ +export enum GuildSystemChannelFlags { + /** + * Suppress member join notifications + */ + SuppressJoinNotifications = 1 << 0, + /** + * Suppress server boost notifications + */ + SuppressPremiumSubscriptions = 1 << 1, + /** + * Suppress server setup tips + */ + SuppressGuildReminderNotifications = 1 << 2, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ +export enum GuildFeature { + /** + * Guild has access to set an animated guild icon + */ + AnimatedIcon = 'ANIMATED_ICON', + /** + * Guild has access to set a guild banner image + */ + Banner = 'BANNER', + /** + * Guild has access to use commerce features (i.e. create store channels) + */ + Commerce = 'COMMERCE', + /** + * Guild can enable welcome screen, Membership Screening and discovery, and receives community updates + */ + Community = 'COMMUNITY', + /** + * Guild is able to be discovered in the directory + */ + Discoverable = 'DISCOVERABLE', + /** + * Guild is able to be featured in the directory + */ + Featurable = 'FEATURABLE', + /** + * Guild has access to set an invite splash background + */ + InviteSplash = 'INVITE_SPLASH', + /** + * Guild has access to create news channels + */ + News = 'NEWS', + /** + * Guild is partnered + */ + Partnered = 'PARTNERED', + RelayEnabled = 'RELAY_ENABLED', + /** + * Guild has access to set a vanity URL + */ + VanityURL = 'VANITY_URL', + /** + * Guild is verified + */ + Verified = 'VERIFIED', + /** + * Guild has access to set 384kbps bitrate in voice (previously VIP voice servers) + */ + VIPRegions = 'VIP_REGIONS', + /** + * Guild has enabled the welcome screen + */ + WelcomeScreenEnabled = 'WELCOME_SCREEN_ENABLED', + /** + * Guild has enabled Membership Screening + */ + MemberVerificationGateEnabled = 'MEMBER_VERIFICATION_GATE_ENABLED', + /** + * Guild can be previewed before joining via Membership Screening or the directory + */ + PreviewEnabled = 'PREVIEW_ENABLED', +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-preview-object + */ +export interface APIGuildPreview { + /** + * Guild id + */ + id: Snowflake; + /** + * Guild name (2-100 characters) + */ + name: string; + /** + * Icon hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * Splash hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + splash: string | null; + /** + * Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + discovery_splash: string | null; + /** + * Custom guild emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features: GuildFeature[]; + /** + * Approximate number of members in this guild + */ + approximate_member_count: number; + /** + * Approximate number of online members in this guild + */ + approximate_presence_count: number; + /** + * The description for the guild + */ + description: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-widget-object + */ +export interface APIGuildWidgetSettings { + /** + * Whether the widget is enabled + */ + enabled: boolean; + /** + * The widget channel id + */ + channel_id: Snowflake | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIGuildMember { + /** + * The user this guild member represents + * + * **This field won't be included in the member object attached to `MESSAGE_CREATE` and `MESSAGE_UPDATE` gateway events.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * This users guild nickname + */ + nick?: string | null; + /** + * Array of role object ids + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles: Snowflake[]; + /** + * When the user joined the guild + */ + joined_at: string; + /** + * When the user started boosting the guild + * + * See https://support.discord.com/hc/en-us/articles/360028038352-Server-Boosting- + */ + premium_since?: string | null; + /** + * Whether the user is deafened in voice channels + */ + deaf: boolean; + /** + * Whether the user is muted in voice channels + */ + mute: boolean; + /** + * Whether the user has not yet passed the guild's Membership Screening requirements + * + * *If this field is not present, it can be assumed as `false`.* + */ + pending?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-object + */ +export interface APIGuildIntegration { + /** + * Integration id + */ + id: Snowflake; + /** + * Integration name + */ + name: string; + /** + * Integration type + */ + type: APIGuildInteractionType; + /** + * Is this integration enabled + */ + enabled: boolean; + /** + * Is this integration syncing + * + * **This field is not provided for `discord` bot integrations.** + */ + syncing?: boolean; + /** + * ID that this integration uses for "subscribers" + * + * **This field is not provided for `discord` bot integrations.** + */ + role_id?: Snowflake; + /** + * Whether emoticons should be synced for this integration (`twitch` only currently) + * + * **This field is not provided for `discord` bot integrations.** + */ + enable_emoticons?: boolean; + /** + * The behavior of expiring subscribers + * + * **This field is not provided for `discord` bot integrations.** + * + * See https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors + */ + expire_behavior?: IntegrationExpireBehavior; + /** + * The grace period (in days) before expiring subscribers + * + * **This field is not provided for `discord` bot integrations.** + */ + expire_grace_period?: number; + /** + * User for this integration + * + * **This field is not provided for `discord` bot integrations.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * Integration account information + * + * See https://discord.com/developers/docs/resources/guild#integration-account-object + */ + account: APIIntegrationAccount; + /** + * When this integration was last synced + * + * **This field is not provided for `discord` bot integrations.** + */ + synced_at?: string; + /** + * How many subscribers this integration has + * + * **This field is not provided for `discord` bot integrations.** + */ + subscriber_count?: number; + /** + * Has this integration been revoked + * + * **This field is not provided for `discord` bot integrations.** + */ + revoked?: boolean; + /** + * The bot/OAuth2 application for discord integrations + * + * See https://discord.com/developers/docs/resources/guild#integration-application-object + * + * **This field is not provided for `discord` bot integrations.** + */ + application?: APIGuildIntegrationApplication; +} + +export type APIGuildInteractionType = 'twitch' | 'youtube' | 'discord'; + +/** + * https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors + */ +export enum IntegrationExpireBehavior { + RemoveRole, + Kick, +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-account-object + */ +export interface APIIntegrationAccount { + /** + * ID of the account + */ + id: string; + /** + * Name of the account + */ + name: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-application-object + */ +export interface APIGuildIntegrationApplication { + /** + * The id of the app + */ + id: Snowflake; + /** + * The name of the app + */ + name: string; + /** + * The icon hash of the app + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * The description of the app + */ + description: string; + /** + * The summary of the app + */ + summary: string; + /** + * The bot associated with this application + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + bot?: APIUser; +} + +/** + * https://discord.com/developers/docs/resources/guild#ban-object + */ +export interface APIBan { + /** + * The reason for the ban + */ + reason: string | null; + /** + * The banned user + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidget { + id: Snowflake; + name: string; + instant_invite: string | null; + channels: APIGuildWidgetChannel[]; + members: APIGuildWidgetMember[]; + presence_count: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidgetChannel { + id: Snowflake; + name: string; + position: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidgetMember { + id: string; + username: string; + discriminator: string; + avatar: string | null; + status: PresenceUpdateStatus; + activity?: { name: string }; + avatar_url: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-image-widget-style-options + */ +export enum GuildWidgetStyle { + /** + * Shield style widget with Discord icon and guild members online count + */ + Shield = 'shield', + /** + * Large image with guild icon, name and online count. "POWERED BY DISCORD" as the footer of the widget + */ + Banner1 = 'banner1', + /** + * Smaller widget style with guild icon, name and online count. Split on the right with Discord logo + */ + Banner2 = 'banner2', + /** + * Large image with guild icon, name and online count. In the footer, Discord logo on the left and "Chat Now" on the right + */ + Banner3 = 'banner3', + /** + * Large Discord logo at the top of the widget. Guild icon, name and online count in the middle portion of the widget + * and a "JOIN MY SERVER" button at the bottom + */ + Banner4 = 'banner4', +} + +export interface APIGuildWelcomeScreen { + /** + * The welcome screen short message + */ + description: string | null; + /** + * Array of suggested channels + */ + welcome_channels: APIGuildWelcomeScreenChannel[]; +} + +export interface APIGuildWelcomeScreenChannel { + /** + * The channel id that is suggested + */ + channel_id: Snowflake; + /** + * The description shown for the channel + */ + description: string; + /** + * The emoji id of the emoji that is shown on the left of the channel + */ + emoji_id: Snowflake | null; + /** + * The emoji name of the emoji that is shown on the left of the channel + */ + emoji_name: string | null; +} + +export interface APIGuildMembershipScreening { + /** + * When the fields were last updated + */ + version: string; + /** + * The steps in the screening form + */ + form_fields: APIGuildMembershipScreeningField[]; + /** + * The server description shown in the screening form + */ + description: string | null; +} + +// TODO: make this a union based on the type in the future, when new types are added + +export interface APIGuildMembershipScreeningField { + /** + * The type of field + */ + field_type: MembershipScreeningFieldType; + /** + * The title of the field + */ + label: string; + /** + * The list of rules + */ + values?: string[]; + /** + * Whether the user has to fill out this field + */ + required: boolean; +} + +export enum MembershipScreeningFieldType { + /** + * Server Rules + */ + Terms = 'TERMS', +} diff --git a/deno/payloads/v9/interactions.ts b/deno/payloads/v9/interactions.ts new file mode 100644 index 00000000..96daf49e --- /dev/null +++ b/deno/payloads/v9/interactions.ts @@ -0,0 +1,426 @@ +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../rest/v9/mod.ts'; +import type { APIGuildMember, APIPartialChannel, APIRole, APIUser, MessageFlags } from './mod.ts'; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommand + */ +export interface APIApplicationCommand { + /** + * Unique id of the command + */ + id: Snowflake; + /** + * Unique id of the parent application + */ + application_id: Snowflake; + /** + * 1-32 character name matching `^[\w-]{1,32}$` + */ + name: string; + /** + * 1-100 character description + */ + description: string; + /** + * The parameters for the command + */ + options?: APIApplicationCommandOption[]; + /** + * Whether the command is enabled by default when the app is added to a guild + * + * If missing, this property should be assumed as `true` + */ + default_permission?: boolean; +} + +interface APIApplicationCommandOptionBase { + type: + | ApplicationCommandOptionType.Boolean + | ApplicationCommandOptionType.User + | ApplicationCommandOptionType.Channel + | ApplicationCommandOptionType.Role + | ApplicationCommandOptionType.Mentionable; + name: string; + description: string; + default?: boolean; + required?: boolean; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption + */ +export type APIApplicationCommandOption = + | APIApplicationCommandArgumentOptions + | APIApplicationCommandSubCommandOptions + | APIApplicationCommandOptionBase; + +/** + * This type is exported as a way to make it stricter for you when you're writing your commands + * + * If the option is a `SUB_COMMAND` or `SUB_COMMAND_GROUP` type, this nested options will be the parameters + */ +export interface APIApplicationCommandSubCommandOptions extends Omit { + type: ApplicationCommandOptionType.SubCommand | ApplicationCommandOptionType.SubCommandGroup; + options?: APIApplicationCommandOption[]; +} + +/** + * This type is exported as a way to make it stricter for you when you're writing your commands + * + * In contrast to `APIApplicationCommandSubCommandOptions`, these types cannot have an `options` array, + * but they can have a `choices` one + */ +export interface APIApplicationCommandArgumentOptions extends Omit { + type: ApplicationCommandOptionType.String | ApplicationCommandOptionType.Integer; + choices?: APIApplicationCommandOptionChoice[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype + */ +export enum ApplicationCommandOptionType { + SubCommand = 1, + SubCommandGroup, + String, + Integer, + Boolean, + User, + Channel, + Role, + Mentionable, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice + */ +export interface APIApplicationCommandOptionChoice { + name: string; + value: string | number; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIBaseInteraction { + /** + * ID of the interaction + */ + id: Snowflake; + /** + * ID of the application this interaction is for + */ + application_id: Snowflake; + /** + * The type of interaction + */ + type: InteractionType; + /** + * The command data payload + */ + data?: APIApplicationCommandInteractionData; + /** + * The channel it was sent from + */ + channel_id?: Snowflake; + /** + * A continuation token for responding to the interaction + */ + token: string; + /** + * Read-only property, always `1` + */ + version: 1; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIInteractionGuildMember extends APIGuildMember { + permissions: Permissions; + user: APIUser; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIGuildInteraction extends APIBaseInteraction { + /** + * The guild it was sent from + * + * In the case of an `APIDMInteraction`, this will not be present + */ + guild_id: Snowflake; + /** + * Guild member data for the invoking user, including permissions + */ + member: APIInteractionGuildMember; + channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIDMInteraction extends APIBaseInteraction { + /** + * User object for the invoking user, if invoked in a DM + */ + user: APIUser; + channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export type APIInteraction = APIGuildInteraction | APIDMInteraction; + +/** + * Like APIGuildInteraction, only with the `data` property always present + * + * @see APIGuildInteraction + */ +export type APIApplicationCommandGuildInteraction = Required; + +/** + * Like APIDMInteraction, only with the `data` property always present + * + * @see APIDMInteraction + */ +export type APIApplicationCommandDMInteraction = Required; + +/** + * Like APIInteraction, only with the `data` property always present + * + * @see APIInteraction + */ +export type APIApplicationCommandInteraction = + | APIApplicationCommandGuildInteraction + | APIApplicationCommandDMInteraction; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype + */ +export enum InteractionType { + Ping = 1, + ApplicationCommand, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#guildapplicationcommandpermissions + */ +export interface APIGuildApplicationCommandPermissions { + /** + * The id of the command + */ + id: Snowflake; + /** + * The id of the application the command belongs to + */ + application_id: Snowflake; + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The permissions for the command in the guild + */ + permissions: APIApplicationCommandPermission[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandpermissions + */ +export interface APIApplicationCommandPermission { + /** + * The id of the role or user + */ + id: Snowflake; + /** + * Role or user + */ + type: ApplicationCommandPermissionType; + /** + * `true` to allow, `false`, to disallow + */ + permission: boolean; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandpermissiontype + */ +export enum ApplicationCommandPermissionType { + Role = 1, + User, +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object + */ +export interface APIInteractionDataResolvedChannel extends Required { + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIInteractionDataResolvedGuildMember extends Omit { + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-applicationcommandinteractiondata + */ +export interface APIApplicationCommandInteractionData { + id: Snowflake; + name: string; + options?: APIApplicationCommandInteractionDataOption[]; + resolved?: { + users?: Record; + roles?: Record; + members?: Record; + channels?: Record; + }; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-applicationcommandinteractiondataoption + */ +export type APIApplicationCommandInteractionDataOption = + | ApplicationCommandInteractionDataOptionSubCommand + | ApplicationCommandInteractionDataOptionSubCommandGroup + | APIApplicationCommandInteractionDataOptionWithValues; + +export interface ApplicationCommandInteractionDataOptionSubCommand { + name: string; + type: ApplicationCommandOptionType.SubCommand; + options: APIApplicationCommandInteractionDataOptionWithValues[]; +} + +export interface ApplicationCommandInteractionDataOptionSubCommandGroup { + name: string; + type: ApplicationCommandOptionType.SubCommandGroup; + options: ApplicationCommandInteractionDataOptionSubCommand[]; +} + +export type APIApplicationCommandInteractionDataOptionWithValues = + | ApplicationCommandInteractionDataOptionString + | ApplicationCommandInteractionDataOptionRole + | ApplicationCommandInteractionDataOptionChannel + | ApplicationCommandInteractionDataOptionUser + | ApplicationCommandInteractionDataOptionMentionable + | ApplicationCommandInteractionDataOptionInteger + | ApplicationCommandInteractionDataOptionBoolean; + +export type ApplicationCommandInteractionDataOptionString = InteractionDataOptionBase< + ApplicationCommandOptionType.String, + string +>; + +export type ApplicationCommandInteractionDataOptionRole = InteractionDataOptionBase< + ApplicationCommandOptionType.Role, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionChannel = InteractionDataOptionBase< + ApplicationCommandOptionType.Channel, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionUser = InteractionDataOptionBase< + ApplicationCommandOptionType.User, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionMentionable = InteractionDataOptionBase< + ApplicationCommandOptionType.Mentionable, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionInteger = InteractionDataOptionBase< + ApplicationCommandOptionType.Integer, + number +>; + +export type ApplicationCommandInteractionDataOptionBoolean = InteractionDataOptionBase< + ApplicationCommandOptionType.Boolean, + boolean +>; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response + */ +export type APIInteractionResponse = + | APIInteractionResponsePong + | APIInteractionResponseChannelMessageWithSource + | APIInteractionResponseDeferredChannelMessageWithSource; + +export interface APIInteractionResponsePong { + type: InteractionResponseType.Pong; +} + +export interface APIInteractionResponseChannelMessageWithSource { + type: InteractionResponseType.ChannelMessageWithSource; + data: APIInteractionApplicationCommandCallbackData; +} + +export interface APIInteractionResponseDeferredChannelMessageWithSource { + type: InteractionResponseType.DeferredChannelMessageWithSource; + data?: Pick; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionresponsetype + */ +export enum InteractionResponseType { + /** + * ACK a `Ping` + */ + Pong = 1, + /** + * Respond to an interaction with a message + */ + ChannelMessageWithSource = 4, + /** + * ACK an interaction and edit to a response later, the user sees a loading state + */ + DeferredChannelMessageWithSource, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionapplicationcommandcallbackdata + */ +export type APIInteractionApplicationCommandCallbackData = Omit< + RESTPostAPIWebhookWithTokenJSONBody, + 'username' | 'avatar_url' +> & { flags?: MessageFlags }; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#messageinteraction + */ +export interface APIMessageInteraction { + /** + * ID of the interaction + */ + id: Snowflake; + /** + * The type of interaction + */ + type: InteractionType; + /** + * The name of the ApplicationCommand + */ + name: string; + /** + * The user who invoked the interaction + */ + user: APIUser; +} + +/** + * @internal + */ +interface InteractionDataOptionBase { + name: string; + type: T; + value: D; +} diff --git a/deno/payloads/v9/invite.ts b/deno/payloads/v9/invite.ts new file mode 100644 index 00000000..95a4177c --- /dev/null +++ b/deno/payloads/v9/invite.ts @@ -0,0 +1,100 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/invite + */ + +import type { APIPartialChannel } from './channel.ts'; +import type { APIPartialGuild } from './guild.ts'; +import type { APIApplication } from './oauth2.ts'; +import type { APIUser } from './user.ts'; + +/** + * https://discord.com/developers/docs/resources/invite#invite-object + */ +export interface APIInvite { + /** + * The invite code (unique ID) + */ + code: string; + /** + * The guild this invite is for + * + * See https://discord.com/developers/docs/resources/guild#guild-object + */ + guild?: APIPartialGuild; + /** + * The channel this invite is for + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channel: Required; + /** + * The user who created the invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + inviter?: APIUser; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-target-user-types + */ + target_type?: InviteTargetType; + /** + * The user whose stream to display for this voice channel stream invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + target_user?: APIUser; + /** + * The embedded application to open for this voice channel embedded application invite + * + * See https://discord.com/developers/docs/topics/oauth2#application + */ + target_application?: Partial; + /** + * Approximate count of online members, returned from the `GET /invites/` endpoint when `with_counts` is `true` + */ + approximate_presence_count?: number; + /** + * Approximate count of total members, returned from the `GET /invites/` endpoint when `with_counts` is `true` + */ + approximate_member_count?: number; + /** + * The expiration date of this invite, returned from the `GET /invites/` endpoint when `with_expiration` is `true` + */ + expires_at?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ +export enum InviteTargetType { + Stream = 1, + EmbeddedApplication, +} + +/** + * https://discord.com/developers/docs/resources/invite#invite-metadata-object + */ +export interface APIExtendedInvite extends APIInvite { + /** + * Number of times this invite has been used + */ + uses: number; + /** + * Max number of times this invite can be used + */ + max_uses: number; + /** + * Duration (in seconds) after which the invite expires + */ + max_age: number; + /** + * Whether this invite only grants temporary membership + */ + temporary: boolean; + /** + * When this invite was created + */ + created_at: string; +} diff --git a/deno/payloads/v9/mod.ts b/deno/payloads/v9/mod.ts new file mode 100644 index 00000000..f512c8bf --- /dev/null +++ b/deno/payloads/v9/mod.ts @@ -0,0 +1,14 @@ +export * from './auditLog.ts'; +export * from './channel.ts'; +export * from './emoji.ts'; +export * from './gateway.ts'; +export * from './guild.ts'; +export * from './interactions.ts'; +export * from './invite.ts'; +export * from './oauth2.ts'; +export * from './permissions.ts'; +export * from './teams.ts'; +export * from './template.ts'; +export * from './user.ts'; +export * from './voice.ts'; +export * from './webhook.ts'; diff --git a/deno/payloads/v9/oauth2.ts b/deno/payloads/v9/oauth2.ts new file mode 100644 index 00000000..7364b614 --- /dev/null +++ b/deno/payloads/v9/oauth2.ts @@ -0,0 +1,209 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/oauth2 + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APITeam } from './teams.ts'; +import type { APIUser } from './user.ts'; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-application-information-response-structure + */ +export interface APIApplication { + /** + * The id of the app + */ + id: Snowflake; + /** + * The name of the app + */ + name: string; + /** + * The icon hash of the app + */ + icon: string | null; + /** + * The description of the app + */ + description: string; + /** + * An array of rpc origin urls, if rpc is enabled + */ + rpc_origins?: string[]; + /** + * When `false` only app owner can join the app's bot to guilds + */ + bot_public: boolean; + /** + * When `true` the app's bot will only join upon completion of the full oauth2 code grant flow + */ + bot_require_code_grant: boolean; + /** + * The url of the application's terms of service + */ + terms_of_service_url?: string; + /** + * The url of the application's privacy policy + */ + privacy_policy_url?: string; + /** + * Partial user object containing info on the owner of the application + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + owner: APIUser; + /** + * If this application is a game sold on Discord, this field will be the summary field for the store page + * of its primary sku + */ + summary: string; + /** + * The hexadecimal encoded key for verification in interactions and the GameSDK's GetTicket function + * + * See https://discord.com/developers/docs/game-sdk/applications#get-ticket + */ + verify_key: string; + /** + * The team this application belongs to + * + * See https://discord.com/developers/docs/topics/teams#data-models-team-object + */ + team: APITeam | null; + /** + * If this application is a game sold on Discord, this field will be the guild to which it has been linked + */ + guild_id?: Snowflake; + /** + * If this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists + */ + primary_sku_id?: Snowflake; + /** + * If this application is a game sold on Discord, this field will be the URL slug that links to the store page + */ + slug?: string; + /** + * If this application is a game sold on Discord, this field will be the hash of the image on store embeds + */ + cover_image?: string; + /** + * The application's public flags + */ + flags: ApplicationFlags; +} + +export enum ApplicationFlags { + ManagedEmoji = 1 << 2, + GroupDMCreate = 1 << 4, + RPCHasConnected = 1 << 11, + GatewayPresence = 1 << 12, + GatewayPresenceLimited = 1 << 13, + GatewayGuildMembers = 1 << 14, + GatewayGuildMembersLimited = 1 << 15, + VerificationPendingGuildLimit = 1 << 16, + Embedded = 1 << 17, +} + +export enum OAuth2Scopes { + /** + * For oauth2 bots, this puts the bot in the user's selected guild by default + */ + Bot = 'bot', + /** + * Allows [/users/@me/connections](https://discord.com/developers/docs/resources/user#get-user-connections) + * to return linked third-party accounts + * + * See https://discord.com/developers/docs/resources/user#get-user-connections + */ + Connections = 'connections', + /** + * Enables [/users/@me](https://discord.com/developers/docs/resources/user#get-current-user) to return an `email` + * + * See https://discord.com/developers/docs/resources/user#get-current-user + */ + Email = 'email', + /** + * Allows [/users/@me](https://discord.com/developers/docs/resources/user#get-current-user) without `email` + * + * See https://discord.com/developers/docs/resources/user#get-current-user + */ + Identify = 'identify', + /** + * Allows [/users/@me/guilds](https://discord.com/developers/docs/resources/user#get-current-user-guilds) + * to return basic information about all of a user's guilds + * + * See https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ + Guilds = 'guilds', + /** + * Allows [/guilds/{guild.id}/members/{user.id}](https://discord.com/developers/docs/resources/guild#add-guild-member) + * to be used for joining users to a guild + * + * See https://discord.com/developers/docs/resources/guild#add-guild-member + */ + GuildsJoin = 'guilds.join', + /** + * Allows your app to join users to a group dm + * + * See https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ + GroupDMJoins = 'gdm.join', + /** + * For local rpc server api access, this allows you to read messages from all client channels + * (otherwise restricted to channels/guilds your app creates) + */ + MessagesRead = 'messages.read', + /** + * For local rpc server access, this allows you to control a user's local Discord client - whitelist only + */ + RPC = 'rpc', + /** + * For local rpc server api access, this allows you to receive notifications pushed out to the user - whitelist only + */ + RPCNotificationsRead = 'rpc.notifications.read', + /** + * This generates a webhook that is returned in the oauth token response for authorization code grants + */ + WebhookIncoming = 'webhook.incoming', + /** + * Allows your app to upload/update builds for a user's applications - whitelist only + */ + ApplicationsBuildsUpload = 'applications.builds.upload', + /** + * Allows your app to read build data for a user's applications + */ + ApplicationsBuildsRead = 'applications.builds.read', + /** + * Allows your app to read and update store data (SKUs, store listings, achievements, etc.) for a user's applications + */ + ApplicationsStoreUpdate = 'applications.store.update', + /** + * Allows your app to read entitlements for a user's applications + */ + ApplicationsEntitlements = 'applications.entitlements', + /** + * Allows your app to know a user's friends and implicit relationships - whitelist only + */ + RelationshipsRead = 'relationships.read', + /** + * Allows your app to fetch data from a user's "Now Playing/Recently Played" list - whitelist only + */ + ActivitiesRead = 'activities.read', + /** + * Allows your app to update a user's activity - whitelist only (NOT REQUIRED FOR GAMESDK ACTIVITY MANAGER) + * + * See https://discord.com/developers/docs/game-sdk/activities + */ + ActivitiesWrite = 'activities.write', + /** + * Allows your app to create Slash Commands in the authorized guild + * + * See https://discord.com/developers/docs/interactions/slash-commands + */ + ApplicationsCommands = 'applications.commands', + /** + * Allows your app to update Slash Commands via this bearer token + * + * See https://discord.com/developers/docs/interactions/slash-commands + */ + ApplicationsCommandsUpdate = 'applications.commands.update', +} diff --git a/deno/payloads/v9/permissions.ts b/deno/payloads/v9/permissions.ts new file mode 100644 index 00000000..6823efd5 --- /dev/null +++ b/deno/payloads/v9/permissions.ts @@ -0,0 +1,119 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/permissions + */ + +import type { Permissions, Snowflake } from '../../globals.ts'; + +/** + * https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * These flags are exported as `BigInt`s and NOT numbers. Wrapping them in `Number()` + * may cause issues, try to use BigInts as much as possible or modules that can + * replicate them in some way + */ +export const PermissionFlagsBits = { + CreateInstantInvite: 1n << 0n, + KickMembers: 1n << 1n, + BanMembers: 1n << 2n, + Administrator: 1n << 3n, + ManageChannels: 1n << 4n, + ManageGuild: 1n << 5n, + AddReactions: 1n << 6n, + ViewAuditLog: 1n << 7n, + PrioritySpeaker: 1n << 8n, + Stream: 1n << 9n, + ViewChannel: 1n << 10n, + SendMessages: 1n << 11n, + SendTTSMessages: 1n << 12n, + ManageMessages: 1n << 13n, + EmbedLinks: 1n << 14n, + AttachFiles: 1n << 15n, + ReadMessageHistory: 1n << 16n, + MentionEveryone: 1n << 17n, + UseExternalEmojis: 1n << 18n, + ViewGuildInsights: 1n << 19n, + Connect: 1n << 20n, + Speak: 1n << 21n, + MuteMembers: 1n << 22n, + DeafenMembers: 1n << 23n, + MoveMembers: 1n << 24n, + UseVAD: 1n << 25n, + ChangeNickname: 1n << 26n, + ManageNicknames: 1n << 27n, + ManageRoles: 1n << 28n, + ManageWebhooks: 1n << 29n, + ManageEmojis: 1n << 30n, + UseSlashCommands: 1n << 31n, + RequestToSpeak: 1n << 32n, + ManageThreads: 1n << 34n, + UsePublicThreads: 1n << 35n, + UsePrivateThreads: 1n << 36n, +} as const; + +/** + * Freeze the object of bits, preventing any modifications to it + * @internal + */ +Object.freeze(PermissionFlagsBits); + +/** + * https://discord.com/developers/docs/topics/permissions#role-object + */ +export interface APIRole { + /** + * Role id + */ + id: Snowflake; + /** + * Role name + */ + name: string; + /** + * Integer representation of hexadecimal color code + */ + color: number; + /** + * If this role is pinned in the user listing + */ + hoist: boolean; + /** + * Position of this role + */ + position: number; + /** + * Permission bit set + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + permissions: Permissions; + /** + * Whether this role is managed by an integration + */ + managed: boolean; + /** + * Whether this role is mentionable + */ + mentionable: boolean; + /** + * The tags this role has + */ + tags?: APIRoleTags; +} + +/** + * https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure + */ +export interface APIRoleTags { + /** + * The id of the bot this role belongs to + */ + bot_id?: Snowflake; + /** + * Whether this is the guild's premium subscriber role + */ + premium_subscriber?: null; + /** + * The id of the integration this role belongs to + */ + integration_id?: Snowflake; +} diff --git a/deno/payloads/v9/teams.ts b/deno/payloads/v9/teams.ts new file mode 100644 index 00000000..6a5b752a --- /dev/null +++ b/deno/payloads/v9/teams.ts @@ -0,0 +1,62 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/teams + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIUser } from './user.ts'; + +/** + * https://discord.com/developers/docs/topics/teams#data-models-team-object + */ +export interface APITeam { + /** + * A hash of the image of the team's icon + */ + icon: string | null; + /** + * The unique id of the team + */ + id: Snowflake; + /** + * The members of the team + */ + members: APITeamMember[]; + /** + * The user id of the current team owner + */ + owner_user_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/teams#data-models-team-members-object + */ +export interface APITeamMember { + /** + * The user's membership state on the team + * + * See https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum + */ + membership_state: TeamMemberMembershipState; + /** + * Will always be `["*"]` + */ + permissions: ['*']; + /** + * The id of the parent team of which they are a member + */ + team_id: Snowflake; + /** + * The avatar, discriminator, id, and username of the user + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum + */ +export enum TeamMemberMembershipState { + Invited = 1, + Accepted, +} diff --git a/deno/payloads/v9/template.ts b/deno/payloads/v9/template.ts new file mode 100644 index 00000000..42564667 --- /dev/null +++ b/deno/payloads/v9/template.ts @@ -0,0 +1,65 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/template + */ + +import type { Snowflake } from '../../globals.ts'; +import type { RESTPostAPIGuildsJSONBody } from '../../rest/v9/mod.ts'; +import type { APIUser } from './user.ts'; + +/** + * https://discord.com/developers/docs/resources/template#template-object + */ +export interface APITemplate { + /** + * The template code (unique ID) + */ + code: string; + /** + * Template name + */ + name: string; + /** + * The description for the template + */ + description: string | null; + /** + * Number of times this template has been used + */ + usage_count: number; + /** + * The ID of the user who created the template + */ + creator_id: Snowflake; + /** + * The user who created the template + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + creator: APIUser; + /** + * When this template was created + */ + created_at: string; + /** + * When this template was last synced to the source guild + */ + updated_at: string; + /** + * The ID of the guild this template is based on + */ + source_guild_id: Snowflake; + /** + * The guild snapshot this template contains + */ + serialized_source_guild: APITemplateSerializedSourceGuild; + /** + * Whether the template has unsynced changes + */ + is_dirty: boolean | null; +} + +export interface APITemplateSerializedSourceGuild extends Omit { + description: string | null; + preferred_locale: string; + icon_hash: string | null; +} diff --git a/deno/payloads/v9/user.ts b/deno/payloads/v9/user.ts new file mode 100644 index 00000000..cf601923 --- /dev/null +++ b/deno/payloads/v9/user.ts @@ -0,0 +1,157 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/user + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIGuildIntegration } from './guild.ts'; + +/** + * https://discord.com/developers/docs/resources/user#user-object + */ +export interface APIUser { + /** + * The user's id + */ + id: Snowflake; + /** + * The user's username, not unique across the platform + */ + username: string; + /** + * The user's 4-digit discord-tag + */ + discriminator: string; + /** + * The user's avatar hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + avatar: string | null; + /** + * Whether the user belongs to an OAuth2 application + */ + bot?: boolean; + /** + * Whether the user is an Official Discord System user (part of the urgent message system) + */ + system?: boolean; + /** + * Whether the user has two factor enabled on their account + */ + mfa_enabled?: boolean; + /** + * The user's chosen language option + */ + locale?: string; + /** + * Whether the email on this account has been verified + */ + verified?: boolean; + /** + * The user's email + */ + email?: string | null; + /** + * The flags on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-user-flags + */ + flags?: UserFlags; + /** + * The type of Nitro subscription on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-premium-types + */ + premium_type?: UserPremiumType; + /** + * The public flags on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-user-flags + */ + public_flags?: UserFlags; +} + +/** + * https://discord.com/developers/docs/resources/user#user-object-user-flags + */ +export enum UserFlags { + None = 0, + DiscordEmployee = 1 << 0, + PartneredServerOwner = 1 << 1, + DiscordHypeSquadEvents = 1 << 2, + BugHunterLevel1 = 1 << 3, + HypeSquadHouseBravery = 1 << 6, + HypeSquadHouseBrilliance = 1 << 7, + HypeSquadHouseBalance = 1 << 8, + EarlySupporter = 1 << 9, + TeamUser = 1 << 10, + BugHunterLevel2 = 1 << 14, + VerifiedBot = 1 << 16, + EarlyVerifiedBotDeveloper = 1 << 17, +} + +/** + * https://discord.com/developers/docs/resources/user#user-object-premium-types + */ +export enum UserPremiumType { + None, + NitroClassic, + Nitro, +} + +/** + * https://discord.com/developers/docs/resources/user#connection-object + */ +export interface APIConnection { + /** + * ID of the connection account + */ + id: string; + /** + * The username of the connection account + */ + name: string; + /** + * The service of the connection + */ + type: string; + /** + * Whether the connection is revoked + */ + revoked?: boolean; + /** + * An array of partial server integrations + * + * See https://discord.com/developers/docs/resources/guild#integration-object + */ + integrations?: Partial[]; + /** + * Whether the connection is verified + */ + verified: boolean; + /** + * Whether friend sync is enabled for this connection + */ + friend_sync: boolean; + /** + * Whether activities related to this connection will be shown in presence updates + */ + show_activity: boolean; + /** + * Visibility of this connection + * + * See https://discord.com/developers/docs/resources/user#connection-object-visibility-types + */ + visibility: ConnectionVisibility; +} + +export enum ConnectionVisibility { + /** + * Invisible to everyone except the user themselves + */ + None, + /** + * Visible to everyone + */ + Everyone, +} diff --git a/deno/payloads/v9/voice.ts b/deno/payloads/v9/voice.ts new file mode 100644 index 00000000..26895ba4 --- /dev/null +++ b/deno/payloads/v9/voice.ts @@ -0,0 +1,96 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/voice + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIGuildMember } from './guild.ts'; + +/** + * https://discord.com/developers/docs/resources/voice#voice-state-object + */ +export interface GatewayVoiceState { + /** + * The guild id this voice state is for + */ + guild_id?: Snowflake; + /** + * The channel id this user is connected to + */ + channel_id: Snowflake | null; + /** + * The user id this voice state is for + */ + user_id: Snowflake; + /** + * The guild member this voice state is for + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * The session id for this voice state + */ + session_id: string; + /** + * Whether this user is deafened by the server + */ + deaf: boolean; + /** + * Whether this user is muted by the server + */ + mute: boolean; + /** + * Whether this user is locally deafened + */ + self_deaf: boolean; + /** + * Whether this user is locally muted + */ + self_mute: boolean; + /** + * Whether this user is streaming using "Go Live" + */ + self_stream?: boolean; + /** + * Whether this user's camera is enabled + */ + self_video: boolean; + /** + * Whether this user is muted by the current user + */ + suppress: boolean; + /** + * The time at which the user requested to speak + */ + request_to_speak_timestamp: string | null; +} + +/** + * https://discord.com/developers/docs/resources/voice#voice-region-object + */ +export interface APIVoiceRegion { + /** + * Unique ID for the region + */ + id: string; + /** + * Name of the region + */ + name: string; + /** + * `true` if this is a vip-only server + */ + vip: boolean; + /** + * `true` for a single server that is closest to the current user's client + */ + optimal: boolean; + /** + * Whether this is a deprecated voice region (avoid switching to these) + */ + deprecated: boolean; + /** + * Whether this is a custom voice region (used for events/etc) + */ + custom: boolean; +} diff --git a/deno/payloads/v9/webhook.ts b/deno/payloads/v9/webhook.ts new file mode 100644 index 00000000..2eb05935 --- /dev/null +++ b/deno/payloads/v9/webhook.ts @@ -0,0 +1,75 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/webhook + */ + +import type { Snowflake } from '../../globals.ts'; +import type { APIPartialChannel, APIPartialGuild, APIUser } from './mod.ts'; + +/** + * https://discord.com/developers/docs/resources/webhook#webhook-object + */ +export interface APIWebhook { + /** + * The id of the webhook + */ + id: Snowflake; + /** + * The type of the webhook + * + * See https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types + */ + type: WebhookType; + /** + * The guild id this webhook is for + */ + guild_id?: Snowflake; + /** + * The channel id this webhook is for + */ + channel_id: Snowflake; + /** + * The user this webhook was created by (not returned when getting a webhook with its token) + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * The default name of the webhook + */ + name: string | null; + /** + * The default avatar of the webhook + */ + avatar: string | null; + /** + * The secure token of the webhook (returned for Incoming Webhooks) + */ + token?: string; + /** + * The bot/OAuth2 application that created this webhook + */ + application_id: Snowflake | null; + /** + * The guild of the channel that this webhook is following (returned for Channel Follower Webhooks) + */ + source_guild?: APIPartialGuild; + /** + * The channel that this webhook is following (returned for Channel Follower Webhooks) + */ + source_channel?: APIPartialChannel; + /** + * The url used for executing the webhook (returned by the webhooks OAuth2 flow) + */ + url?: string; +} + +export enum WebhookType { + /** + * Incoming Webhooks can post messages to channels with a generated token + */ + Incoming = 1, + /** + * Channel Follower Webhooks are internal webhooks used with Channel Following to post new messages into channels + */ + ChannelFollower, +} diff --git a/deno/rest/common.ts b/deno/rest/common.ts index 5e455af8..7a085fe7 100644 --- a/deno/rest/common.ts +++ b/deno/rest/common.ts @@ -105,6 +105,10 @@ export enum RESTJSONErrorCodes { InvalidStickerSent = 50081, + InvalidActionOnArchivedThread = 50083, + InvalidThreadNotificationSettings, + ParameterEarlierThanCreation, + TwoFactorAuthenticationIsRequired = 60003, ReactionWasBlocked = 90001, diff --git a/deno/rest/mod.ts b/deno/rest/mod.ts index 4fe447ba..428116c6 100644 --- a/deno/rest/mod.ts +++ b/deno/rest/mod.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8/mod.ts'; +export * from './v9/mod.ts'; diff --git a/deno/rest/v9/auditLog.ts b/deno/rest/v9/auditLog.ts new file mode 100644 index 00000000..af301042 --- /dev/null +++ b/deno/rest/v9/auditLog.ts @@ -0,0 +1,28 @@ +import type { Snowflake } from '../../globals.ts'; +import type { APIAuditLog, AuditLogEvent } from '../../payloads/v9/auditLog.ts'; + +/** + * https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log + */ +export interface RESTGetAPIAuditLogQuery { + /** + * Filter the log for actions made by a user + */ + user_id?: Snowflake; + /** + * The type of audit log events + */ + action_type?: AuditLogEvent; + /** + * Filter the log before a certain entry ID + */ + before?: Snowflake; + /** + * How many entries are returned (default 50, minimum 1, maximum 100) + * + * @default 50 + */ + limit?: number; +} + +export type RESTGetAPIAuditLogResult = APIAuditLog; diff --git a/deno/rest/v9/channel.ts b/deno/rest/v9/channel.ts new file mode 100644 index 00000000..838ba5df --- /dev/null +++ b/deno/rest/v9/channel.ts @@ -0,0 +1,553 @@ +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { + APIAllowedMentions, + APIChannel, + APIEmbed, + APIExtendedInvite, + APIFollowedChannel, + APIMessage, + APIMessageReference, + APIOverwrite, + APIThreadList, + APIThreadMember, + APIUser, + ChannelType, + InviteTargetType, + MessageFlags, + OverwriteType, + ThreadAutoArchiveDuration, + VideoQualityMode, +} from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel + */ +export type RESTGetAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export interface RESTPatchAPIChannelJSONBody { + /** + * 2-100 character channel name + * + * Channel types: all + */ + name?: string; + + /** + * The type of channel; only conversion between `text` and `news` + * is supported and only in guilds with the "NEWS" feature + * + * Channel types: text, news + */ + type?: ChannelType.GuildNews | ChannelType.GuildText; + /** + * The position of the channel in the left-hand listing + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + position?: number | null; + /** + * 0-1024 character channel topic + * + * Channel types: text, news + */ + topic?: string | null; + /** + * Whether the channel is nsfw + * + * Channel types: text, news, store + */ + nsfw?: boolean | null; + /** + * 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_CHANNELS`, + * are unaffected + * + * Channel types: text, newsThread, publicThread, privateThread + */ + rate_limit_per_user?: number | null; + /** + * The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers) + * + * Channel types: voice + */ + bitrate?: number | null; + /** + * The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit + * + * Channel types: voice + */ + user_limit?: number | null; + /** + * Channel or category-specific permissions + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + permission_overwrites?: APIOverwrite[] | null; + /** + * ID of the new parent category for a channel + * + * Channel types: text, news, store, voice + */ + parent_id?: Snowflake | null; + /** + * Voice region id for the voice or stage channel, automatic when set to `null` + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + rtc_region?: string | null; + /** + * The camera video quality mode of the voice channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes + */ + video_quality_mode?: VideoQualityMode | null; + /** + * Whether the thread should be archived + * + * Channel types: newsThread, publicThread, privateThread + */ + archived?: boolean; + /** + * The amount of time in minutes to wait before automatically archiving the thread + * + * Channel types: newsThread, publicThread, privateThread + */ + auto_archive_duration?: ThreadAutoArchiveDuration; + /** + * Whether the thread should be locked + * + * Channel types: newsThread, publicThread, privateThread + */ + locked?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export type RESTPatchAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#deleteclose-channel + */ +export type RESTDeleteAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export interface RESTGetAPIChannelMessagesQuery { + /** + * Get messages around this message ID + */ + around?: Snowflake; + /** + * Get messages before this message ID + */ + before?: Snowflake; + /** + * Get messages after this message ID + */ + after?: Snowflake; + /** + * Max number of messages to return (1-100) + * + * @default 50 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export type RESTGetAPIChannelMessagesResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-message + */ +export type RESTGetAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ +export type APIMessageReferenceSend = Partial & + Required> & { + /** + * Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message + * + * @default true + */ + fail_if_not_exists?: boolean; + }; + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export interface RESTPostAPIChannelMessageJSONBody { + /** + * The message contents (up to 2000 characters) + */ + content?: string; + /** + * A nonce that can be used for optimistic message sending + */ + nonce?: number | string; + /** + * `true` if this is a TTS message + */ + tts?: boolean; + /** + * Embedded `rich` content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embed?: APIEmbed; + /** + * Allowed mentions for a message + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object + */ + allowed_mentions?: APIAllowedMentions; + /** + * Include to make your message a reply + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ + message_reference?: APIMessageReferenceSend; +} + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIChannelMessageJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#crosspost-message + */ +export type RESTPostAPIChannelMessageCrosspostResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#create-reaction + */ +export type RESTPutAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-own-reaction + */ +export type RESTDeleteAPIChannelMessageOwnReaction = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-user-reaction + */ +export type RESTDeleteAPIChannelMessageUserReactionResult = never; + +/* + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export interface RESTGetAPIChannelMessageReactionUsersQuery { + /** + * Get users after this user ID + */ + after?: Snowflake; + /** + * Max number of users to return (1-100) + * + * @default 25 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export type RESTGetAPIChannelMessageReactionUsersResult = APIUser[]; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions + */ +export type RESTDeleteAPIChannelAllMessageReactionsResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji + */ +export type RESTDeleteAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export interface RESTPatchAPIChannelMessageJSONBody { + /** + * The new message contents (up to 2000 characters) + */ + content?: string | null; + /** + * Embedded `rich` content + */ + embed?: APIEmbed | null; + /** + * Edit the flags of a message (only `SUPPRESS_EMBEDS` can currently be set/unset) + * + * When specifying flags, ensure to include all previously set flags/bits + * in addition to ones that you are modifying + */ + flags?: MessageFlags | null; + /** + * Allowed mentions for the message + */ + allowed_mentions?: APIAllowedMentions | null; +} + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export type RESTPatchAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#delete-message + */ +export type RESTDeleteAPIChannelMessageResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export interface RESTPostAPIChannelMessagesBulkDeleteJSONBody { + /** + * An array of message ids to delete (2-100) + */ + messages: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export type RESTPostAPIChannelMessagesBulkDeleteResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export interface RESTPutAPIChannelPermissionJSONBody { + /** + * The bitwise value of all allowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + allow: Permissions; + /** + * The bitwise value of all disallowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + deny: Permissions; + /** + * `0` for a role or `1` for a member + */ + type: OverwriteType; +} + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export type RESTPutAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-invites + */ +export type RESTGetAPIChannelInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export interface RESTPostAPIChannelInviteJSONBody { + /** + * Duration of invite in seconds before expiry, or 0 for never + * + * @default 86400 (24 hours) + */ + max_age?: number; + /** + * Max number of uses or 0 for unlimited + * + * @default 0 + */ + max_uses?: number; + /** + * Whether this invite only grants temporary membership + * + * @default false + */ + temporary?: boolean; + /** + * If true, don't try to reuse a similar invite + * (useful for creating many unique one time use invites) + * + * @default false + */ + unique?: boolean; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ + target_type?: InviteTargetType; + /** + * The id of the user whose stream to display for this invite + * - Required if `target_type` is 1 + * - The user must be streaming in the channel + */ + target_user_id?: Snowflake; + /** + * The id of the embedded application to open for this invite + * - Required if `target_type` is 2 + * - The application must have the `EMBEDDED` flag + */ + target_application_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export type RESTPostAPIChannelInviteResult = APIExtendedInvite; + +/** + * https://discord.com/developers/docs/resources/channel#delete-channel-permission + */ +export type RESTDeleteAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export interface RESTPostAPIChannelFollowersJSONBody { + /** + * ID of target channel + */ + webhook_channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export type RESTPostAPIChannelFollowersResult = APIFollowedChannel; + +/** + * https://discord.com/developers/docs/resources/channel#trigger-typing-indicator + */ +export type RESTPostAPIChannelTypingResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-pinned-messages + */ +export type RESTGetAPIChannelPinsResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#add-pinned-channel-message + */ +export type RESTPutAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-pinned-channel-message + */ +export type RESTDeleteAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export interface RESTPutAPIChannelRecipientJSONBody { + /** + * Access token of a user that has granted your app the `gdm.join` scope + */ + access_token: string; + /** + * Nickname of the user being added + */ + nick?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export type RESTPutAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient + */ +export type RESTDeleteAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-with-message + */ +export interface RESTPostAPIChannelThreadsJSONBody { + /** + * 2-100 character thread name + */ + name: string; + /** + * The amount of time in minutes to wait before automatically archiving the thread + */ + auto_archive_duration: ThreadAutoArchiveDuration; +} + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-with-message + */ +export type RESTPostAPIChannelThreadsResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#join-thread + */ +export type RESTPutAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#leave-thread + */ +export type RESTDeleteAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#list-thread-members + */ +export type RESTGetAPIChannelThreadMembersResult = APIThreadMember[]; + +/* + * https://discord.com/developers/docs/resources/channel#list-public-archived-threads + */ +export interface RESTGetAPIChannelThreadsArchivedQuery { + /** + * Get threads before this id or ISO8601 timestamp + */ + before?: Snowflake | string; + /** + * Max number of thread to return + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#list-active-threads + */ +export type RESTGetAPIChannelThreadsResult = APIThreadList; + +/** + * https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads + */ +export type RESTGetAPIChannelUsersThreadsArchivedResult = APIThreadList; diff --git a/deno/rest/v9/emoji.ts b/deno/rest/v9/emoji.ts new file mode 100644 index 00000000..37c95bc6 --- /dev/null +++ b/deno/rest/v9/emoji.ts @@ -0,0 +1,61 @@ +import type { Snowflake } from '../../globals.ts'; +import type { APIEmoji } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/emoji#list-guild-emojis + */ +export type RESTGetAPIGuildEmojisResult = APIEmoji[]; + +/** + * https://discord.com/developers/docs/resources/emoji#get-guild-emoji + */ +export type RESTGetAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji-json-params + */ +export interface RESTPostAPIGuildEmojiJSONBody { + /** + * Name of the emoji + */ + name: string; + /** + * The 128x128 emoji image + * + * https://discord.com/developers/docs/reference#image-data + */ + image: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji + */ +export type RESTPostAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export interface RESTPatchAPIGuildEmojiJSONBody { + /** + * Name of the emoji + */ + name?: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[] | null; +} + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export type RESTPatchAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#delete-guild-emoji + */ +export type RESTDeleteAPIGuildEmojiResult = never; diff --git a/deno/rest/v9/gateway.ts b/deno/rest/v9/gateway.ts new file mode 100644 index 00000000..fa2d5b2a --- /dev/null +++ b/deno/rest/v9/gateway.ts @@ -0,0 +1,11 @@ +import type { APIGatewayBotInfo, APIGatewayInfo } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway + */ +export type RESTGetAPIGatewayResult = APIGatewayInfo; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway-bot + */ +export type RESTGetAPIGatewayBotResult = APIGatewayBotInfo; diff --git a/deno/rest/v9/guild.ts b/deno/rest/v9/guild.ts new file mode 100644 index 00000000..b0fc916f --- /dev/null +++ b/deno/rest/v9/guild.ts @@ -0,0 +1,780 @@ +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { + APIBan, + APIChannel, + APIExtendedInvite, + APIGuild, + APIGuildIntegration, + APIGuildMember, + APIGuildMembershipScreening, + APIGuildPreview, + APIGuildWelcomeScreen, + APIGuildWidget, + APIGuildWidgetSettings, + APIRole, + APIVoiceRegion, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildFeature, + GuildSystemChannelFlags, + GuildVerificationLevel, + GuildWidgetStyle, +} from '../../payloads/v9/mod.ts'; +import type { RESTPutAPIChannelPermissionJSONBody } from './channel.ts'; + +export interface APIGuildCreateOverwrite extends RESTPutAPIChannelPermissionJSONBody { + id: number | string; +} + +export type APIGuildCreatePartialChannel = Partial< + Pick +> & { + name: string; + id?: number | string; + parent_id?: number | string | null; + permission_overwrites?: APIGuildCreateOverwrite[]; +}; + +export interface APIGuildCreateRole extends RESTPostAPIGuildRoleJSONBody { + id: number | string; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export interface RESTPostAPIGuildsJSONBody { + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter; + /** + * New guild roles + * + * **When using this parameter, the first member of the array is used to change properties of the guild's @everyone role. + * If you are trying to bootstrap a guild with additional roles, keep this in mind.** + * + * *When using this parameter, the required `id` field within each role object is an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions + * in a channel when also passing in channels with the channels array.* + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles?: APIGuildCreateRole[]; + /** + * New guild's channels + * + * **When using the channels parameter, the `position` field is ignored, and none of the default channels are created.** + * + * *When using the channels parameter, the `id` field within each channel object may be set to an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to create `GUILD_CATEGORY` channels + * by setting the `parent_id` field on any children to the category's id field. + * Category channels must be listed before any children.* + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channels?: APIGuildCreatePartialChannel[]; + /** + * ID for afk channel + */ + afk_channel_id?: number | Snowflake | null; + /** + * AFK timeout in seconds + */ + afk_timeout?: number; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id?: number | Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export type RESTPostAPIGuildsResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export interface RESTGetAPIGuildQuery { + /** + * When `true`, will return approximate member and presence counts for the guild + * + * @default false + */ + with_counts?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export type RESTGetAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-preview + */ +export type RESTGetAPIGuildPreviewResult = APIGuildPreview; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export interface RESTPatchAPIGuildJSONBody { + /** + * New name for the guild (2-100 characters) + */ + name?: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string | null; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel | null; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications | null; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter | null; + /** + * ID for afk channel + */ + afk_channel_id?: Snowflake | null; + /** + * AFK timeout in seconds + */ + afk_timeout?: number; + /** + * base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the guild has `ANIMATED_ICON` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string | null; + /** + * User id to transfer guild ownership to (must be owner) + */ + owner_id?: Snowflake; + /** + * base64 16:9 png/jpeg image for the guild splash (when the guild has `INVITE_SPLASH` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + splash?: string | null; + /** + * base64 png/jpeg image for the guild discovery splash (when the guild has `DISCOVERABLE` feature) + */ + discovery_splash?: string | null; + /** + * base64 16:9 png/jpeg image for the guild banner (when the guild has `BANNER` feature) + */ + banner?: string | null; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id?: Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; + /** + * The id of the channel where Community guilds display rules and/or guidelines + */ + rules_channel_id?: Snowflake | null; + /** + * The id of the channel where admins and moderators of Community guilds receive notices from Discord + */ + public_updates_channel_id?: Snowflake | null; + /** + * The preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" + * + * @default "en-US" (if the value is set to `null`) + */ + preferred_locale?: string | null; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features?: GuildFeature[]; + /** + * The description for the guild, if the guild is discoverable + */ + description?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export type RESTPatchAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild + */ +export type RESTDeleteAPIGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-channels + */ +export type RESTGetAPIGuildChannelsResult = APIChannel[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelJSONBody = Omit; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsJSONBody = Array<{ + /** + * Channel id + */ + id: Snowflake; + /** + * Sorting position of the channel + */ + position: number; + /** + * Sync channel overwrites with the new parent, when moving to a new `parent_id` + */ + lock_permissions?: boolean; + /** + * The new parent id of this channel + */ + parent_id?: Snowflake | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-member + */ +export type RESTGetAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export interface RESTGetAPIGuildMembersQuery { + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; + /** + * The highest user id in the previous page + * + * @default 0 + */ + after?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export type RESTGetAPIGuildMembersResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#search-guild-members + */ +export interface RESTGetAPIGuildMembersSearchQuery { + /** + * Query string to match username(s) and nickname(s) against + */ + query: string; + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; +} + +export type RESTGetAPIGuildMembersSearchResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export interface RESTPutAPIGuildMemberJSONBody { + /** + * An oauth2 access token granted with the `guilds.join` to the bot's application for the user you want to add to the guild + */ + access_token: string; + /** + * Value to set users nickname to + * + * Requires `MANAGE_NICKNAMES` permission + */ + nick?: string; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[]; + /** + * Whether the user is muted in voice channels + * + * Requires `MUTE_MEMBERS` permission + */ + mute?: boolean; + /** + * Whether the user is deafened in voice channels + * + * Requires `DEAFEN_MEMBERS` permission + */ + deaf?: boolean; +} + +export type RESTPutAPIGuildMemberResult = APIGuildMember | undefined; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-member + */ +export interface RESTPatchAPIGuildMemberJSONBody { + /** + * Value to set users nickname to + * + * Requires `MANAGE_NICKNAMES` permission + */ + nick?: string | null; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[] | null; + /** + * Whether the user is muted in voice channels. Will throw a 400 if the user is not in a voice channel + * + * Requires `MUTE_MEMBERS` permission + */ + mute?: boolean | null; + /** + * Whether the user is deafened in voice channels. Will throw a 400 if the user is not in a voice channel + * + * Requires `DEAFEN_MEMBERS` permission + */ + deaf?: boolean | null; + /** + * ID of channel to move user to (if they are connected to voice) + * + * Requires `MOVE_MEMBERS` permission + */ + channel_id?: Snowflake | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export type RESTPatchAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + */ +export interface RESTPatchAPICurrentGuildMemberNicknameJSONBody { + /** + * Value to set users nickname to + * + * Requires `CHANGE_NICKNAME` permission + */ + nick?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + */ +export type RESTPatchAPICurrentGuildMemberNicknameResult = Required; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member-role + */ +export type RESTPutAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member-role + */ +export type RESTDeleteAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member + */ +export type RESTDeleteAPIGuildMemberResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-bans + */ +export type RESTGetAPIGuildBansResult = APIBan[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-ban + */ +export type RESTGetAPIGuildBanResult = APIBan; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export interface RESTPutAPIGuildBanJSONBody { + /** + * Number of days to delete messages for (0-7) + */ + delete_message_days?: number; + /** + * Reason for the ban + */ + reason?: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export type RESTPutAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-ban + */ +export type RESTDeleteAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-roles + */ +export type RESTGetAPIGuildRolesResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export interface RESTPostAPIGuildRoleJSONBody { + /** + * Name of the role + * + * @default "new role" + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + * + * @default "​default role permissions in guild" + */ + permissions?: Permissions | null; + /** + * RGB color value + * + * @default 0 + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + * + * @default false + */ + hoist?: boolean | null; + /** + * Whether the role should be mentionable + * + * @default false + */ + mentionable?: boolean | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export type RESTPostAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsJSONBody = Array<{ + /** + * Role id + */ + id: Snowflake; + /** + * Sorting position of the role + */ + position?: number; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export interface RESTPatchAPIGuildRoleJSONBody { + /** + * Name of the role + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + */ + permissions?: Permissions | null; + /** + * RGB color value + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + */ + hoist?: boolean | null; + /** + * Whether the role should be mentionable + */ + mentionable?: boolean | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export type RESTPatchAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-role + */ +export type RESTDeleteAPIGuildRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountQuery { + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Role(s) to include + * + * While this is typed as a string, it represents an array of + * role IDs delimited by commas + * + * See https://discord.com/developers/docs/resources/guild#get-guild-prune-count-query-string-params + */ + include_roles?: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountResult { + pruned: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export interface RESTPostAPIGuildPruneJSONBody { + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Whether `pruned is returned, discouraged for large guilds + * + * @default true + */ + compute_prune_count?: boolean; + /** + * Role(s) to include + */ + include_roles?: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export interface RESTPostAPIGuildPruneResult { + pruned: number | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-voice-regions + */ +export type RESTGetAPIGuildVoiceRegionsResult = APIVoiceRegion[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-invites + */ +export type RESTGetAPIGuildInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-integrations + */ +export type RESTGetAPIGuildIntegrationsResult = APIGuildIntegration[]; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-integration + */ +export type RESTDeleteAPIGuildIntegrationResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-settings + */ +export type RESTGetAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsJSONBody = Partial; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget + */ +export type RESTGetAPIGuildWidgetJSONResult = APIGuildWidget; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-vanity-url + */ +export interface RESTGetAPIGuildVanityUrlResult { + code: string | null; + uses: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-image + */ +export interface RESTGetAPIGuildWidgetImageQuery { + /** + * Style of the widget image returned + * + * @default "shield" + */ + style?: GuildWidgetStyle; +} + +/** + * Note: while the return type is `ArrayBuffer`, the expected result is + * a buffer of sorts (depends if in browser or on node.js/deno). + */ +export type RESTGetAPIGuildWidgetImageResult = ArrayBuffer; + +export type RESTGetAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +export interface RESTPatchAPIGuildMemberVerificationJSONBody { + /** + * Whether Membership Screening is enabled + */ + enabled?: boolean; + /** + * Array of field objects serialized in a string + */ + form_fields?: string; + /** + * The server description to show in the screening form + */ + description?: string | null; +} + +export type RESTPatchAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +export interface RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody { + /** + * The id of the channel the user is currently in + */ + channel_id: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; + /** + * Sets the user's request to speak + */ + request_to_speak_timestamp?: string | null; +} + +export interface RESTPatchAPIGuildVoiceStateUserJSONBody { + /** + * The id of the channel the user is currently in + */ + channel_id: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen + */ +export type RESTGetAPIGuildWelcomeScreenResult = APIGuildWelcomeScreen; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen + */ +export interface RESTPatchAPIGuildWelcomeScreenJSONBody extends Nullable> { + /** + * Whether the welcome screen is enabled + */ + enabled?: boolean | null; +} + +type Nullable = { + [P in keyof T]: T[P] | null; +}; diff --git a/deno/rest/v9/interactions.ts b/deno/rest/v9/interactions.ts new file mode 100644 index 00000000..1989879b --- /dev/null +++ b/deno/rest/v9/interactions.ts @@ -0,0 +1,147 @@ +import type { + APIApplicationCommand, + APIApplicationCommandPermission, + APIGuildApplicationCommandPermissions, + APIInteractionResponse, +} from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-global-application-commands + */ +export type RESTGetAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-global-application-command + */ +export type RESTGetAPIApplicationCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsJSONBody = Omit; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandJSONBody = Partial; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-commands + */ +export type RESTGetAPIApplicationGuildCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-command + */ +export type RESTGetAPIApplicationGuildCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandJSONBody = Partial; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackJSONBody = APIInteractionResponse; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIInteractionCallbackJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-command-permissions + */ +export type RESTGetAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-application-command-permissions + */ +export type RESTGetAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-application-command-permissions + */ +export interface RESTPutAPIApplicationCommandPermissionsJSONBody { + permissions: APIApplicationCommandPermission[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-application-command-permissions + */ +export type RESTPutAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsJSONBody = Pick< + APIGuildApplicationCommandPermissions, + 'id' | 'permissions' +>[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; diff --git a/deno/rest/v9/invite.ts b/deno/rest/v9/invite.ts new file mode 100644 index 00000000..4e8c5f83 --- /dev/null +++ b/deno/rest/v9/invite.ts @@ -0,0 +1,22 @@ +import type { APIInvite } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/invite#get-invite + */ +export interface RESTGetAPIInviteQuery { + /** + * Whether the invite should contain approximate member counts + */ + with_counts?: boolean; + /** + * Whether the invite should contain the expiration date + */ + with_expiration?: boolean; +} + +export type RESTGetAPIInviteResult = APIInvite; + +/** + * https://discord.com/developers/docs/resources/invite#delete-invite + */ +export type RESTDeleteAPIInviteResult = APIInvite; diff --git a/deno/rest/v9/mod.ts b/deno/rest/v9/mod.ts new file mode 100644 index 00000000..3297f359 --- /dev/null +++ b/deno/rest/v9/mod.ts @@ -0,0 +1,743 @@ +import type { Snowflake } from '../../globals.ts'; + +export * from '../common.ts'; + +export * from './auditLog.ts'; +export * from './channel.ts'; +export * from './emoji.ts'; +export * from './gateway.ts'; +export * from './guild.ts'; +export * from './interactions.ts'; +export * from './invite.ts'; +export * from './oauth2.ts'; +export * from './template.ts'; +export * from './user.ts'; +export * from './voice.ts'; +export * from './webhook.ts'; + +export const APIVersion = '9'; + +export const Routes = { + /** + * Route for: + * - GET `/guilds/{guild.id}/audit-logs` + */ + guildAuditLog(guildID: Snowflake) { + return `/guilds/${guildID}/audit-logs` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}` + * - PATCH `/channels/{channel.id}` + * - DELETE `/channels/{channel.id}` + */ + channel(channelID: Snowflake) { + return `/channels/${channelID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages` + * - POST `/channels/{channel.id}/messages` + */ + channelMessages(channelID: Snowflake) { + return `/channels/${channelID}/messages` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}` + * - PATCH `/channels/{channel.id}/messages/{message.id}` + * - DELETE `/channels/{channel.id}/messages/{message.id}` + */ + channelMessage(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/{message.id}/crosspost` + */ + channelMessageCrosspost(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/crosspost` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageOwnReaction(channelID: Snowflake, messageID: Snowflake, emoji: string) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}/@me` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{user.id}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageUserReaction(channelID: Snowflake, messageID: Snowflake, emoji: string, userID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}/${userID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageReaction(channelID: Snowflake, messageID: Snowflake, emoji: string) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions` + */ + channelMessageAllReactions(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/reactions` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/bulk-delete` + */ + channelBulkDelete(channelID: Snowflake) { + return `/channels/${channelID}/messages/bulk-delete` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/permissions/{overwrite.id}` + * - DELETE `/channels/{channel.id}/permissions/{overwrite.id}` + */ + channelPermission(channelID: Snowflake, overwriteID: Snowflake) { + return `/channels/${channelID}/permissions/${overwriteID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/invites` + * - POST `/channels/{channel.id}/invites` + */ + channelInvites(channelID: Snowflake) { + return `/channels/${channelID}/invites` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/followers` + */ + channelFollowers(channelID: Snowflake) { + return `/channels/${channelID}/followers` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/typing` + */ + channelTyping(channelID: Snowflake) { + return `/channels/${channelID}/typing` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/pins` + */ + channelPins(channelID: Snowflake) { + return `/channels/${channelID}/pins` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/pins/{message.id}` + * - DELETE `/channels/{channel.id}/pins/{message.id}` + */ + channelPin(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/pins/${messageID}` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/recipients/{user.id}` + * - DELETE `/channels/{channel.id}/recipients/{user.id}` + */ + channelRecipient(channelID: Snowflake, userID: Snowflake) { + return `/channels/${channelID}/recipients/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis` + * - POST `/guilds/{guild.id}/emojis` + */ + guildEmojis(guildID: Snowflake) { + return `/guilds/${guildID}/emojis` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis/{emoji.id}` + * - PATCH `/guilds/{guild.id}/emojis/{emoji.id}` + * - DELETE `/guilds/{guild.id}/emojis/{emoji.id}` + */ + guildEmoji(guildID: Snowflake, emojiID: Snowflake) { + return `/guilds/${guildID}/emojis/${emojiID}` as const; + }, + + /** + * Route for: + * - POST `/guilds` + */ + guilds() { + return '/guilds' as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}` + * - PATCH `/guilds/{guild.id}` + * - DELETE `/guilds/{guild.id}` + */ + guild(guildID: Snowflake) { + return `/guilds/${guildID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/preview` + */ + guildPreview(guildID: Snowflake) { + return `/guilds/${guildID}/preview` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/channels` + * - POST `/guilds/{guild.id}/channels` + * - PATCH `/guilds/{guild.id}/channels` + */ + guildChannels(guildID: Snowflake) { + return `/guilds/${guildID}/channels` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/{user.id}` + * - PUT `/guilds/{guild.id}/members/{user.id}` + * - PATCH `/guilds/{guild.id}/members/{user.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}` + */ + guildMember(guildID: Snowflake, userID: Snowflake) { + return `/guilds/${guildID}/members/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members` + */ + guildMembers(guildID: Snowflake) { + return `/guilds/${guildID}/members` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/search` + */ + guildMembersSearch(guildID: Snowflake) { + return `/guilds/${guildID}/members/search` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/members/@me/nick` + */ + guildCurrentMemberNickname(guildID: Snowflake) { + return `/guilds/${guildID}/members/@me/nick` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + */ + guildMemberRole(guildID: Snowflake, memberID: Snowflake, roleID: Snowflake) { + return `/guilds/${guildID}/members/${memberID}/roles/${roleID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans` + */ + guildBans(guildID: Snowflake) { + return `/guilds/${guildID}/bans` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans/{user.id}` + * - PUT `/guilds/{guild.id}/bans/{user.id}` + * - DELETE `/guilds/{guild.id}/bans/{user.id}` + */ + guildBan(guildID: Snowflake, userID: Snowflake) { + return `/guilds/${guildID}/bans/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/roles` + * - POST `/guilds/{guild.id}/roles` + * - PATCH `/guilds/{guild.id}/roles` + */ + guildRoles(guildID: Snowflake) { + return `/guilds/${guildID}/roles` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/roles/{role.id}` + */ + guildRole(guildID: Snowflake, roleID: Snowflake) { + return `/guilds/${guildID}/roles/${roleID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/prune` + * - POST `/guilds/{guild.id}/prune` + */ + guildPrune(guildID: Snowflake) { + return `/guilds/${guildID}/prune` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/regions` + */ + guildVoiceRegions(guildID: Snowflake) { + return `/guilds/${guildID}/regions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/invites` + */ + guildInvites(guildID: Snowflake) { + return `/guilds/${guildID}/invites` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/integrations` + */ + guildIntegrations(guildID: Snowflake) { + return `/guilds/${guildID}/integrations` as const; + }, + + /** + * Route for: + * - DELETE `/guilds/{guild.id}/integrations/{integration.id}` + */ + guildIntegration(guildID: Snowflake, integrationID: Snowflake) { + return `/guilds/${guildID}/integrations/${integrationID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget` + * - PATCH `/guilds/{guild.id}/widget` + */ + guildWidgetSettings(guildID: Snowflake) { + return `/guilds/${guildID}/widget` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.json` + */ + guildWidgetJSON(guildID: Snowflake) { + return `/guilds/${guildID}/widget.json` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/vanity-url` + */ + guildVanityUrl(guildID: Snowflake) { + return `/guilds/${guildID}/vanity-url` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.png` + */ + guildWidgetImage(guildID: Snowflake) { + return `/guilds/${guildID}/widget.png` as const; + }, + + /** + * Route for: + * - GET `/invites/{invite.code}` + * - DELETE `/invites/{invite.code}` + */ + invite(code: string) { + return `/invites/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/templates/{template.code}` + * - POST `/guilds/templates/{template.code}` + */ + template(code: string) { + return `/guilds/templates/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/templates` + * - POST `/guilds/{guild.id}/templates` + */ + guildTemplates(guildID: Snowflake) { + return `/guilds/${guildID}/templates` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/templates/{template.code}` + * - PATCH `/guilds/{guild.id}/templates/{template.code}` + * - DELETE `/guilds/{guild.id}/templates/{template.code}` + */ + guildTemplate(guildID: Snowflake, code: string) { + return `/guilds/${guildID}/templates/${code}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/threads` + * - POST `/channels/{channel.id}/messages/{message.id}/threads` + */ + threads(parentID: Snowflake, messageID?: Snowflake) { + const parts = ['', 'channels', parentID]; + + if (messageID) parts.push('messages', messageID); + + parts.push('threads'); + + return parts.join('/') as `/channels/${Snowflake}/threads` | `/channels/${Snowflake}/messages/${Snowflake}/threads`; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/threads/active` + * - GET `/channels/{channel.id}/threads/archived/public` + * - GET `/channels/{channel.id}/threads/archived/private` + */ + channelThreads(channelID: Snowflake, archived?: 'public' | 'private') { + const parts = ['', 'channels', channelID, 'threads']; + + if (archived) parts.push('archived', archived); + else parts.push('active'); + + return parts.join('/') as + | `/channels/${Snowflake}/threads/active` + | `/channels/${Snowflake}/threads/archived/${'public' | 'private'}`; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/users/@me/threads/archived/prviate` + */ + channelJoinedArhivedThreads(channelID: Snowflake) { + return `/channels/${channelID}/users/@me/threads/archived/private` as const; + }, + + /** + * Route for: + * - GET `/channels/{thread.id}/thread-members` + * - PUT `/channels/{thread.id}/thread-members/@me` + * - PUT `/channels/{thread.id}/thread-members/{user.id}` + * - DELETE `/channels/{thread.id}/thread-members/@me` + * - DELETE `/channels/{thread.id}/thread-members/{user.id}` + */ + threadMembers(threadID: Snowflake, userID?: Snowflake | '@me') { + const parts = ['', 'channels', threadID, 'thread-members']; + + if (userID) parts.push(userID); + + return parts.join('/') as + | `/channels/${Snowflake}/thread-members` + | `/channels/${Snowflake}/thread-members/${Snowflake | '@me'}`; + }, + + /** + * Route for: + * - GET `/users/@me` + * - GET `/users/{user.id}` + * - PATCH `/users/@me` + * + * @param [userID='@me'] The user ID, defaulted to `@me` + */ + user(userID: Snowflake | '@me' = '@me') { + return `/users/${userID}` as const; + }, + + /** + * Route for: + * - GET `/users/@me/guilds` + */ + userGuilds() { + return `/users/@me/guilds` as const; + }, + + /** + * Route for: + * - DELETE `/users/@me/guilds/{guild.id}` + */ + userGuild(guildID: Snowflake) { + return `/users/@me/guilds/${guildID}` as const; + }, + + /** + * Route for: + * - POST `/users/@me/channels` + */ + userChannels() { + return `/users/@me/channels` as const; + }, + + /** + * Route for: + * - GET `/users/@me/connections` + */ + userConnections() { + return `/users/@me/connections` as const; + }, + + /** + * Route for: + * - GET `/voice/regions` + */ + voiceRegions() { + return `/voice/regions` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/webhooks` + * - POST `/channels/{channel.id}/webhooks` + */ + channelWebhooks(channelID: Snowflake) { + return `/channels/${channelID}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/webhooks` + */ + guildWebhooks(guildID: Snowflake) { + return `/guilds/${guildID}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}` + * - GET `/webhooks/{webhook.id}/{webhook.token}` + * - PATCH `/webhooks/{webhook.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}` + * - DELETE `/webhooks/{webhook.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}` + * - POST `/webhooks/{webhook.id}/{webhook.token}` + * + * - POST `/webhooks/{application.id}/{interaction.token}` + */ + webhook(webhookID: Snowflake, webhookToken?: string) { + const parts = ['', 'webhooks', webhookID]; + + if (webhookToken) parts.push(webhookToken); + + return parts.join('/') as `/webhooks/${Snowflake}` | `/webhooks/${Snowflake}/${string}`; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/@original` + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * - DELETE `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * + * @param [messageID='@original'] The message ID to change, defaulted to `@original` + */ + webhookMessage(webhookID: Snowflake, webhookToken: string, messageID: Snowflake | '@original' = '@original') { + return `/webhooks/${webhookID}/${webhookToken}/messages/${messageID}` as const; + }, + + /** + * Route for: + * - POST `/webhooks/{webhook.id}/{webhook.token}/github` + * - POST `/webhooks/{webhook.id}/{webhook.token}/slack` + */ + webhookPlatform(webhookID: Snowflake, webhookToken: string, platform: 'github' | 'slack') { + return `/webhooks/${webhookID}/${webhookToken}/${platform}` as const; + }, + + /** + * Route for: + * - GET `/gateway` + */ + gateway() { + return `/gateway` as const; + }, + + /** + * Route for: + * - GET `/gateway/bot` + */ + gatewayBot() { + return `/gateway/bot` as const; + }, + + /** + * Route for: + * - GET `/oauth2/applications/@me` + */ + oauth2CurrentApplication() { + return `/oauth2/applications/@me` as const; + }, + + /** + * Route for: + * - GET `/oauth2/@me` + */ + oauth2CurrentAuthorization() { + return `/oauth2/@me` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands` + * - PUT `/applications/{application.id}/commands` + * - POST `/applications/{application.id}/commands` + */ + applicationCommands(applicationID: Snowflake) { + return `/applications/${applicationID}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/commands/{command.id}` + */ + applicationCommand(applicationID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/commands/${commandID}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands` + * - POST `/applications/{application.id}/guilds/{guild.id}/commands` + */ + applicationGuildCommands(applicationID: Snowflake, guildID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + */ + applicationGuildCommand(applicationID: Snowflake, guildID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}` as const; + }, + + /** + * Route for: + * - POST `/interactions/{interaction.id}/{interaction.token}/callback` + */ + interactionCallback(interactionID: Snowflake, interactionToken: string) { + return `/interactions/${interactionID}/${interactionToken}/callback` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/member-verification` + * - PATCH `/guilds/{guild.id}/member-verification` + */ + guildMemberVerification(guildID: Snowflake) { + return `/guilds/${guildID}/member-verification` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/voice-states/@me` + * - PATCH `/guilds/{guild.id}/voice-states/{user.id}` + */ + guildVoiceState(guildID: Snowflake, userID: Snowflake | '@me' = '@me') { + return `/guilds/${guildID}/voice-states/${userID}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + */ + guildApplicationCommandsPermissions(applicationID: Snowflake, guildID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/permissions` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + */ + applicationCommandPermissions(applicationID: Snowflake, guildID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}/permissions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/welcome-screen` + * - PATCH `/guilds/{guild.id}/welcome-screen` + */ + guildWelcomeScreen(guildID: Snowflake) { + return `/guilds/${guildID}/welcome-screen` as const; + }, +}; + +export const RouteBases = { + api: 'https://discord.com/api', + cdn: 'https://cdn.discordapp.com', + invite: 'https://discord.gg', + template: 'https://discord.new', + gift: 'https://discord.gift', +} as const; + +// Freeze bases object +Object.freeze(RouteBases); + +export const OAuth2Routes = { + authorizationURL: `https://discord.com/api/v${APIVersion}/oauth2/authorize`, + tokenURL: `https://discord.com/api/v${APIVersion}/oauth2/token`, + /** + * See https://tools.ietf.org/html/rfc7009 + */ + tokenRevocationURL: `https://discord.com/api/v${APIVersion}/oauth2/token/revoke`, +} as const; + +// Freeze OAuth2 route object +Object.freeze(OAuth2Routes); diff --git a/deno/rest/v9/oauth2.ts b/deno/rest/v9/oauth2.ts new file mode 100644 index 00000000..e0168d3c --- /dev/null +++ b/deno/rest/v9/oauth2.ts @@ -0,0 +1,199 @@ +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { APIApplication, APIGuild, APIUser, APIWebhook, OAuth2Scopes } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-application-information + */ +export type RESTGetAPIOAuth2CurrentApplicationResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-authorization-information + */ +export interface RESTGetAPIOAuth2CurrentAuthorizationResult { + /** + * the current application + */ + application: Partial; + /** + * the scopes the user has authorized the application for + */ + scopes: OAuth2Scopes[]; + /** + * when the access token expires + */ + expires: string; + /** + * the user who has authorized, if the user has authorized with the `identify` scope + */ + user?: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant + */ +export interface RESTOAuth2AuthorizationQuery { + response_type: 'code'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTOAuth2AuthorizationQueryResult { + code: string; + state?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTPostOAuth2AccessTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'authorization_code'; + code: string; + redirect_uri?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response + */ +export interface RESTPostOAuth2AccessTokenResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-refresh-token-exchange-example + */ +export interface RESTPostOAuth2RefreshTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'refresh_token'; + refresh_token: string; +} + +export type RESTPostOAuth2RefreshTokenResult = RESTPostOAuth2AccessTokenResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant + */ +export interface RESTOAuth2ImplicitAuthorizationQuery { + response_type: 'token'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant-redirect-url-example + */ +export type RESTOAuth2ImplicitAuthorizationURLFragmentResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#client-credentials-grant + */ +export interface RESTPostOAuth2ClientCredentialsURLEncodedData { + grant_type: 'client_credentials'; + scope: string; +} + +export type RESTPostOAuth2ClientCredentialsResult = RESTOAuth2ImplicitAuthorizationURLFragmentResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow-bot-auth-parameters + */ +export interface RESTOAuth2BotAuthorizationQuery { + /** + * Your app's client id + */ + client_id: Snowflake; + /** + * Needs to include bot for the bot flow + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The permissions you're requesting + * + * See https://discord.com/developers/docs/topics/permissions + */ + permissions?: Permissions; + /** + * Pre-fills the dropdown picker with a guild for the user + */ + guild_id?: Snowflake; + /** + * `true` or `false`—disallows the user from changing the guild dropdown + */ + disable_guild_select?: boolean; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization + */ +export interface RESTOAuth2AdvancedBotAuthorizationQuery { + client_id: Snowflake; + /** + * This assumes you include the `bot` scope alongside others (like `identify` for example) + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The required permissions bitfield, stringified + */ + permissions?: Permissions; + guild_id?: Snowflake; + disable_guild_select?: boolean; + response_type: string; + redirect_uri?: string; +} + +export interface RESTOAuth2AdvancedBotAuthorizationQueryResult { + code: string; + state?: string; + guild_id: Snowflake; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization-extended-bot-authorization-access-token-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + guild: APIGuild; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#webhooks-webhook-token-response-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + webhook: APIWebhook; +} + +export type RESTPostOAuth2AccessTokenWithBotAndGuildsAndWebhookIncomingScopeResult = RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult & + RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult; diff --git a/deno/rest/v9/template.ts b/deno/rest/v9/template.ts new file mode 100644 index 00000000..d2a56ce5 --- /dev/null +++ b/deno/rest/v9/template.ts @@ -0,0 +1,70 @@ +import type { APIGuild, APITemplate } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/template#get-template + */ +export type RESTGetAPITemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#create-guild-from-template + */ +export interface RESTPostAPITemplateCreateGuildJSONBody { + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; +} +/** + * https://discord.com/developers/docs/resources/template#create-guild-from-template + */ +export type RESTPostAPITemplateCreateGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/template#get-guild-templates + */ +export type RESTGetAPIGuildTemplatesResult = APITemplate[]; + +/** + * https://discord.com/developers/docs/resources/template#create-guild-template + */ +export interface RESTPostAPIGuildTemplatesJSONBody { + /** + * Name of the template (1-100 characters) + */ + name: string; + /** + * Description for the template (0-120 characters) + */ + description?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/template#create-guild-template + */ +export type RESTPostAPIGuildTemplatesResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#sync-guild-template + */ +export type RESTPutAPIGuildTemplateSyncResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateJSONBody = Partial; + +/** + * https://discord.com/developers/docs/resources/template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#delete-guild-template + */ +export type RESTDeleteAPIGuildTemplateResult = APITemplate; diff --git a/deno/rest/v9/user.ts b/deno/rest/v9/user.ts new file mode 100644 index 00000000..001402b0 --- /dev/null +++ b/deno/rest/v9/user.ts @@ -0,0 +1,90 @@ +import type { Permissions, Snowflake } from '../../globals.ts'; +import type { APIChannel, APIConnection, APIUser, GuildFeature } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user + */ +export type RESTGetAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-user + */ +export type RESTGetAPIUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export interface RESTPatchAPICurrentUserJSONBody { + /** + * User's username, if changed may cause the user's discriminator to be randomized + */ + username?: string; + /** + * If passed, modifies the user's avatar + */ + avatar?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export type RESTPatchAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export interface RESTGetAPICurrentUserGuildsQuery { + /** + * Get guilds before this guild ID + */ + before?: Snowflake; + /** + * Get guilds after this guild ID + */ + after?: Snowflake; + /** + * Max number of guilds to return (1-100) + * + * @default 100 + */ + limit?: number; +} + +export interface RESTAPIPartialCurrentUserGuild { + id: Snowflake; + name: string; + icon: string | null; + owner: boolean; + features: GuildFeature[]; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export type RESTGetAPICurrentUserGuildsResult = RESTAPIPartialCurrentUserGuild[]; + +/** + * https://discord.com/developers/docs/resources/user#leave-guild + */ +export type RESTDeleteAPICurrentUserGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export interface RESTPostAPICurrentUserCreateDMChannelJSONBody { + /** + * The recipient to open a DM channel with + */ + recipient_id: string; +} + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export type RESTPostAPICurrentUserCreateDMChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/user#get-user-connections + */ +export type RESTGetAPICurrentUserConnectionsResult = APIConnection[]; diff --git a/deno/rest/v9/voice.ts b/deno/rest/v9/voice.ts new file mode 100644 index 00000000..296f81de --- /dev/null +++ b/deno/rest/v9/voice.ts @@ -0,0 +1,6 @@ +import type { APIVoiceRegion } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/voice#list-voice-regions + */ +export type GetAPIVoiceRegionsResult = APIVoiceRegion[]; diff --git a/deno/rest/v9/webhook.ts b/deno/rest/v9/webhook.ts new file mode 100644 index 00000000..b7dbfbbd --- /dev/null +++ b/deno/rest/v9/webhook.ts @@ -0,0 +1,252 @@ +import type { Snowflake } from '../../globals.ts'; +import type { APIAllowedMentions, APIEmbed, APIMessage, APIWebhook } from '../../payloads/v9/mod.ts'; + +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export interface RESTPostAPIChannelWebhookJSONBody { + /** + * Name of the webhook (1-80 characters) + */ + name: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export type RESTPostAPIChannelWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-channel-webhooks + */ +export type RESTGetAPIChannelWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-guild-webhooks + */ +export type RESTGetAPIGuildWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook + */ +export type RESTGetAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-with-token + */ +export type RESTGetAPIWebhookWithTokenResult = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export interface RESTPatchAPIWebhookJSONBody { + /** + * The default name of the webhook + */ + name?: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; + /** + * The new channel id this webhook should be moved to + */ + channel_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export type RESTPatchAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenJSONBody = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenResult = RESTGetAPIWebhookWithTokenResult; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook + */ +export type RESTDeleteAPIWebhookResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token + */ +export type RESTDeleteAPIWebhookWithTokenResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export interface RESTPostAPIWebhookWithTokenJSONBody { + /** + * The message contents (up to 2000 characters) + */ + content?: string; + /** + * Override the default username of the webhook + */ + username?: string; + /** + * Override the default avatar of the webhook + */ + avatar_url?: string; + /** + * `true` if this is a TTS message + */ + tts?: boolean; + /** + * Embedded `rich` content + */ + embeds?: APIEmbed[]; + /** + * Allowed mentions for the message + */ + allowed_mentions?: APIAllowedMentions; + /** + * The thread to post this message in + */ + thread_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIWebhookWithTokenJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export interface RESTPostAPIWebhookWithTokenQuery { + /** + * Waits for server confirmation of message send before response, and returns the created message body + * (defaults to `false`; when `false` a message that is not saved does not return an error) + * + * @default false + */ + wait?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenSlackResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenGitHubResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageJSONBody = Nullable< + Pick +>; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPatchAPIWebhookWithTokenMessageJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-message + */ +export type RESTGetAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-message + */ +export type RESTDeleteAPIWebhookWithTokenMessageResult = never; + +type Nullable = { + [P in keyof T]: T[P] | null; +}; diff --git a/deno/rpc/mod.ts b/deno/rpc/mod.ts index 567a4e3d..27b9e84b 100644 --- a/deno/rpc/mod.ts +++ b/deno/rpc/mod.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8.ts'; +export * from './v9.ts'; diff --git a/deno/rpc/v9.ts b/deno/rpc/v9.ts new file mode 100644 index 00000000..8798138c --- /dev/null +++ b/deno/rpc/v9.ts @@ -0,0 +1,33 @@ +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc-rpc-error-codes + */ +export enum RPCErrorCodes { + UnknownError = 1000, + InvalidPayload = 4000, + InvalidCommand = 4002, + InvalidGuild, + InvalidEvent, + InvalidChannel, + InvalidPermissions, + InvalidClientID, + InvalidOrigin, + InvalidToken, + InvalidUser, + OAuth2Error = 5000, + SelectChannelTimedOut, + GetGuildTimedOut, + SelectVoiceForceRequired, + CaptureShortcutAlreadyListening, +} + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc-rpc-close-event-codes + */ +export enum RPCCloseEventCodes { + InvalidClientID = 4000, + InvalidOrigin, + RateLimited, + TokenRevoked, + InvalidVersion, + InvalidEncoding, +} diff --git a/deno/utils/mod.ts b/deno/utils/mod.ts index d644c6ab..99effc2d 100644 --- a/deno/utils/mod.ts +++ b/deno/utils/mod.ts @@ -1,4 +1,4 @@ // This file exports all the utility functions available in the recommended API / Gateway version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8.ts'; +export * from './v9.ts'; diff --git a/deno/utils/v9.ts b/deno/utils/v9.ts new file mode 100644 index 00000000..298dcc89 --- /dev/null +++ b/deno/utils/v9.ts @@ -0,0 +1,48 @@ +import { + APIApplicationCommandDMInteraction, + APIApplicationCommandGuildInteraction, + APIApplicationCommandInteraction, + APIDMInteraction, + APIGuildInteraction, + APIInteraction, +} from '../payloads/v9/mod.ts'; + +/** + * A type-guard check for guild interactions. + * @param interaction The interaction to check against the + * @returns A boolean that indicates if the interaction was received from a guild + */ +export function isGuildInteraction(interaction: APIInteraction): interaction is APIGuildInteraction { + return Reflect.has(interaction, 'guild_id'); +} + +/** + * A type-guard check for DM interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction was received from a direct message + */ +export function isDMInteraction(interaction: APIInteraction): interaction is APIDMInteraction { + return !isGuildInteraction(interaction); +} + +/** + * A type-guard check for guild application command interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the command interaction was received from a guild + */ +export function isApplicationCommandGuildInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandGuildInteraction { + return isGuildInteraction(interaction); +} + +/** + * A type-guard check for direct message application command interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the command interaction was received from a direct message + */ +export function isApplicationCommandDMInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandDMInteraction { + return !isGuildInteraction(interaction); +} diff --git a/deno/v9.ts b/deno/v9.ts new file mode 100644 index 00000000..a690f6b8 --- /dev/null +++ b/deno/v9.ts @@ -0,0 +1,6 @@ +export * from './globals.ts'; +export * from './gateway/v9.ts'; +export * from './payloads/v9/mod.ts'; +export * from './rest/v9/mod.ts'; +export * from './rpc/v9.ts'; +export * as Utils from './utils/v9.ts'; diff --git a/gateway/index.ts b/gateway/index.ts index a0be17f6..59605663 100644 --- a/gateway/index.ts +++ b/gateway/index.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended gateway version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8'; +export * from './v9'; diff --git a/gateway/v9.ts b/gateway/v9.ts new file mode 100644 index 00000000..dd7eb5b8 --- /dev/null +++ b/gateway/v9.ts @@ -0,0 +1,1646 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/gateway + */ + +import type { Snowflake } from '../globals'; +import type { + APIApplication, + APIApplicationCommand, + APIApplicationCommandInteraction, + APIChannel, + APIEmoji, + APIGuild, + APIGuildIntegration, + APIGuildMember, + APIMessage, + APIRole, + APIThreadMember, + APIUnavailableGuild, + APIUser, + GatewayActivity, + GatewayPresenceUpdate as RawGatewayPresenceUpdate, + GatewayThreadListSync as RawGatewayThreadListSync, + GatewayThreadMembersUpdate as RawGatewayThreadMembersUpdate, + GatewayVoiceState, + InviteTargetType, + PresenceUpdateStatus, +} from '../payloads/v9/index'; + +export * from './common'; + +export const GatewayVersion = '9'; + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes + */ +export const enum GatewayOpcodes { + /** + * An event was dispatched + */ + Dispatch, + /** + * A bidirectional opcode to maintain an active gateway connection. + * Fired periodically by the client, or fired by the gateway to request an immediate heartbeat from the client. + */ + Heartbeat, + /** + * Starts a new session during the initial handshake + */ + Identify, + /** + * Update the client's presence + */ + PresenceUpdate, + /** + * Used to join/leave or move between voice channels + */ + VoiceStateUpdate, + /** + * Resume a previous session that was disconnected + */ + Resume = 6, + /** + * You should attempt to reconnect and resume immediately + */ + Reconnect, + /** + * Request information about offline guild members in a large guild + */ + RequestGuildMembers, + /** + * The session has been invalidated. You should reconnect and identify/resume accordingly + */ + InvalidSession, + /** + * Sent immediately after connecting, contains the `heartbeat_interval` to use + */ + Hello, + /** + * Sent in response to receiving a heartbeat to acknowledge that it has been received + */ + HeartbeatAck, +} + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-close-event-codes + */ +export const enum GatewayCloseCodes { + /** + * We're not sure what went wrong. Try reconnecting? + */ + UnknownError = 4000, + /** + * You sent an invalid Gateway opcode or an invalid payload for an opcode. Don't do that! + * + * See https://discord.com/developers/docs/topics/gateway#payloads-and-opcodes + */ + UnknownOpcode, + /** + * You sent an invalid payload to us. Don't do that! + * + * See https://discord.com/developers/docs/topics/gateway#sending-payloads + */ + DecodeError, + /** + * You sent us a payload prior to identifying + * + * See https://discord.com/developers/docs/topics/gateway#identify + */ + NotAuthenticated, + /** + * The account token sent with your identify payload is incorrect + * + * See https://discord.com/developers/docs/topics/gateway#identify + */ + AuthenticationFailed, + /** + * You sent more than one identify payload. Don't do that! + */ + AlreadyAuthenticated, + /** + * The sequence sent when resuming the session was invalid. Reconnect and start a new session + * + * See https://discord.com/developers/docs/topics/gateway#resume + */ + InvalidSeq = 4007, + /** + * Woah nelly! You're sending payloads to us too quickly. Slow it down! You will be disconnected on receiving this + */ + RateLimited, + /** + * Your session timed out. Reconnect and start a new one + */ + SessionTimedOut, + /** + * You sent us an invalid shard when identifying + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + InvalidShard, + /** + * The session would have handled too many guilds - you are required to shard your connection in order to connect + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + ShardingRequired, + /** + * You sent an invalid version for the gateway + */ + InvalidAPIVersion, + /** + * You sent an invalid intent for a Gateway Intent. You may have incorrectly calculated the bitwise value + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + */ + InvalidIntents, + /** + * You sent a disallowed intent for a Gateway Intent. You may have tried to specify an intent that you have not + * enabled or are not whitelisted for + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + * + * See https://discord.com/developers/docs/topics/gateway#privileged-intents + */ + DisallowedIntents, +} + +/** + * https://discord.com/developers/docs/topics/gateway#list-of-intents + */ +export const enum GatewayIntentBits { + Guilds = 1 << 0, + GuildMembers = 1 << 1, + GuildBans = 1 << 2, + GuildEmojis = 1 << 3, + GuildIntegrations = 1 << 4, + GuildWebhooks = 1 << 5, + GuildInvites = 1 << 6, + GuildVoiceStates = 1 << 7, + GuildPresences = 1 << 8, + GuildMessages = 1 << 9, + GuildMessageReactions = 1 << 10, + GuildMessageTyping = 1 << 11, + DirectMessages = 1 << 12, + DirectMessageReactions = 1 << 13, + DirectMessageTyping = 1 << 14, +} + +/** + * https://discord.com/developers/docs/topics/gateway#commands-and-events-gateway-events + */ +export const enum GatewayDispatchEvents { + ApplicationCommandCreate = 'APPLICATION_COMMAND_CREATE', + ApplicationCommandDelete = 'APPLICATION_COMMAND_DELETE', + ApplicationCommandUpdate = 'APPLICATION_COMMAND_UPDATE', + ChannelCreate = 'CHANNEL_CREATE', + ChannelDelete = 'CHANNEL_DELETE', + ChannelPinsUpdate = 'CHANNEL_PINS_UPDATE', + ChannelUpdate = 'CHANNEL_UPDATE', + GuildBanAdd = 'GUILD_BAN_ADD', + GuildBanRemove = 'GUILD_BAN_REMOVE', + GuildCreate = 'GUILD_CREATE', + GuildDelete = 'GUILD_DELETE', + GuildEmojisUpdate = 'GUILD_EMOJIS_UPDATE', + GuildIntegrationsUpdate = 'GUILD_INTEGRATIONS_UPDATE', + GuildMemberAdd = 'GUILD_MEMBER_ADD', + GuildMemberRemove = 'GUILD_MEMBER_REMOVE', + GuildMembersChunk = 'GUILD_MEMBERS_CHUNK', + GuildMemberUpdate = 'GUILD_MEMBER_UPDATE', + GuildRoleCreate = 'GUILD_ROLE_CREATE', + GuildRoleDelete = 'GUILD_ROLE_DELETE', + GuildRoleUpdate = 'GUILD_ROLE_UPDATE', + GuildUpdate = 'GUILD_UPDATE', + IntegrationCreate = 'INTEGRATION_CREATE', + IntegrationDelete = 'INTEGRATION_DELETE', + IntegrationUpdate = 'INTEGRATION_UPDATE', + InteractionCreate = 'INTERACTION_CREATE', + InviteCreate = 'INVITE_CREATE', + InviteDelete = 'INVITE_DELETE', + MessageCreate = 'MESSAGE_CREATE', + MessageDelete = 'MESSAGE_DELETE', + MessageDeleteBulk = 'MESSAGE_DELETE_BULK', + MessageReactionAdd = 'MESSAGE_REACTION_ADD', + MessageReactionRemove = 'MESSAGE_REACTION_REMOVE', + MessageReactionRemoveAll = 'MESSAGE_REACTION_REMOVE_ALL', + MessageReactionRemoveEmoji = 'MESSAGE_REACTION_REMOVE_EMOJI', + MessageUpdate = 'MESSAGE_UPDATE', + PresenceUpdate = 'PRESENCE_UPDATE', + Ready = 'READY', + Resumed = 'RESUMED', + ThreadCreate = 'THREAD_CREATE', + ThreadDelete = 'THREAD_DELETE', + ThreadListSync = 'THREAD_LIST_SYNC', + ThreadMembersUpdate = 'THREAD_MEMBERS_UPDATE', + ThreadMemberUpdate = 'THREAD_MEMBER_UPDATE', + ThreadUpdate = 'THREAD_UPDATE', + TypingStart = 'TYPING_START', + UserUpdate = 'USER_UPDATE', + VoiceServerUpdate = 'VOICE_SERVER_UPDATE', + VoiceStateUpdate = 'VOICE_STATE_UPDATE', + WebhooksUpdate = 'WEBHOOKS_UPDATE', +} + +export type GatewaySendPayload = + | GatewayHeartbeat + | GatewayIdentify + | GatewayUpdatePresence + | GatewayVoiceStateUpdate + | GatewayResume + | GatewayRequestGuildMembers; + +export type GatewayReceivePayload = + | GatewayHello + | GatewayHeartbeatRequest + | GatewayHeartbeatAck + | GatewayInvalidSession + | GatewayReconnect + | GatewayDispatchPayload; + +export type GatewayDispatchPayload = + | GatewayChannelModifyDispatch + | GatewayChannelPinsUpdateDispatch + | GatewayGuildBanModifyDispatch + | GatewayGuildDeleteDispatch + | GatewayGuildEmojisUpdateDispatch + | GatewayGuildIntegrationsUpdateDispatch + | GatewayGuildMemberAddDispatch + | GatewayGuildMemberRemoveDispatch + | GatewayGuildMembersChunkDispatch + | GatewayGuildMemberUpdateDispatch + | GatewayGuildModifyDispatch + | GatewayGuildRoleDeleteDispatch + | GatewayGuildRoleModifyDispatch + | GatewayIntegrationCreateDispatch + | GatewayIntegrationDeleteDispatch + | GatewayIntegrationUpdateDispatch + | GatewayInteractionCreateDispatch + | GatewayInviteCreateDispatch + | GatewayInviteDeleteDispatch + | GatewayMessageCreateDispatch + | GatewayMessageDeleteBulkDispatch + | GatewayMessageDeleteDispatch + | GatewayMessageReactionAddDispatch + | GatewayMessageReactionRemoveAllDispatch + | GatewayMessageReactionRemoveDispatch + | GatewayMessageReactionRemoveEmojiDispatch + | GatewayMessageUpdateDispatch + | GatewayPresenceUpdateDispatch + | GatewayReadyDispatch + | GatewayResumedDispatch + | GatewayThreadListSyncDispatch + | GatewayThreadMembersUpdateDispatch + | GatewayThreadMemberUpdateDispatch + | GatewayThreadModifyDispatch + | GatewayTypingStartDispatch + | GatewayUserUpdateDispatch + | GatewayVoiceServerUpdateDispatch + | GatewayVoiceStateUpdateDispatch + | GatewayWebhooksUpdateDispatch; + +// #region Dispatch Payloads + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + * https://discord.com/developers/docs/topics/gateway#application-command-update + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandModifyDispatch = DataPayload< + | GatewayDispatchEvents.ApplicationCommandCreate + | GatewayDispatchEvents.ApplicationCommandUpdate + | GatewayDispatchEvents.ApplicationCommandDelete, + GatewayApplicationCommandModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + * https://discord.com/developers/docs/topics/gateway#application-command-update + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export interface GatewayApplicationCommandModifyDispatchData extends APIApplicationCommand { + guild_id?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + */ +export type GatewayApplicationCommandCreateDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-create + */ +export type GatewayApplicationCommandCreateDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-update + */ +export type GatewayApplicationCommandUpdateDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-update + */ +export type GatewayApplicationCommandUpdateDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandDeleteDispatch = GatewayApplicationCommandModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#application-command-delete + */ +export type GatewayApplicationCommandDeleteDispatchData = GatewayApplicationCommandModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#hello + */ +export interface GatewayHello extends NonDispatchPayload { + op: GatewayOpcodes.Hello; + d: GatewayHelloData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#hello + */ +export interface GatewayHelloData { + /** + * The interval (in milliseconds) the client should heartbeat with + */ + heartbeat_interval: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export interface GatewayHeartbeatRequest extends NonDispatchPayload { + op: GatewayOpcodes.Heartbeat; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack + */ +export interface GatewayHeartbeatAck extends NonDispatchPayload { + op: GatewayOpcodes.HeartbeatAck; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invalid-session + */ +export interface GatewayInvalidSession extends NonDispatchPayload { + op: GatewayOpcodes.InvalidSession; + d: GatewayInvalidSessionData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invalid-session + */ +export type GatewayInvalidSessionData = boolean; + +/** + * https://discord.com/developers/docs/topics/gateway#reconnect + */ +export interface GatewayReconnect extends NonDispatchPayload { + op: GatewayOpcodes.Reconnect; + d: never; +} + +/** + * https://discord.com/developers/docs/topics/gateway#ready + */ +export type GatewayReadyDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#ready + */ +export interface GatewayReadyDispatchData { + /** + * Gateway version + * + * See https://discord.com/developers/docs/topics/gateway#gateways-gateway-versions + */ + v: number; + /** + * Information about the user including email + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; + /** + * The guilds the user is in + * + * See https://discord.com/developers/docs/resources/guild#unavailable-guild-object + */ + guilds: APIUnavailableGuild[]; + /** + * Used for resuming connections + */ + session_id: string; + /** + * The shard information associated with this session, if sent when identifying + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shard?: [shard_id: number, shard_count: number]; + /** + * Contains `id` and `flags` + * + * See https://discord.com/developers/docs/topics/oauth2#application-object + */ + application: Pick; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resumed + */ +export type GatewayResumedDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + * https://discord.com/developers/docs/topics/gateway#channel-update + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelModifyDispatch = DataPayload< + GatewayDispatchEvents.ChannelCreate | GatewayDispatchEvents.ChannelDelete | GatewayDispatchEvents.ChannelUpdate, + GatewayChannelModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + * https://discord.com/developers/docs/topics/gateway#channel-update + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelModifyDispatchData = APIChannel; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + */ +export type GatewayChannelCreateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-create + */ +export type GatewayChannelCreateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-update + */ +export type GatewayChannelUpdateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-update + */ +export type GatewayChannelUpdateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelDeleteDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-delete + */ +export type GatewayChannelDeleteDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-pins-update + */ +export type GatewayChannelPinsUpdateDispatch = DataPayload< + GatewayDispatchEvents.ChannelPinsUpdate, + GatewayChannelPinsUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#channel-pins-update + */ +export interface GatewayChannelPinsUpdateDispatchData { + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The time at which the most recent pinned message was pinned + */ + last_pin_timestamp?: string | null; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildCreate | GatewayDispatchEvents.GuildUpdate, + GatewayGuildModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildModifyDispatchData = APIGuild; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + */ +export type GatewayGuildCreateDispatch = GatewayGuildModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-create + */ +export type GatewayGuildCreateDispatchData = GatewayGuildModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildUpdateDispatch = GatewayGuildModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-update + */ +export type GatewayGuildUpdateDispatchData = GatewayGuildModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-delete + */ +export type GatewayGuildDeleteDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-delete + */ +export type GatewayGuildDeleteDispatchData = APIUnavailableGuild; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildBanAdd | GatewayDispatchEvents.GuildBanRemove, + GatewayGuildBanModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export interface GatewayGuildBanModifyDispatchData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * The banned user + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + */ +export type GatewayGuildBanAddDispatch = GatewayGuildBanModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-add + */ +export type GatewayGuildBanAddDispatchData = GatewayGuildBanModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanRemoveDispatch = GatewayGuildBanModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-ban-remove + */ +export type GatewayGuildBanRemoveDispatchData = GatewayGuildBanModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-emojis-update + */ +export type GatewayGuildEmojisUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildEmojisUpdate, + GatewayGuildEmojisUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-emojis-update + */ +export interface GatewayGuildEmojisUpdateDispatchData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * Array of emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-integrations-update + */ +export type GatewayGuildIntegrationsUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildIntegrationsUpdate, + GatewayGuildIntegrationsUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-integrations-update + */ +export interface GatewayGuildIntegrationsUpdateDispatchData { + /** + * ID of the guild whose integrations were updated + */ + guild_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-add + */ +export type GatewayGuildMemberAddDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberAdd, + GatewayGuildMemberAddDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-add + */ +export interface GatewayGuildMemberAddDispatchData extends APIGuildMember { + /** + * The id of the guild + */ + guild_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-remove + */ +export type GatewayGuildMemberRemoveDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberRemove, + GatewayGuildMemberRemoveDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-remove + */ +export interface GatewayGuildMemberRemoveDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The user who was removed + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-update + */ +export type GatewayGuildMemberUpdateDispatch = DataPayload< + GatewayDispatchEvents.GuildMemberUpdate, + GatewayGuildMemberUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-member-update + */ +export type GatewayGuildMemberUpdateDispatchData = Omit & + Partial> & + Required> & { + /** + * The id of the guild + */ + guild_id: Snowflake; + }; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ +export type GatewayGuildMembersChunkDispatch = DataPayload< + GatewayDispatchEvents.GuildMembersChunk, + GatewayGuildMembersChunkDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ +export interface GatewayGuildMembersChunkDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * Set of guild members + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + members: APIGuildMember[]; + /** + * The chunk index in the expected chunks for this response (`0 <= chunk_index < chunk_count`) + */ + chunk_index?: number; + /** + * The total number of expected chunks for this response + */ + chunk_count?: number; + /** + * If passing an invalid id to `REQUEST_GUILD_MEMBERS`, it will be returned here + */ + not_found?: unknown[]; + /** + * If passing true to `REQUEST_GUILD_MEMBERS`, presences of the returned members will be here + * + * See https://discord.com/developers/docs/topics/gateway#presence + */ + presences?: RawGatewayPresenceUpdate[]; + /** + * The nonce used in the Guild Members Request + * + * See https://discord.com/developers/docs/topics/gateway#request-guild-members + */ + nonce?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleModifyDispatch = DataPayload< + GatewayDispatchEvents.GuildRoleCreate | GatewayDispatchEvents.GuildRoleUpdate, + GatewayGuildRoleModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export interface GatewayGuildRoleModifyDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The role created or updated + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + role: APIRole; +} + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + */ +export type GatewayGuildRoleCreateDispatch = GatewayGuildRoleModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-create + */ +export type GatewayGuildRoleCreateDispatchData = GatewayGuildRoleModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleUpdateDispatch = GatewayGuildRoleModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-update + */ +export type GatewayGuildRoleUpdateDispatchData = GatewayGuildRoleModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-delete + */ +export type GatewayGuildRoleDeleteDispatch = DataPayload< + GatewayDispatchEvents.GuildRoleDelete, + GatewayGuildRoleDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#guild-role-delete + */ +export interface GatewayGuildRoleDeleteDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The id of the role + */ + role_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#integration-create + */ +export type GatewayIntegrationCreateDispatch = DataPayload< + GatewayDispatchEvents.IntegrationCreate, + GatewayIntegrationCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-create + */ +export type GatewayIntegrationCreateDispatchData = APIGuildIntegration & { guild_id: Snowflake }; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationUpdateDispatch = DataPayload< + GatewayDispatchEvents.IntegrationUpdate, + GatewayIntegrationUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationUpdateDispatchData = APIGuildIntegration & { guild_id: Snowflake }; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-update + */ +export type GatewayIntegrationDeleteDispatch = DataPayload< + GatewayDispatchEvents.IntegrationDelete, + GatewayIntegrationDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#integration-delete + */ +export interface GatewayIntegrationDeleteDispatchData { + /** + * Integration id + */ + id: Snowflake; + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * ID of the bot/OAuth2 application for this Discord integration + */ + application_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#interaction-create + */ +export type GatewayInteractionCreateDispatch = DataPayload< + GatewayDispatchEvents.InteractionCreate, + GatewayInteractionCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#interaction-create + */ +export type GatewayInteractionCreateDispatchData = APIApplicationCommandInteraction; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-create + */ +export type GatewayInviteCreateDispatch = DataPayload< + GatewayDispatchEvents.InviteCreate, + GatewayInviteCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-create + */ +export interface GatewayInviteCreateDispatchData { + /** + * The channel the invite is for + */ + channel_id: Snowflake; + /** + * The unique invite code + * + * See https://discord.com/developers/docs/resources/invite#invite-object + */ + code: string; + /** + * The time at which the invite was created + */ + created_at: number; + /** + * The guild of the invite + */ + guild_id?: Snowflake; + /** + * The user that created the invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + inviter?: APIUser; + /** + * How long the invite is valid for (in seconds) + */ + max_age: number; + /** + * The maximum number of times the invite can be used + */ + max_uses: number; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ + target_type?: InviteTargetType; + /** + * The user whose stream to display for this voice channel stream invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + target_user?: APIUser; + /** + * The embedded application to open for this voice channel embedded application invite + */ + target_application?: Partial; + /** + * Whether or not the invite is temporary (invited users will be kicked on disconnect unless they're assigned a role) + */ + temporary: boolean; + /** + * How many times the invite has been used (always will be `0`) + */ + uses: 0; +} + +/** + * https://discord.com/developers/docs/topics/gateway#invite-delete + */ +export type GatewayInviteDeleteDispatch = DataPayload< + GatewayDispatchEvents.InviteDelete, + GatewayInviteDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#invite-delete + */ +export interface GatewayInviteDeleteDispatchData { + /** + * The channel of the invite + */ + channel_id: Snowflake; + /** + * The guild of the invite + */ + guild_id?: Snowflake; + /** + * The unique invite code + * + * See https://discord.com/developers/docs/resources/invite#invite-object + */ + code: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-create + */ +export type GatewayMessageCreateDispatch = DataPayload< + GatewayDispatchEvents.MessageCreate, + GatewayMessageCreateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-create + */ +export type GatewayMessageCreateDispatchData = APIMessage; + +/** + * https://discord.com/developers/docs/topics/gateway#message-update + */ +export type GatewayMessageUpdateDispatch = DataPayload< + GatewayDispatchEvents.MessageUpdate, + GatewayMessageUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-update + */ +export type GatewayMessageUpdateDispatchData = { + id: Snowflake; + channel_id: Snowflake; +} & Partial; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete + */ +export type GatewayMessageDeleteDispatch = DataPayload< + GatewayDispatchEvents.MessageDelete, + GatewayMessageDeleteDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete + */ +export interface GatewayMessageDeleteDispatchData { + /** + * The id of the message + */ + id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete-bulk + */ +export type GatewayMessageDeleteBulkDispatch = DataPayload< + GatewayDispatchEvents.MessageDeleteBulk, + GatewayMessageDeleteBulkDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-delete-bulk + */ +export interface GatewayMessageDeleteBulkDispatchData { + /** + * The ids of the messages + */ + ids: Snowflake[]; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-add + */ +export type GatewayMessageReactionAddDispatch = ReactionData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-add + */ +export type GatewayMessageReactionAddDispatchData = GatewayMessageReactionAddDispatch['d']; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove + */ +export type GatewayMessageReactionRemoveDispatch = ReactionData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove + */ +export type GatewayMessageReactionRemoveDispatchData = GatewayMessageReactionRemoveDispatch['d']; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all + */ +export type GatewayMessageReactionRemoveAllDispatch = DataPayload< + GatewayDispatchEvents.MessageReactionRemoveAll, + GatewayMessageReactionRemoveAllDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all + */ +export type GatewayMessageReactionRemoveAllDispatchData = MessageReactionRemoveData; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + */ +export type GatewayMessageReactionRemoveEmojiDispatch = DataPayload< + GatewayDispatchEvents.MessageReactionRemoveEmoji, + GatewayMessageReactionRemoveEmojiDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji + */ +export interface GatewayMessageReactionRemoveEmojiDispatchData extends MessageReactionRemoveData { + /** + * The emoji that was removed + */ + emoji: APIEmoji; +} + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update + */ +export type GatewayPresenceUpdateDispatch = DataPayload< + GatewayDispatchEvents.PresenceUpdate, + GatewayPresenceUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update + */ +export type GatewayPresenceUpdateDispatchData = RawGatewayPresenceUpdate; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync + */ +export type GatewayThreadListSyncDispatch = DataPayload< + GatewayDispatchEvents.ThreadListSync, + GatewayThreadListSyncDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync + */ +export type GatewayThreadListSyncDispatchData = RawGatewayThreadListSync; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update + */ +export type GatewayThreadMembersUpdateDispatch = DataPayload< + GatewayDispatchEvents.ThreadMembersUpdate, + GatewayThreadMembersUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update + */ +export type GatewayThreadMembersUpdateDispatchData = RawGatewayThreadMembersUpdate; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-member-update + */ +export type GatewayThreadMemberUpdateDispatch = DataPayload< + GatewayDispatchEvents.ThreadMemberUpdate, + GatewayThreadMemberUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-member-update + */ +export type GatewayThreadMemberUpdateDispatchData = APIThreadMember; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + * https://discord.com/developers/docs/topics/gateway#thread-update + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadModifyDispatch = DataPayload< + GatewayDispatchEvents.ThreadCreate | GatewayDispatchEvents.ThreadDelete | GatewayDispatchEvents.ThreadUpdate, + GatewayChannelModifyDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + */ +export type GatewayThreadCreateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-create + */ +export type GatewayThreadCreateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-update + */ +export type GatewayThreadUpdateDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-update + */ +export type GatewayThreadUpdateDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadDeleteDispatch = GatewayChannelModifyDispatch; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-delete + */ +export type GatewayThreadDeleteDispatchData = GatewayChannelModifyDispatchData; + +/** + * https://discord.com/developers/docs/topics/gateway#typing-start + */ +export type GatewayTypingStartDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#typing-start + */ +export interface GatewayTypingStartDispatchData { + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The id of the user + */ + user_id: Snowflake; + /** + * Unix time (in seconds) of when the user started typing + */ + timestamp: number; + /** + * The member who started typing if this happened in a guild + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; +} + +/** + * https://discord.com/developers/docs/topics/gateway#user-update + */ +export type GatewayUserUpdateDispatch = DataPayload; + +/** + * https://discord.com/developers/docs/topics/gateway#user-update + */ +export type GatewayUserUpdateDispatchData = APIUser; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-state-update + */ +export type GatewayVoiceStateUpdateDispatch = DataPayload< + GatewayDispatchEvents.VoiceStateUpdate, + GatewayVoiceStateUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-state-update + */ +export type GatewayVoiceStateUpdateDispatchData = GatewayVoiceState; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-server-update + */ +export type GatewayVoiceServerUpdateDispatch = DataPayload< + GatewayDispatchEvents.VoiceServerUpdate, + GatewayVoiceServerUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#voice-server-update + */ +export interface GatewayVoiceServerUpdateDispatchData { + /** + * Voice connection token + */ + token: string; + /** + * The guild this voice server update is for + */ + guild_id: Snowflake; + /** + * The voice server host + * + * A `null` endpoint means that the voice server allocated has gone away and is trying to be reallocated. + * You should attempt to disconnect from the currently connected voice server, and not attempt to reconnect + * until a new voice server is allocated + */ + endpoint: string | null; +} + +/** + * https://discord.com/developers/docs/topics/gateway#webhooks-update + */ +export type GatewayWebhooksUpdateDispatch = DataPayload< + GatewayDispatchEvents.WebhooksUpdate, + GatewayWebhooksUpdateDispatchData +>; + +/** + * https://discord.com/developers/docs/topics/gateway#webhooks-update + */ +export interface GatewayWebhooksUpdateDispatchData { + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; +} + +// #endregion Dispatch Payloads + +// #region Sendable Payloads + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export interface GatewayHeartbeat { + op: GatewayOpcodes.Heartbeat; + d: GatewayHeartbeatData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#heartbeating + */ +export type GatewayHeartbeatData = number | null; + +/** + * https://discord.com/developers/docs/topics/gateway#identify + */ +export interface GatewayIdentify { + op: GatewayOpcodes.Identify; + d: GatewayIdentifyData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#identify + */ +export interface GatewayIdentifyData { + /** + * Authentication token + */ + token: string; + /** + * Connection properties + * + * See https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties + */ + properties: GatewayIdentifyProperties; + /** + * Whether this connection supports compression of packets + * + * @default false + */ + compress?: boolean; + /** + * Value between 50 and 250, total number of members where the gateway will stop sending + * offline members in the guild member list + * + * @default 50 + */ + large_threshold?: number; + /** + * Used for Guild Sharding + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shard?: [shard_id: number, shard_count: number]; + /** + * Presence structure for initial presence information + * + * See https://discord.com/developers/docs/topics/gateway#update-status + */ + presence?: GatewayPresenceUpdateData; + /** + * The Gateway Intents you wish to receive + * + * See https://discord.com/developers/docs/topics/gateway#gateway-intents + */ + intents: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties + */ +export interface GatewayIdentifyProperties { + /** + * Your operating system + */ + $os: string; + /** + * Your library name + */ + $browser: string; + /** + * Your library name + */ + $device: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resume + */ +export interface GatewayResume { + op: GatewayOpcodes.Resume; + d: GatewayResumeData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#resume + */ +export interface GatewayResumeData { + /** + * Session token + */ + token: string; + /** + * Session id + */ + session_id: string; + /** + * Last sequence number received + */ + seq: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#request-guild-members + */ +export interface GatewayRequestGuildMembers { + op: GatewayOpcodes.RequestGuildMembers; + d: GatewayRequestGuildMembersData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#request-guild-members + */ +export interface GatewayRequestGuildMembersData { + /** + * ID of the guild to get members for + */ + guild_id: Snowflake; + /** + * String that username starts with, or an empty string to return all members + */ + query?: string; + /** + * Maximum number of members to send matching the `query`; + * a limit of `0` can be used with an empty string `query` to return all members + */ + limit: number; + /** + * Used to specify if we want the presences of the matched members + */ + presences?: boolean; + /** + * Used to specify which users you wish to fetch + */ + user_ids?: Snowflake | Snowflake[]; + /** + * Nonce to identify the Guild Members Chunk response + * + * Nonce can only be up to 32 bytes. If you send an invalid nonce it will be ignored and the reply member_chunk(s) will not have a `nonce` set. + * + * See https://discord.com/developers/docs/topics/gateway#guild-members-chunk + */ + nonce?: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-voice-state + */ +export interface GatewayVoiceStateUpdate { + op: GatewayOpcodes.VoiceStateUpdate; + d: GatewayVoiceStateUpdateData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-voice-state + */ +export interface GatewayVoiceStateUpdateData { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * ID of the voice channel client wants to join (`null` if disconnecting) + */ + channel_id: Snowflake | null; + /** + * Is the client muted + */ + self_mute: boolean; + /** + * Is the client deafened + */ + self_deaf: boolean; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-status + */ +export interface GatewayUpdatePresence { + op: GatewayOpcodes.PresenceUpdate; + d: GatewayPresenceUpdateData; +} + +/** + * https://discord.com/developers/docs/topics/gateway#update-status-gateway-status-update-structure + */ +export interface GatewayPresenceUpdateData { + /** + * Unix time (in milliseconds) of when the client went idle, or `null` if the client is not idle + */ + since: number | null; + /** + * The user's activities + * + * See https://discord.com/developers/docs/topics/gateway#activity-object + */ + activities: GatewayActivityUpdateData[]; + /** + * The user's new status + * + * See https://discord.com/developers/docs/topics/gateway#update-status-status-types + */ + status: PresenceUpdateStatus; + /** + * Whether or not the client is afk + */ + afk: boolean; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-structure + */ +export type GatewayActivityUpdateData = Pick; + +// #endregion Sendable Payloads + +// #region Shared +interface BasePayload { + /** + * Opcode for the payload + */ + op: GatewayOpcodes; + /** + * Event data + */ + d?: unknown; + /** + * Sequence number, used for resuming sessions and heartbeats + */ + s: number; + /** + * The event name for this payload + */ + t?: string; +} + +type NonDispatchPayload = Omit; + +interface DataPayload extends BasePayload { + op: GatewayOpcodes.Dispatch; + t: Event; + d: D; +} + +type ReactionData = DataPayload< + E, + Omit< + { + /** + * The id of the user + */ + user_id: Snowflake; + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the message + */ + message_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; + /** + * The member who reacted if this happened in a guild + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * The emoji used to react + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emoji: APIEmoji; + }, + O + > +>; + +interface MessageReactionRemoveData { + /** + * The id of the channel + */ + channel_id: Snowflake; + /** + * The id of the message + */ + message_id: Snowflake; + /** + * The id of the guild + */ + guild_id?: Snowflake; +} +// #endregion Shared diff --git a/package.json b/package.json index 4a7b852e..eb1f7662 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "discord-api-types", "version": "0.18.1", "description": "Discord API typings that are kept up to date for use in bot library creation.", - "main": "./v8.js", - "module": "./v8.mjs", - "types": "./v8.d.ts", + "main": "./v9.js", + "module": "./v9.mjs", + "types": "./v9.d.ts", "exports": { "./globals": { "require": "./globals.js", @@ -18,6 +18,10 @@ "require": "./v8.js", "import": "./v8.mjs" }, + "./v9": { + "require": "./v9.js", + "import": "./v9.mjs" + }, "./gateway": { "require": "./gateway/index.js", "import": "./gateway/index.mjs" diff --git a/payloads/index.ts b/payloads/index.ts index 8e20aaf8..fad3a484 100644 --- a/payloads/index.ts +++ b/payloads/index.ts @@ -1,4 +1,4 @@ // This file exports all the payloads available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8/index'; +export * from './v9/index'; diff --git a/payloads/v9/auditLog.ts b/payloads/v9/auditLog.ts new file mode 100644 index 00000000..a4b52b58 --- /dev/null +++ b/payloads/v9/auditLog.ts @@ -0,0 +1,576 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/audit-log + */ + +import type { Snowflake } from '../../globals'; +import type { APIOverwrite, ChannelType } from './channel'; +import type { + APIGuildIntegration, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildMFALevel, + GuildVerificationLevel, + IntegrationExpireBehavior, +} from './guild'; +import type { APIRole } from './permissions'; +import type { APIUser } from './user'; +import type { APIWebhook } from './webhook'; + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-object-audit-log-structure + */ +export interface APIAuditLog { + /** + * Webhooks found in the audit log + * + * See https://discord.com/developers/docs/resources/webhook#webhook-object + */ + webhooks: APIWebhook[]; + /** + * Users found in the audit log + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + users: APIUser[]; + /** + * Audit log entries + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object + */ + audit_log_entries: APIAuditLogEntry[]; + /** + * Partial integration objects + * + * See https://discord.com/developers/docs/resources/guild#integration-object + */ + integrations: APIGuildIntegration[]; +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-entry-structure + */ +export interface APIAuditLogEntry { + /** + * ID of the affected entity (webhook, user, role, etc.) + */ + target_id: string | null; + /** + * Changes made to the `target_id` + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-change-object + */ + changes?: APIAuditLogChange[]; + /** + * The user who made the changes + * + * This can be `null` in some cases (webhooks deleting themselves by using their own token, for example) + */ + user_id: Snowflake | null; + /** + * ID of the entry + */ + id: Snowflake; + /** + * Type of action that occurred + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events + */ + action_type: AuditLogEvent; + /** + * Additional info for certain action types + * + * See https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info + */ + options?: APIAuditLogOptions; + /** + * The reason for the change (0-512 characters) + */ + reason?: string; +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events + */ +export const enum AuditLogEvent { + GuildUpdate = 1, + + ChannelCreate = 10, + ChannelUpdate, + ChannelDelete, + ChannelOverwriteCreate, + ChannelOverwriteUpdate, + ChannelOverwriteDelete, + + MemberKick = 20, + MemberPrune, + MemberBanAdd, + MemberBanRemove, + MemberUpdate, + MemberRoleUpdate, + MemberMove, + MemberDisconnect, + BotAdd, + + RoleCreate = 30, + RoleUpdate, + RoleDelete, + + InviteCreate = 40, + InviteUpdate, + InviteDelete, + + WebhookCreate = 50, + WebhookUpdate, + WebhookDelete, + + EmojiCreate = 60, + EmojiUpdate, + EmojiDelete, + + MessageDelete = 72, + MessageBulkDelete, + MessagePin, + MessageUnpin, + + IntegrationCreate = 80, + IntegrationUpdate, + IntegrationDelete, +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-optional-audit-entry-info + */ +export interface APIAuditLogOptions { + /** + * Number of days after which inactive members were kicked + * + * Present from: + * - MEMBER_PRUNE + */ + delete_member_days?: string; + /** + * Number of members removed by the prune + * + * Present from: + * - MEMBER_PRUNE + */ + members_removed?: string; + + /** + * Channel in which the entities were targeted + * + * Present from: + * - MEMBER_MOVE + * - MESSAGE_PIN + * - MESSAGE_UNPIN + * - MESSAGE_DELETE + */ + channel_id?: Snowflake; + + /** + * ID of the message that was targeted + * + * Present from: + * - MESSAGE_PIN + * - MESSAGE_UNPIN + */ + message_id?: Snowflake; + + /** + * Number of entities that were targeted + * + * Present from: + * - MESSAGE_DELETE + * - MESSAGE_BULK_DELETE + * - MEMBER_DISCONNECT + * - MEMBER_MOVE + */ + count?: string; + + /** + * ID of the overwritten entity + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + */ + id?: Snowflake; + + /** + * Type of overwritten entity - "0" for "role" or "1" for "member" + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + * + * {@link AuditLogOptionsType} + */ + type?: AuditLogOptionsType; + + /** + * Name of the role + * + * Present from: + * - CHANNEL_OVERWRITE_CREATE + * - CHANNEL_OVERWRITE_UPDATE + * - CHANNEL_OVERWRITE_DELETE + * + * **Present only if the {@link APIAuditLogOptions#type entry type} is "0"** + */ + role_name?: string; +} + +export const enum AuditLogOptionsType { + Role = '0', + Member = '1', +} + +/** + * https://discord.com/developers/docs/resources/audit-log#audit-log-change-object-audit-log-change-structure + */ +export type APIAuditLogChange = + | APIAuditLogChangeKeyName + | APIAuditLogChangeKeyDescription + | APIAuditLogChangeKeyIconHash + | APIAuditLogChangeKeySplashHash + | APIAuditLogChangeKeyDiscoverySplashHash + | APIAuditLogChangeKeyBannerHash + | APIAuditLogChangeKeyOwnerID + | APIAuditLogChangeKeyRegion + | APIAuditLogChangeKeyPreferredLocale + | APIAuditLogChangeKeyAFKChannelID + | APIAuditLogChangeKeyAFKTimeout + | APIAuditLogChangeKeyRulesChannelID + | APIAuditLogChangeKeyPublicUpdatesChannelID + | APIAuditLogChangeKeyMFALevel + | APIAuditLogChangeKeyVerificationLevel + | APIAuditLogChangeKeyExplicitContentFilter + | APIAuditLogChangeKeyDefaultMessageNotifications + | APIAuditLogChangeKeyVanityURLCode + | APIAuditLogChangeKey$Add + | APIAuditLogChangeKey$Remove + | APIAuditLogChangeKeyPruneDeleteDays + | APIAuditLogChangeKeyWidgetEnabled + | APIAuditLogChangeKeyWidgetChannelID + | APIAuditLogChangeKeySystemChannelID + | APIAuditLogChangeKeyPosition + | APIAuditLogChangeKeyTopic + | APIAuditLogChangeKeyBitrate + | APIAuditLogChangeKeyPermissionOverwrites + | APIAuditLogChangeKeyNSFW + | APIAuditLogChangeKeyApplicationID + | APIAuditLogChangeKeyRateLimitPerUser + | APIAuditLogChangeKeyPermissions + | APIAuditLogChangeKeyColor + | APIAuditLogChangeKeyHoist + | APIAuditLogChangeKeyMentionable + | APIAuditLogChangeKeyAllow + | APIAuditLogChangeKeyDeny + | APIAuditLogChangeKeyCode + | APIAuditLogChangeKeyChannelID + | APIAuditLogChangeKeyInviterID + | APIAuditLogChangeKeyMaxUses + | APIAuditLogChangeKeyUses + | APIAuditLogChangeKeyMaxAge + | APIAuditLogChangeKeyTemporary + | APIAuditLogChangeKeyDeaf + | APIAuditLogChangeKeyMute + | APIAuditLogChangeKeyNick + | APIAuditLogChangeKeyAvatarHash + | APIAuditLogChangeKeyID + | APIAuditLogChangeKeyType + | APIAuditLogChangeKeyEnableEmoticons + | APIAuditLogChangeKeyExpireBehavior + | APIAuditLogChangeKeyExpireGracePeriod + | APIAuditLogChangeKeyUserLimit; + +/** + * Returned when a guild's name is changed + */ +export type APIAuditLogChangeKeyName = AuditLogChangeData<'name', string>; + +/** + * Returned when a guild's description is changed + */ +export type APIAuditLogChangeKeyDescription = AuditLogChangeData<'description', string>; + +/** + * Returned when a guild's icon is changed + */ +export type APIAuditLogChangeKeyIconHash = AuditLogChangeData<'icon_hash', string>; + +/** + * Returned when a guild's splash is changed + */ +export type APIAuditLogChangeKeySplashHash = AuditLogChangeData<'splash_hash', string>; + +/** + * Returned when a guild's discovery splash is changed + */ +export type APIAuditLogChangeKeyDiscoverySplashHash = AuditLogChangeData<'discovery_splash_hash', string>; + +/** + * Returned when a guild's banner hash is changed + */ +export type APIAuditLogChangeKeyBannerHash = AuditLogChangeData<'banner_hash', string>; + +/** + * Returned when a guild's owner_id is changed + */ +export type APIAuditLogChangeKeyOwnerID = AuditLogChangeData<'owner_id', Snowflake>; + +/** + * Returned when a guild's region is changed + */ +export type APIAuditLogChangeKeyRegion = AuditLogChangeData<'region', string>; + +/** + * Returned when a guild's preferred_locale is changed + */ +export type APIAuditLogChangeKeyPreferredLocale = AuditLogChangeData<'preferred_locale', string>; + +/** + * Returned when a guild's afk_channel_id is changed + */ +export type APIAuditLogChangeKeyAFKChannelID = AuditLogChangeData<'afk_channel_id', Snowflake>; + +/** + * Returned when a guild's afk_timeout is changed + */ +export type APIAuditLogChangeKeyAFKTimeout = AuditLogChangeData<'afk_timeout', number>; + +/** + * Returned when a guild's rules_channel_id is changed + */ +export type APIAuditLogChangeKeyRulesChannelID = AuditLogChangeData<'rules_channel_id', string>; + +/** + * Returned when a guild's public_updates_channel_id is changed + */ +export type APIAuditLogChangeKeyPublicUpdatesChannelID = AuditLogChangeData<'public_updates_channel_id', string>; + +/** + * Returned when a guild's mfa_level is changed + */ +export type APIAuditLogChangeKeyMFALevel = AuditLogChangeData<'mfa_level', GuildMFALevel>; + +/** + * Returned when a guild's verification_level is changed + */ +export type APIAuditLogChangeKeyVerificationLevel = AuditLogChangeData<'verification_level', GuildVerificationLevel>; + +/** + * Returned when a guild's explicit_content_filter is changed + */ +export type APIAuditLogChangeKeyExplicitContentFilter = AuditLogChangeData< + 'explicit_content_filter', + GuildExplicitContentFilter +>; + +/** + * Returned when a guild's default_message_notifications is changed + */ +export type APIAuditLogChangeKeyDefaultMessageNotifications = AuditLogChangeData< + 'default_message_notifications', + GuildDefaultMessageNotifications +>; + +/** + * Returned when a guild's vanity_url_code is changed + */ +export type APIAuditLogChangeKeyVanityURLCode = AuditLogChangeData<'vanity_url_code', string>; + +/** + * Returned when new role(s) are added + */ +export type APIAuditLogChangeKey$Add = AuditLogChangeData<'$add', APIRole[]>; + +/** + * Returned when role(s) are removed + */ +export type APIAuditLogChangeKey$Remove = AuditLogChangeData<'$remove', APIRole[]>; + +/** + * Returned when there is a change in number of days after which inactive and role-unassigned members are kicked + */ +export type APIAuditLogChangeKeyPruneDeleteDays = AuditLogChangeData<'prune_delete_days', number>; + +/** + * Returned when a guild's widget is enabled + */ +export type APIAuditLogChangeKeyWidgetEnabled = AuditLogChangeData<'widget_enabled', boolean>; + +/** + * Returned when a guild's widget_channel_id is changed + */ +export type APIAuditLogChangeKeyWidgetChannelID = AuditLogChangeData<'widget_channel_id', Snowflake>; + +/** + * Returned when a guild's system_channel_id is changed + */ +export type APIAuditLogChangeKeySystemChannelID = AuditLogChangeData<'system_channel_id', Snowflake>; + +/** + * Returned when a channel's position is changed + */ +export type APIAuditLogChangeKeyPosition = AuditLogChangeData<'position', number>; + +/** + * Returned when a channel's topic is changed + */ +export type APIAuditLogChangeKeyTopic = AuditLogChangeData<'topic', string>; + +/** + * Returned when a voice channel's bitrate is changed + */ +export type APIAuditLogChangeKeyBitrate = AuditLogChangeData<'bitrate', number>; + +/** + * Returned when a channel's permission overwrites is changed + */ +export type APIAuditLogChangeKeyPermissionOverwrites = AuditLogChangeData<'permission_overwrites', APIOverwrite[]>; + +/** + * Returned when a channel's NSFW restriction is changed + */ +export type APIAuditLogChangeKeyNSFW = AuditLogChangeData<'nsfw', boolean>; + +/** + * The application ID of the added or removed Webhook or Bot + */ +export type APIAuditLogChangeKeyApplicationID = AuditLogChangeData<'application_id', Snowflake>; + +/** + * Returned when a channel's amount of seconds a user has to wait before sending another message + * is changed + */ +export type APIAuditLogChangeKeyRateLimitPerUser = AuditLogChangeData<'rate_limit_per_user', number>; + +/** + * Returned when a permission bitfield is changed + */ +export type APIAuditLogChangeKeyPermissions = AuditLogChangeData<'permissions', string>; + +/** + * Returned when a role's color is changed + */ +export type APIAuditLogChangeKeyColor = AuditLogChangeData<'color', number>; + +/** + * Returned when a role's hoist status is changed + */ +export type APIAuditLogChangeKeyHoist = AuditLogChangeData<'hoist', boolean>; + +/** + * Returned when a role's mentionable status is changed + */ +export type APIAuditLogChangeKeyMentionable = AuditLogChangeData<'mentionable', boolean>; + +/** + * Returned when an overwrite's allowed permissions bitfield is changed + */ +export type APIAuditLogChangeKeyAllow = AuditLogChangeData<'allow', string>; + +/** + * Returned when an overwrite's denied permissions bitfield is changed + */ +export type APIAuditLogChangeKeyDeny = AuditLogChangeData<'deny', string>; + +/** + * Returned when an invite's code is changed + */ +export type APIAuditLogChangeKeyCode = AuditLogChangeData<'code', string>; + +/** + * Returned when an invite's channel_id is changed + */ +export type APIAuditLogChangeKeyChannelID = AuditLogChangeData<'channel_id', Snowflake>; + +/** + * Returned when an invite's inviter_id is changed + */ +export type APIAuditLogChangeKeyInviterID = AuditLogChangeData<'inviter_id', Snowflake>; + +/** + * Returned when an invite's max_uses is changed + */ +export type APIAuditLogChangeKeyMaxUses = AuditLogChangeData<'max_uses', number>; + +/** + * Returned when an invite's uses is changed + */ +export type APIAuditLogChangeKeyUses = AuditLogChangeData<'uses', number>; + +/** + * Returned when an invite's max_age is changed + */ +export type APIAuditLogChangeKeyMaxAge = AuditLogChangeData<'max_age', number>; + +/** + * Returned when an invite's temporary status is changed + */ +export type APIAuditLogChangeKeyTemporary = AuditLogChangeData<'temporary', boolean>; + +/** + * Returned when a user's deaf status is changed + */ +export type APIAuditLogChangeKeyDeaf = AuditLogChangeData<'deaf', boolean>; + +/** + * Returned when a user's mute status is changed + */ +export type APIAuditLogChangeKeyMute = AuditLogChangeData<'mute', boolean>; + +/** + * Returned when a user's nick is changed + */ +export type APIAuditLogChangeKeyNick = AuditLogChangeData<'mute', boolean>; + +/** + * Returned when a user's avatar_hash is changed + */ +export type APIAuditLogChangeKeyAvatarHash = AuditLogChangeData<'avatar_hash', string>; + +/** + * The ID of the changed entity - sometimes used in conjunction with other keys + */ +export type APIAuditLogChangeKeyID = AuditLogChangeData<'id', Snowflake>; + +/** + * The type of entity created + */ +export type APIAuditLogChangeKeyType = AuditLogChangeData<'type', ChannelType | string>; + +/** + * Returned when an integration's enable_emoticons is changed + */ +export type APIAuditLogChangeKeyEnableEmoticons = AuditLogChangeData<'enable_emoticons', boolean>; + +/** + * Returned when an integration's expire_behavior is changed + */ +export type APIAuditLogChangeKeyExpireBehavior = AuditLogChangeData<'expire_behavior', IntegrationExpireBehavior>; + +/** + * Returned when an integration's expire_grace_period is changed + */ +export type APIAuditLogChangeKeyExpireGracePeriod = AuditLogChangeData<'expire_grace_period', number>; + +/** + * Returned when a voice channel's user_limit is changed + */ +export type APIAuditLogChangeKeyUserLimit = AuditLogChangeData<'user_limit', number>; + +interface AuditLogChangeData { + key: K; + /** + * The new value + * + * If `new_value` is not present in the change object, while `old_value` is, + * that means the property that was changed has been reset, or set to `null` + */ + new_value?: D; + old_value?: D; +} diff --git a/payloads/v9/channel.ts b/payloads/v9/channel.ts new file mode 100644 index 00000000..696496f2 --- /dev/null +++ b/payloads/v9/channel.ts @@ -0,0 +1,1048 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/channel + */ + +import type { Permissions, Snowflake } from '../../globals'; +import type { APIPartialEmoji } from './emoji'; +import type { APIGuildMember } from './guild'; +import type { APIMessageInteraction } from './interactions'; +import { APIApplication } from './oauth2'; +import type { APIRole } from './permissions'; +import type { APIUser } from './user'; + +/** + * Not documented, but partial only includes id, name, and type + */ +export interface APIPartialChannel { + /** + * The id of the channel + */ + id: Snowflake; + /** + * The type of the channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ + type: ChannelType; + /** + * The name of the channel (2-100 characters) + */ + name?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object-channel-structure + */ +export interface APIChannel extends APIPartialChannel { + /** + * The id of the guild (may be missing for some channel objects received over gateway guild dispatches) + */ + guild_id?: Snowflake; + /** + * Sorting position of the channel + */ + position?: number; + /** + * Explicit permission overwrites for members and roles + * + * See https://discord.com/developers/docs/resources/channel#overwrite-object + */ + permission_overwrites?: APIOverwrite[]; + /** + * The channel topic (0-1024 characters) + */ + topic?: string | null; + /** + * Whether the channel is nsfw + */ + nsfw?: boolean; + /** + * The id of the last message sent in this channel (may not point to an existing or valid message) + */ + last_message_id?: Snowflake | null; + /** + * The bitrate (in bits) of the voice channel + */ + bitrate?: number; + /** + * The user limit of the voice channel + */ + 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_CHANNELS`, are unaffected + */ + rate_limit_per_user?: number; + /** + * The recipients of the DM + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + recipients?: APIUser[]; + /** + * Icon hash + */ + icon?: string | null; + /** + * ID of the DM creator or thread creator + */ + owner_id?: Snowflake; + /** + * Application id of the group DM creator if it is bot-created + */ + application_id?: Snowflake; + /** + * ID of the parent category for a channel (each parent category can contain up to 50 channels) + * + * OR + * + * ID of the parent channel for a thread + */ + parent_id?: Snowflake | null; + /** + * When the last pinned message was pinned. + * This may be `null` in events such as `GUILD_CREATE` when a message is not pinned + */ + last_pin_timestamp?: string | null; + /** + * Voice region id for the voice or stage channel, automatic when set to `null` + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + rtc_region?: string | null; + /** + * The camera video quality mode of the voice channel, `1` when not present + * + * See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes + */ + video_quality_mode?: VideoQualityMode; + /** + * The approximate message count of the thread, does not count above 50 even if there are more messages + */ + message_count?: number; + /** + * The approximate member count of the thread, does not count above 50 even if there are more members + */ + member_count?: number; + /** + * The metadata for a thread channel not shared by other channels + */ + thread_metadata?: APIThreadMetadata; + /** + * The client users member for the thread, only included in select endpoints + */ + member?: APIThreadMember; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ +export const enum ChannelType { + /** + * A text channel within a guild + */ + GuildText, + /** + * A direct message between users + */ + DM, + /** + * A voice channel within a guild + */ + GuildVoice, + /** + * A direct message between multiple users + */ + GroupDM, + /** + * An organizational category that contains up to 50 channels + * + * See https://support.discord.com/hc/en-us/articles/115001580171-Channel-Categories-101 + */ + GuildCategory, + /** + * A channel that users can follow and crosspost into their own guild + * + * See https://support.discord.com/hc/en-us/articles/360032008192 + */ + GuildNews, + /** + * A channel in which game developers can sell their game on Discord + * + * See https://discord.com/developers/docs/game-and-server-management/special-channels + */ + GuildStore, + /** + * A thread channel (public) within a Guild News channel + */ + GuildNewsThread = 10, + /** + * A public thread channel within a Guild Text channel + */ + GuildPublicThread, + /** + * A private thread channel within a Guild Text channel + */ + GuildPrivateThread, + /** + * A voice channel for hosting events with an audience + * + * See https://support.discord.com/hc/en-us/articles/1500005513722 + */ + GuildStageVoice, +} + +export const enum VideoQualityMode { + /** + * Discord chooses the quality for optimal performance + */ + Auto = 1, + /** + * 720p + */ + Full, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-structure + */ +export interface APIMessage { + /** + * ID of the message + */ + id: Snowflake; + /** + * ID of the channel the message was sent in + */ + channel_id: Snowflake; + /** + * ID of the guild the message was sent in + */ + guild_id?: Snowflake; + /** + * The author of this message (only a valid user in the case where the message is generated by a user or bot user) + * + * If the message is generated by a webhook, the author object corresponds to the webhook's id, + * username, and avatar. You can tell if a message is generated by a webhook by checking for the `webhook_id` property + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + author: APIUser; + /** + * Member properties for this message's author + * + * The member object exists in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events + * from text-based guild channels + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * Contents of the message + */ + content: string; + /** + * When this message was sent + */ + timestamp: string; + /** + * When this message was edited (or null if never) + */ + edited_timestamp: string | null; + /** + * Whether this was a TTS message + */ + tts: boolean; + /** + * Whether this message mentions everyone + */ + mention_everyone: boolean; + /** + * Users specifically mentioned in the message + * + * The `member` field is only present in `MESSAGE_CREATE` and `MESSAGE_UPDATE` events + * from text-based guild channels + * + * See https://discord.com/developers/docs/resources/user#user-object + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + mentions: (APIUser & { member?: Omit })[]; + /** + * Roles specifically mentioned in this message + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + mention_roles: APIRole['id'][]; + /** + * Channels specifically mentioned in this message + * + * Not all channel mentions in a message will appear in `mention_channels`. + * - Only textual channels that are visible to everyone in a lurkable guild will ever be included + * - Only crossposted messages (via Channel Following) currently include `mention_channels` at all + * + * If no mentions in the message meet these requirements, this field will not be sent + * + * See https://discord.com/developers/docs/resources/channel#channel-mention-object + */ + mention_channels?: APIChannelMention[]; + /** + * Any attached files + * + * See https://discord.com/developers/docs/resources/channel#attachment-object + */ + attachments: APIAttachment[]; + /** + * Any embedded content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embeds: APIEmbed[]; + /** + * Reactions to the message + * + * See https://discord.com/developers/docs/resources/channel#reaction-object + */ + reactions?: APIReaction[]; + /** + * A nonce that can be used for optimistic message sending (up to 25 characters) + * + * **You will not receive this from further fetches. This is received only once from a `MESSAGE_CREATE` + * event to ensure it got sent** + */ + nonce?: string | number; + /** + * Whether this message is pinned + */ + pinned: boolean; + /** + * If the message is generated by a webhook, this is the webhook's id + */ + webhook_id?: Snowflake; + /** + * Type of message + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-types + */ + type: MessageType; + /** + * Sent with Rich Presence-related chat embeds + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-activity-structure + */ + activity?: APIMessageActivity; + /** + * Sent with Rich Presence-related chat embeds + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-application-structure + */ + application?: Partial; + /** + * Reference data sent with crossposted messages, replies, pins, and thread starter messages + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ + message_reference?: APIMessageReference; + /** + * Message flags combined as a bitfield + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags?: MessageFlags; + /** + * The stickers sent with the message (bots currently can only receive messages with stickers, not send) + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-sticker-structure + */ + stickers?: APISticker[]; + /** + * The message associated with the `message_reference` + * + * This field is only returned for messages with a `type` of `19` (REPLY). + * + * If the message is a reply but the `referenced_message` field is not present, + * the backend did not attempt to fetch the message that was being replied to, + * so its state is unknown. + * + * If the field exists but is `null`, the referenced message was deleted + * + * See https://discord.com/developers/docs/resources/channel#message-object + */ + referenced_message?: APIMessage | null; + /** + * Sent if the message is a response to an Interaction + */ + interaction?: APIMessageInteraction; + /** + * Sent if a thread was started from this message + */ + thread?: APIChannel; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-types + */ +export const enum MessageType { + Default, + RecipientAdd, + RecipientRemove, + Call, + ChannelNameChange, + ChannelIconChange, + ChannelPinnedMessage, + GuildMemberJoin, + UserPremiumGuildSubscription, + UserPremiumGuildSubscriptionTier1, + UserPremiumGuildSubscriptionTier2, + UserPremiumGuildSubscriptionTier3, + ChannelFollowAdd, + GuildDiscoveryDisqualified = 14, + GuildDiscoveryRequalified, + GuildDiscoveryGracePeriodInitialWarning, + GuildDiscoveryGracePeriodFinalWarning, + ThreadCreated, + Reply, + ApplicationCommand, + ThreadStarterMessage, + GuildInviteReminder, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-activity-structure + */ +export interface APIMessageActivity { + /** + * Type of message activity + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-activity-types + */ + type: MessageActivityType; + /** + * `party_id` from a Rich Presence event + * + * See https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields + */ + party_id?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ +export interface APIMessageReference { + /** + * ID of the originating message + */ + message_id?: Snowflake; + /** + * ID of the originating message's channel + */ + channel_id: Snowflake; + /** + * ID of the originating message's guild + */ + guild_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-activity-types + */ +export const enum MessageActivityType { + Join = 1, + Spectate, + Listen, + JoinRequest = 5, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-flags + */ +export const enum MessageFlags { + /** + * This message has been published to subscribed channels (via Channel Following) + */ + Crossposted = 1 << 0, + /** + * This message originated from a message in another channel (via Channel Following) + */ + IsCrosspost = 1 << 1, + /** + * Do not include any embeds when serializing this message + */ + SuppressEmbeds = 1 << 2, + /** + * The source message for this crosspost has been deleted (via Channel Following) + */ + SourceMessageDeleted = 1 << 3, + /** + * This message came from the urgent message system + */ + Urgent = 1 << 4, + /** + * This message has an associated thread, which shares its id + */ + HasThread = 1 << 5, + /** + * This message is only visible to the user who invoked the Interaction + */ + Ephemeral = 1 << 6, + /** + * This message is an Interaction Response and the bot is "thinking" + */ + Loading = 1 << 7, +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-sticker-structure + */ +export interface APISticker { + /** + * ID of the sticker + */ + id: Snowflake; + /** + * ID of the pack the sticker is from + */ + pack_id: Snowflake; + /** + * Name of the sticker + */ + name: string; + /** + * Description of the sticker + */ + description: string; + /** + * A comma-separated list of tags for the sticker + */ + tags?: string; + /** + * Sticker asset hash + */ + asset: string; + /** + * Type of sticker format + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-sticker-format-types + */ + format_type: StickerFormatType; +} + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-sticker-format-types + */ +export const enum StickerFormatType { + PNG = 1, + APNG, + LOTTIE, +} + +/** + * https://discord.com/developers/docs/resources/channel#followed-channel-object + */ +export interface APIFollowedChannel { + /** + * Source channel id + */ + channel_id: Snowflake; + /** + * Created target webhook id + */ + webhook_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#reaction-object-reaction-structure + */ +export interface APIReaction { + /** + * Times this emoji has been used to react + */ + count: number; + /** + * Whether the current user reacted using this emoji + */ + me: boolean; + /** + * Emoji information + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emoji: APIPartialEmoji; +} + +/** + * https://discord.com/developers/docs/resources/channel#overwrite-object-overwrite-structure + */ +export interface APIOverwrite { + /** + * Role or user id + */ + id: Snowflake; + /** + * Either 0 (role) or 1 (member) + * + * {@link OverwriteType} + */ + type: OverwriteType; + /** + * Permission bit set + * + * See https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + allow: Permissions; + /** + * Permission bit set + * + * See https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + deny: Permissions; +} + +export const enum OverwriteType { + Role, + Member, +} + +/** + * https://discord.com/developers/docs/resources/channel#thread-metadata-object-thread-metadata-structure + */ +export interface APIThreadMetadata { + /** + * Whether the thread is archived + */ + archived: boolean; + /** + * ID of the user that last archived or unarchived the thread + */ + archiver_id?: Snowflake; + /** + * Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080 + */ + auto_archive_duration: ThreadAutoArchiveDuration; + /** + * An ISO8601 timestamp when the thread's archive status was last changed, used for calculating recent activity + */ + archive_timestamp: string; + /** + * When a thread is locked, only users with MANAGE_THREADS can unarchive it + */ + locked?: boolean; +} + +export const enum ThreadAutoArchiveDuration { + OneHour = 60, + OneDay = 1440, + ThreeDays = 4320, + OneWeek = 10080, +} + +/** + * https://discord.com/developers/docs/resources/channel#thread-member-object-thread-member-structure + */ +export interface APIThreadMember { + /** + * The id of the thread + */ + id: Snowflake; + /** + * The id of the member + */ + user_id: Snowflake; + /** + * An ISO8601 timestamp for when the member last joined + */ + join_timestamp: string; + /** + * Member flags combined as a bitfield + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags: ThreadMemberFlags; +} + +export const enum ThreadMemberFlags {} + +export interface APIThreadList { + /** + * The threads that were fetched + */ + threads: APIChannel[]; + /** + * The members for the client user in each of the fetched threads + */ + members: APIThreadMember[]; + /** + * Whether there are potentially additional threads + */ + has_more?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-structure + * + * Length limit: 6000 characters + */ +export interface APIEmbed { + /** + * Title of embed + * + * Length limit: 256 characters + */ + title?: string; + /** + * Type of embed (always "rich" for webhook embeds) + * + * @deprecated *Embed types should be considered deprecated and might be removed in a future API version* + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-types + */ + type?: EmbedType; + /** + * Description of embed + * + * Length limit: 2048 characters + */ + description?: string; + /** + * URL of embed + */ + url?: string; + /** + * Timestamp of embed content + */ + timestamp?: string; + /** + * Color code of the embed + */ + color?: number; + /** + * Footer information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure + */ + footer?: APIEmbedFooter; + /** + * Image information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure + */ + image?: APIEmbedImage; + /** + * Thumbnail information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure + */ + thumbnail?: APIEmbedThumbnail; + /** + * Video information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure + */ + video?: APIEmbedVideo; + /** + * Provider information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure + */ + provider?: APIEmbedProvider; + /** + * Author information + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure + */ + author?: APIEmbedAuthor; + /** + * Fields information + * + * Length limit: 25 field objects + * + * See https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure + */ + fields?: APIEmbedField[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-types + * @deprecated *Embed types should be considered deprecated and might be removed in a future API version* + */ +export const enum EmbedType { + /** + * Generic embed rendered from embed attributes + */ + Rich = 'rich', + /** + * Image embed + */ + Image = 'image', + /** + * Video embed + */ + Video = 'video', + /** + * Animated gif image embed rendered as a video embed + */ + GIFV = 'gifv', + /** + * Article embed + */ + Article = 'article', + /** + * Link embed + */ + Link = 'link', +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-thumbnail-structure + */ +export interface APIEmbedThumbnail { + /** + * Source url of thumbnail (only supports http(s) and attachments) + */ + url?: string; + /** + * A proxied url of the thumbnail + */ + proxy_url?: string; + /** + * Height of thumbnail + */ + height?: number; + /** + * Width of thumbnail + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-video-structure + */ +export interface APIEmbedVideo { + /** + * Source url of video + */ + url?: string; + /** + * Height of video + */ + height?: number; + /** + * Width of video + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure + */ +export interface APIEmbedImage { + /** + * Source url of image (only supports http(s) and attachments) + */ + url?: string; + /** + * A proxied url of the image + */ + proxy_url?: string; + /** + * Height of image + */ + height?: number; + /** + * Width of image + */ + width?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-provider-structure + */ +export interface APIEmbedProvider { + /** + * Name of provider + */ + name?: string; + /** + * URL of provider + */ + url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure + */ +export interface APIEmbedAuthor { + /** + * Name of author + * + * Length limit: 256 characters + */ + name?: string; + /** + * URL of author + */ + url?: string; + /** + * URL of author icon (only supports http(s) and attachments) + */ + icon_url?: string; + /** + * A proxied url of author icon + */ + proxy_icon_url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure + */ +export interface APIEmbedFooter { + /** + * Footer text + * + * Length limit: 2048 characters + */ + text: string; + /** + * URL of footer icon (only supports http(s) and attachments) + */ + icon_url?: string; + /** + * A proxied url of footer icon + */ + proxy_icon_url?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure + */ +export interface APIEmbedField { + /** + * Name of the field + * + * Length limit: 256 characters + */ + name: string; + /** + * Value of the field + * + * Length limit: 1024 characters + */ + value: string; + /** + * Whether or not this field should display inline + */ + inline?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#attachment-object-attachment-structure + */ +export interface APIAttachment { + /** + * Attachment id + */ + id: Snowflake; + /** + * Name of file attached + */ + filename: string; + /** + * The attachment's media type + * + * See https://en.wikipedia.org/wiki/Media_type + */ + content_type?: string; + /** + * Size of file in bytes + */ + size: number; + /** + * Source url of file + */ + url: string; + /** + * A proxied url of file + */ + proxy_url: string; + /** + * Height of file (if image) + */ + height?: number | null; + /** + * Width of file (if image) + */ + width?: number | null; +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-mention-object-channel-mention-structure + */ +export interface APIChannelMention { + /** + * ID of the channel + */ + id: Snowflake; + /** + * ID of the guild containing the channel + */ + guild_id: Snowflake; + /** + * The type of channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-channel-types + */ + type: ChannelType; + /** + * The name of the channel + */ + name: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types + */ +export const enum AllowedMentionsTypes { + /** + * Controls @everyone and @here mentions + */ + Everyone = 'everyone', + /** + * Controls role mentions + */ + Role = 'roles', + /** + * Controls user mentions + */ + User = 'users', +} + +/** + * https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mentions-structure + */ +export interface APIAllowedMentions { + /** + * An array of allowed mention types to parse from the content + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object-allowed-mention-types + */ + parse?: AllowedMentionsTypes[]; + /** + * Array of role_ids to mention (Max size of 100) + */ + roles?: Snowflake[]; + /** + * Array of user_ids to mention (Max size of 100) + */ + users?: Snowflake[]; + /** + * For replies, whether to mention the author of the message being replied to (default false) + * + * @default false + */ + replied_user?: boolean; +} diff --git a/payloads/v9/emoji.ts b/payloads/v9/emoji.ts new file mode 100644 index 00000000..3db04800 --- /dev/null +++ b/payloads/v9/emoji.ts @@ -0,0 +1,51 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/emoji + */ + +import type { Snowflake } from '../../globals'; +import type { APIRole } from './permissions'; +import type { APIUser } from './user'; + +/** + * Not documented but mentioned + */ +export interface APIPartialEmoji { + /** + * Emoji id + */ + id: Snowflake | null; + /** + * Emoji name (can be null only in reaction emoji objects) + */ + name: string | null; + /** + * Whether this emoji is animated + */ + animated?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/emoji#emoji-object-emoji-structure + */ +export interface APIEmoji extends APIPartialEmoji { + /** + * Roles this emoji is whitelisted to + */ + roles?: APIRole['id'][]; + /** + * User that created this emoji + */ + user?: APIUser; + /** + * Whether this emoji must be wrapped in colons + */ + require_colons?: boolean; + /** + * Whether this emoji is managed + */ + managed?: boolean; + /** + * Whether this emoji can be used, may be false due to loss of Server Boosts + */ + available?: boolean; +} diff --git a/payloads/v9/gateway.ts b/payloads/v9/gateway.ts new file mode 100644 index 00000000..4b1b170f --- /dev/null +++ b/payloads/v9/gateway.ts @@ -0,0 +1,363 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/gateway + */ + +import type { Snowflake } from '../../globals'; +import type { APIChannel, APIThreadMember } from './channel'; +import type { APIEmoji } from './emoji'; +import type { APIUser } from './user'; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway + */ +export interface APIGatewayInfo { + /** + * The WSS URL that can be used for connecting to the gateway + */ + url: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway-bot + */ +export interface APIGatewayBotInfo extends APIGatewayInfo { + /** + * The recommended number of shards to use when connecting + * + * See https://discord.com/developers/docs/topics/gateway#sharding + */ + shards: number; + /** + * Information on the current session start limit + * + * See https://discord.com/developers/docs/topics/gateway#session-start-limit-object + */ + session_start_limit: APIGatewaySessionStartLimit; +} + +/** + * https://discord.com/developers/docs/topics/gateway#session-start-limit-object + */ +export interface APIGatewaySessionStartLimit { + /** + * The total number of session starts the current user is allowed + */ + total: number; + /** + * The remaining number of session starts the current user is allowed + */ + remaining: number; + /** + * The number of milliseconds after which the limit resets + */ + reset_after: number; + /** + * The number of identify requests allowed per 5 seconds + */ + max_concurrency: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#presence-update-presence-update-event-fields + */ +export interface GatewayPresenceUpdate { + /** + * The user presence is being updated for + * + * **The user object within this event can be partial, the only field which must be sent is the `id` field, + * everything else is optional.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: Partial & Pick; + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * Either "idle", "dnd", "online", or "offline" + */ + status?: PresenceUpdateStatus; + /** + * User's current activities + * + * See https://discord.com/developers/docs/topics/gateway#activity-object + */ + activities?: GatewayActivity[]; + /** + * User's platform-dependent status + * + * See https://discord.com/developers/docs/topics/gateway#client-status-object + */ + client_status?: GatewayPresenceClientStatus; +} + +export const enum PresenceUpdateStatus { + Online = 'online', + DoNotDisturb = 'dnd', + Idle = 'idle', + /** + * Invisible and shown as offline + */ + Invisible = 'invisible', + Offline = 'offline', +} + +/** + * https://discord.com/developers/docs/topics/gateway#client-status-object + */ +export interface GatewayPresenceClientStatus { + /** + * The user's status set for an active desktop (Windows, Linux, Mac) application session + */ + desktop?: PresenceUpdateStatus; + /** + * The user's status set for an active mobile (iOS, Android) application session + */ + mobile?: PresenceUpdateStatus; + /** + * The user's status set for an active web (browser, bot account) application session + */ + web?: PresenceUpdateStatus; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-structure + */ +export interface GatewayActivity { + /** + * The activity's id + */ + id: string; + /** + * The activity's name + */ + name: string; + /** + * Activity type + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-types + */ + type: ActivityType; + /** + * Stream url, is validated when type is `1` + */ + url?: string | null; + /** + * Unix timestamp of when the activity was added to the user's session + */ + created_at: number; + /** + * Unix timestamps for start and/or end of the game + */ + timestamps?: GatewayActivityTimestamps; + sync_id?: string; + platform?: ActivityPlatform; + /** + * Application id for the game + */ + application_id?: Snowflake; + /** + * What the player is currently doing + */ + details?: string | null; + /** + * The user's current party status + */ + state?: string | null; + /** + * The emoji used for a custom status + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji + */ + emoji?: GatewayActivityEmoji; + session_id?: string; + /** + * Information for the current party of the player + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-party + */ + party?: GatewayActivityParty; + /** + * Images for the presence and their hover texts + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets + */ + assets?: GatewayActivityAssets; + /** + * Secrets for Rich Presence joining and spectating + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets + */ + secrets?: GatewayActivitySecrets; + /** + * Whether or not the activity is an instanced game session + */ + instance?: boolean; + /** + * Activity flags `OR`d together, describes what the payload includes + * + * See https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + flags?: ActivityFlags; + /** + * The custom buttons shown in the Rich Presence (max 2) + */ + buttons?: string[] | GatewayActivityButton[]; +} + +export enum ActivityPlatform { + Desktop = 'desktop', + Samsung = 'samsung', + Xbox = 'xbox', +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-types + */ +export const enum ActivityType { + /** + * Playing {game} + */ + Game, + /** + * Streaming {details} + */ + Streaming, + /** + * Listening to {name} + */ + Listening, + /** + * Watching {details} + */ + Watching, + /** + * {emoji} {details} + */ + Custom, + /** + * Competing in {name} + */ + Competing, +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-timestamps + */ +export interface GatewayActivityTimestamps { + /** + * Unix time (in milliseconds) of when the activity started + */ + start?: number; + /** + * Unix time (in milliseconds) of when the activity ends + */ + end?: number; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji + */ +export type GatewayActivityEmoji = Partial> & Pick; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-party + */ +export interface GatewayActivityParty { + /** + * The id of the party + */ + id?: string; + /** + * Used to show the party's current and maximum size + */ + size?: [current_size: number, max_size: number]; +} + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets + */ +export type GatewayActivityAssets = Partial< + Record<'large_image' | 'large_text' | 'small_image' | 'small_text', string> +>; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets + */ +export type GatewayActivitySecrets = Partial>; + +/** + * https://discord.com/developers/docs/topics/gateway#activity-object-activity-flags + */ +export const enum ActivityFlags { + Instance = 1 << 0, + Join = 1 << 1, + Spectate = 1 << 2, + JoinRequest = 1 << 3, + Sync = 1 << 4, + Play = 1 << 5, +} + +export interface GatewayActivityButton { + /** + * The text shown on the button (1-32 characters) + */ + label: string; + /** + * The url opened when clicking the button (1-512 characters) + */ + url: string; +} + +/** + * https://discord.com/developers/docs/topics/gateway#thread-list-sync-thread-list-sync-event-fields + */ +export interface GatewayThreadListSync { + /** + * ID of the guild + */ + guild_id: Snowflake; + /** + * The ids of all the parent channels whose threads are being synced, otherwise the entire guild + */ + channel_ids?: Snowflake[]; + /** + * Array of the synced threads + */ + threads: APIChannel[]; + /** + * The member objects for the client user in each joined thread that was synced + */ + members: Record; +} + +export type GatewayThreadListSyncMember = Omit; + +/** + * https://discord.com/developers/docs/topics/gateway#thread-members-update-thread-members-update-event-fields + */ +export interface GatewayThreadMembersUpdate { + /** + * The id of the thread for which members are being synced + */ + id: Snowflake; + /** + * The id of the guild that the thread is in + */ + guild_id: Snowflake; + /** + * The approximate member count of the thread, does not count above 50 even if there are more members + */ + member_count: number; + /** + * The members that were added to the thread + */ + added_members?: APIThreadMember[]; + /** + * The ids of the members that were removed from the thread + */ + removed_member_ids?: Snowflake[]; +} diff --git a/payloads/v9/guild.ts b/payloads/v9/guild.ts new file mode 100644 index 00000000..4b3c30d9 --- /dev/null +++ b/payloads/v9/guild.ts @@ -0,0 +1,884 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/guild + */ + +import type { Permissions, Snowflake } from '../../globals'; +import type { APIChannel } from './channel'; +import type { APIEmoji } from './emoji'; +import type { GatewayPresenceUpdate, PresenceUpdateStatus } from './gateway'; +import type { APIRole } from './permissions'; +import type { APIUser } from './user'; +import type { GatewayVoiceState } from './voice'; + +/** + * https://discord.com/developers/docs/resources/guild#unavailable-guild-object + */ +export interface APIUnavailableGuild { + /** + * Guild id + */ + id: Snowflake; + /** + * `true` if this guild is unavailable due to an outage + */ + unavailable: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-structure + */ +export interface APIPartialGuild extends Omit, Pick { + /** + * Guild name (2-100 characters, excluding trailing and leading whitespace) + */ + name: string; + /** + * Icon hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * Splash hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + splash: string | null; + /** + * Banner hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + banner?: string | null; + /** + * The description for the guild, if the guild is discoverable + */ + description?: string | null; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features?: GuildFeature[]; + /** + * Verification level required for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel; + /** + * The vanity url code for the guild + */ + vanity_url_code?: string | null; + /** + * `true` if this guild is unavailable due to an outage + */ + unavailable?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-structure + */ +export interface APIGuild extends APIPartialGuild { + /** + * Icon hash, returned when in the template object + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon_hash?: string | null; + /** + * Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + discovery_splash: string | null; + /** + * `true` if the user is the owner of the guild + * + * **This field is only received from https://discord.com/developers/docs/resources/user#get-current-user-guilds** + */ + owner?: boolean; + /** + * ID of owner + */ + owner_id: Snowflake; + /** + * Total permissions for the user in the guild (excludes overrides) + * + * **This field is only received from https://discord.com/developers/docs/resources/user#get-current-user-guilds** + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + permissions?: Permissions; + /** + * Voice region id for the guild + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + * @deprecated This field has been deprecated in favor of `rtc_region` on the channel. + */ + region: string; + /** + * ID of afk channel + */ + afk_channel_id: Snowflake | null; + /** + * afk timeout in seconds + */ + afk_timeout: number; + /** + * `true` if the guild widget is enabled + */ + widget_enabled?: boolean; + /** + * The channel id that the widget will generate an invite to, or `null` if set to no invite + */ + widget_channel_id?: Snowflake | null; + /** + * Verification level required for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level: GuildVerificationLevel; + /** + * Default message notifications level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications: GuildDefaultMessageNotifications; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter: GuildExplicitContentFilter; + /** + * Roles in the guild + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles: APIRole[]; + /** + * Custom guild emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features: GuildFeature[]; + /** + * Required MFA level for the guild + * + * See https://discord.com/developers/docs/resources/guild#guild-object-mfa-level + */ + mfa_level: GuildMFALevel; + /** + * Application id of the guild creator if it is bot-created + */ + application_id: Snowflake | null; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id: Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags: GuildSystemChannelFlags; + /** + * The id of the channel where Community guilds can display rules and/or guidelines + */ + rules_channel_id: Snowflake | null; + /** + * When this guild was joined at + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + joined_at?: string; + /** + * `true` if this is considered a large guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + large?: boolean; + /** + * Total number of members in this guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + */ + member_count?: number; + /** + * States of members currently in voice channels; lacks the `guild_id` key + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/voice#voice-state-object + */ + voice_states?: Omit[]; + /** + * Users in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + members?: APIGuildMember[]; + /** + * Channels in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channels?: APIChannel[]; + /** + * Threads in the guild + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + threads?: APIChannel[]; + /** + * Presences of the members in the guild, will only include non-offline members if the size is greater than `large_threshold` + * + * **This field is only sent within the [GUILD_CREATE](https://discord.com/developers/docs/topics/gateway#guild-create) event** + * + * See https://discord.com/developers/docs/topics/gateway#presence-update + */ + presences?: GatewayPresenceUpdate[]; + /** + * The maximum number of presences for the guild (the default value, currently 25000, is in effect when `null` is returned) + */ + max_presences?: number | null; + /** + * The maximum number of members for the guild + */ + max_members?: number; + /** + * The vanity url code for the guild + */ + vanity_url_code: string | null; + /** + * The description for the guild, if the guild is discoverable + */ + description: string | null; + /** + * Banner hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + banner: string | null; + /** + * Premium tier (Server Boost level) + * + * See https://discord.com/developers/docs/resources/guild#guild-object-premium-tier + */ + premium_tier: GuildPremiumTier; + /** + * The number of boosts this guild currently has + */ + premium_subscription_count?: number; + /** + * The preferred locale of a Community guild; used in guild discovery and notices from Discord; defaults to "en-US" + * + * @default "en-US" + */ + preferred_locale: string; + /** + * The id of the channel where admins and moderators of Community guilds receive notices from Discord + */ + public_updates_channel_id: Snowflake | null; + /** + * The maximum amount of users in a video channel + */ + max_video_channel_users?: number; + /** + * **This field is only received from https://discord.com/developers/docs/resources/guild#get-guild with the `with_counts` query parameter set to `true`** + */ + approximate_member_count?: number; + /** + * **This field is only received from https://discord.com/developers/docs/resources/guild#get-guild with the `with_counts` query parameter set to `true`** + */ + approximate_presence_count?: number; + /** + * The welcome screen of a Community guild, shown to new members + * + * Returned in the invite object + */ + welcome_screen?: APIGuildWelcomeScreen; + /** + * `true` if this guild is designated as NSFW + * + * See https://support.discord.com/hc/en-us/articles/1500005389362-NSFW-Server-Designation + */ + nsfw: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ +export const enum GuildDefaultMessageNotifications { + AllMessages, + OnlyMentions, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ +export const enum GuildExplicitContentFilter { + Disabled, + MembersWithoutRoles, + AllMembers, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-mfa-level + */ +export const enum GuildMFALevel { + None, + Elevated, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ +export const enum GuildVerificationLevel { + /** + * Unrestricted + */ + None, + /** + * Must have verified email on account + */ + Low, + /** + * Must be registered on Discord for longer than 5 minutes + */ + Medium, + /** + * Must be a member of the guild for longer than 10 minutes + */ + High, + /** + * Must have a verified phone number + */ + VeryHigh, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-premium-tier + */ +export const enum GuildPremiumTier { + None, + Tier1, + Tier2, + Tier3, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ +export const enum GuildSystemChannelFlags { + /** + * Suppress member join notifications + */ + SuppressJoinNotifications = 1 << 0, + /** + * Suppress server boost notifications + */ + SuppressPremiumSubscriptions = 1 << 1, + /** + * Suppress server setup tips + */ + SuppressGuildReminderNotifications = 1 << 2, +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ +export const enum GuildFeature { + /** + * Guild has access to set an animated guild icon + */ + AnimatedIcon = 'ANIMATED_ICON', + /** + * Guild has access to set a guild banner image + */ + Banner = 'BANNER', + /** + * Guild has access to use commerce features (i.e. create store channels) + */ + Commerce = 'COMMERCE', + /** + * Guild can enable welcome screen, Membership Screening and discovery, and receives community updates + */ + Community = 'COMMUNITY', + /** + * Guild is able to be discovered in the directory + */ + Discoverable = 'DISCOVERABLE', + /** + * Guild is able to be featured in the directory + */ + Featurable = 'FEATURABLE', + /** + * Guild has access to set an invite splash background + */ + InviteSplash = 'INVITE_SPLASH', + /** + * Guild has access to create news channels + */ + News = 'NEWS', + /** + * Guild is partnered + */ + Partnered = 'PARTNERED', + RelayEnabled = 'RELAY_ENABLED', + /** + * Guild has access to set a vanity URL + */ + VanityURL = 'VANITY_URL', + /** + * Guild is verified + */ + Verified = 'VERIFIED', + /** + * Guild has access to set 384kbps bitrate in voice (previously VIP voice servers) + */ + VIPRegions = 'VIP_REGIONS', + /** + * Guild has enabled the welcome screen + */ + WelcomeScreenEnabled = 'WELCOME_SCREEN_ENABLED', + /** + * Guild has enabled Membership Screening + */ + MemberVerificationGateEnabled = 'MEMBER_VERIFICATION_GATE_ENABLED', + /** + * Guild can be previewed before joining via Membership Screening or the directory + */ + PreviewEnabled = 'PREVIEW_ENABLED', +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-preview-object + */ +export interface APIGuildPreview { + /** + * Guild id + */ + id: Snowflake; + /** + * Guild name (2-100 characters) + */ + name: string; + /** + * Icon hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * Splash hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + splash: string | null; + /** + * Discovery splash hash; only present for guilds with the "DISCOVERABLE" feature + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + discovery_splash: string | null; + /** + * Custom guild emojis + * + * See https://discord.com/developers/docs/resources/emoji#emoji-object + */ + emojis: APIEmoji[]; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features: GuildFeature[]; + /** + * Approximate number of members in this guild + */ + approximate_member_count: number; + /** + * Approximate number of online members in this guild + */ + approximate_presence_count: number; + /** + * The description for the guild + */ + description: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-widget-object + */ +export interface APIGuildWidgetSettings { + /** + * Whether the widget is enabled + */ + enabled: boolean; + /** + * The widget channel id + */ + channel_id: Snowflake | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIGuildMember { + /** + * The user this guild member represents + * + * **This field won't be included in the member object attached to `MESSAGE_CREATE` and `MESSAGE_UPDATE` gateway events.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * This users guild nickname + */ + nick?: string | null; + /** + * Array of role object ids + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles: Snowflake[]; + /** + * When the user joined the guild + */ + joined_at: string; + /** + * When the user started boosting the guild + * + * See https://support.discord.com/hc/en-us/articles/360028038352-Server-Boosting- + */ + premium_since?: string | null; + /** + * Whether the user is deafened in voice channels + */ + deaf: boolean; + /** + * Whether the user is muted in voice channels + */ + mute: boolean; + /** + * Whether the user has not yet passed the guild's Membership Screening requirements + * + * *If this field is not present, it can be assumed as `false`.* + */ + pending?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-object + */ +export interface APIGuildIntegration { + /** + * Integration id + */ + id: Snowflake; + /** + * Integration name + */ + name: string; + /** + * Integration type + */ + type: APIGuildInteractionType; + /** + * Is this integration enabled + */ + enabled: boolean; + /** + * Is this integration syncing + * + * **This field is not provided for `discord` bot integrations.** + */ + syncing?: boolean; + /** + * ID that this integration uses for "subscribers" + * + * **This field is not provided for `discord` bot integrations.** + */ + role_id?: Snowflake; + /** + * Whether emoticons should be synced for this integration (`twitch` only currently) + * + * **This field is not provided for `discord` bot integrations.** + */ + enable_emoticons?: boolean; + /** + * The behavior of expiring subscribers + * + * **This field is not provided for `discord` bot integrations.** + * + * See https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors + */ + expire_behavior?: IntegrationExpireBehavior; + /** + * The grace period (in days) before expiring subscribers + * + * **This field is not provided for `discord` bot integrations.** + */ + expire_grace_period?: number; + /** + * User for this integration + * + * **This field is not provided for `discord` bot integrations.** + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * Integration account information + * + * See https://discord.com/developers/docs/resources/guild#integration-account-object + */ + account: APIIntegrationAccount; + /** + * When this integration was last synced + * + * **This field is not provided for `discord` bot integrations.** + */ + synced_at?: string; + /** + * How many subscribers this integration has + * + * **This field is not provided for `discord` bot integrations.** + */ + subscriber_count?: number; + /** + * Has this integration been revoked + * + * **This field is not provided for `discord` bot integrations.** + */ + revoked?: boolean; + /** + * The bot/OAuth2 application for discord integrations + * + * See https://discord.com/developers/docs/resources/guild#integration-application-object + * + * **This field is not provided for `discord` bot integrations.** + */ + application?: APIGuildIntegrationApplication; +} + +export type APIGuildInteractionType = 'twitch' | 'youtube' | 'discord'; + +/** + * https://discord.com/developers/docs/resources/guild#integration-object-integration-expire-behaviors + */ +export const enum IntegrationExpireBehavior { + RemoveRole, + Kick, +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-account-object + */ +export interface APIIntegrationAccount { + /** + * ID of the account + */ + id: string; + /** + * Name of the account + */ + name: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#integration-application-object + */ +export interface APIGuildIntegrationApplication { + /** + * The id of the app + */ + id: Snowflake; + /** + * The name of the app + */ + name: string; + /** + * The icon hash of the app + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + icon: string | null; + /** + * The description of the app + */ + description: string; + /** + * The summary of the app + */ + summary: string; + /** + * The bot associated with this application + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + bot?: APIUser; +} + +/** + * https://discord.com/developers/docs/resources/guild#ban-object + */ +export interface APIBan { + /** + * The reason for the ban + */ + reason: string | null; + /** + * The banned user + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidget { + id: Snowflake; + name: string; + instant_invite: string | null; + channels: APIGuildWidgetChannel[]; + members: APIGuildWidgetMember[]; + presence_count: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidgetChannel { + id: Snowflake; + name: string; + position: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-example-get-guild-widget + */ +export interface APIGuildWidgetMember { + id: string; + username: string; + discriminator: string; + avatar: string | null; + status: PresenceUpdateStatus; + activity?: { name: string }; + avatar_url: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-image-widget-style-options + */ +export const enum GuildWidgetStyle { + /** + * Shield style widget with Discord icon and guild members online count + */ + Shield = 'shield', + /** + * Large image with guild icon, name and online count. "POWERED BY DISCORD" as the footer of the widget + */ + Banner1 = 'banner1', + /** + * Smaller widget style with guild icon, name and online count. Split on the right with Discord logo + */ + Banner2 = 'banner2', + /** + * Large image with guild icon, name and online count. In the footer, Discord logo on the left and "Chat Now" on the right + */ + Banner3 = 'banner3', + /** + * Large Discord logo at the top of the widget. Guild icon, name and online count in the middle portion of the widget + * and a "JOIN MY SERVER" button at the bottom + */ + Banner4 = 'banner4', +} + +export interface APIGuildWelcomeScreen { + /** + * The welcome screen short message + */ + description: string | null; + /** + * Array of suggested channels + */ + welcome_channels: APIGuildWelcomeScreenChannel[]; +} + +export interface APIGuildWelcomeScreenChannel { + /** + * The channel id that is suggested + */ + channel_id: Snowflake; + /** + * The description shown for the channel + */ + description: string; + /** + * The emoji id of the emoji that is shown on the left of the channel + */ + emoji_id: Snowflake | null; + /** + * The emoji name of the emoji that is shown on the left of the channel + */ + emoji_name: string | null; +} + +export interface APIGuildMembershipScreening { + /** + * When the fields were last updated + */ + version: string; + /** + * The steps in the screening form + */ + form_fields: APIGuildMembershipScreeningField[]; + /** + * The server description shown in the screening form + */ + description: string | null; +} + +// TODO: make this a union based on the type in the future, when new types are added + +export interface APIGuildMembershipScreeningField { + /** + * The type of field + */ + field_type: MembershipScreeningFieldType; + /** + * The title of the field + */ + label: string; + /** + * The list of rules + */ + values?: string[]; + /** + * Whether the user has to fill out this field + */ + required: boolean; +} + +export const enum MembershipScreeningFieldType { + /** + * Server Rules + */ + Terms = 'TERMS', +} diff --git a/payloads/v9/index.ts b/payloads/v9/index.ts new file mode 100644 index 00000000..fa90579b --- /dev/null +++ b/payloads/v9/index.ts @@ -0,0 +1,14 @@ +export * from './auditLog'; +export * from './channel'; +export * from './emoji'; +export * from './gateway'; +export * from './guild'; +export * from './interactions'; +export * from './invite'; +export * from './oauth2'; +export * from './permissions'; +export * from './teams'; +export * from './template'; +export * from './user'; +export * from './voice'; +export * from './webhook'; diff --git a/payloads/v9/interactions.ts b/payloads/v9/interactions.ts new file mode 100644 index 00000000..70c3bcd3 --- /dev/null +++ b/payloads/v9/interactions.ts @@ -0,0 +1,426 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { RESTPostAPIWebhookWithTokenJSONBody } from '../../rest/v9/index'; +import type { APIGuildMember, APIPartialChannel, APIRole, APIUser, MessageFlags } from './index'; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommand + */ +export interface APIApplicationCommand { + /** + * Unique id of the command + */ + id: Snowflake; + /** + * Unique id of the parent application + */ + application_id: Snowflake; + /** + * 1-32 character name matching `^[\w-]{1,32}$` + */ + name: string; + /** + * 1-100 character description + */ + description: string; + /** + * The parameters for the command + */ + options?: APIApplicationCommandOption[]; + /** + * Whether the command is enabled by default when the app is added to a guild + * + * If missing, this property should be assumed as `true` + */ + default_permission?: boolean; +} + +interface APIApplicationCommandOptionBase { + type: + | ApplicationCommandOptionType.Boolean + | ApplicationCommandOptionType.User + | ApplicationCommandOptionType.Channel + | ApplicationCommandOptionType.Role + | ApplicationCommandOptionType.Mentionable; + name: string; + description: string; + default?: boolean; + required?: boolean; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoption + */ +export type APIApplicationCommandOption = + | APIApplicationCommandArgumentOptions + | APIApplicationCommandSubCommandOptions + | APIApplicationCommandOptionBase; + +/** + * This type is exported as a way to make it stricter for you when you're writing your commands + * + * If the option is a `SUB_COMMAND` or `SUB_COMMAND_GROUP` type, this nested options will be the parameters + */ +export interface APIApplicationCommandSubCommandOptions extends Omit { + type: ApplicationCommandOptionType.SubCommand | ApplicationCommandOptionType.SubCommandGroup; + options?: APIApplicationCommandOption[]; +} + +/** + * This type is exported as a way to make it stricter for you when you're writing your commands + * + * In contrast to `APIApplicationCommandSubCommandOptions`, these types cannot have an `options` array, + * but they can have a `choices` one + */ +export interface APIApplicationCommandArgumentOptions extends Omit { + type: ApplicationCommandOptionType.String | ApplicationCommandOptionType.Integer; + choices?: APIApplicationCommandOptionChoice[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype + */ +export const enum ApplicationCommandOptionType { + SubCommand = 1, + SubCommandGroup, + String, + Integer, + Boolean, + User, + Channel, + Role, + Mentionable, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptionchoice + */ +export interface APIApplicationCommandOptionChoice { + name: string; + value: string | number; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIBaseInteraction { + /** + * ID of the interaction + */ + id: Snowflake; + /** + * ID of the application this interaction is for + */ + application_id: Snowflake; + /** + * The type of interaction + */ + type: InteractionType; + /** + * The command data payload + */ + data?: APIApplicationCommandInteractionData; + /** + * The channel it was sent from + */ + channel_id?: Snowflake; + /** + * A continuation token for responding to the interaction + */ + token: string; + /** + * Read-only property, always `1` + */ + version: 1; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIInteractionGuildMember extends APIGuildMember { + permissions: Permissions; + user: APIUser; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIGuildInteraction extends APIBaseInteraction { + /** + * The guild it was sent from + * + * In the case of an `APIDMInteraction`, this will not be present + */ + guild_id: Snowflake; + /** + * Guild member data for the invoking user, including permissions + */ + member: APIInteractionGuildMember; + channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export interface APIDMInteraction extends APIBaseInteraction { + /** + * User object for the invoking user, if invoked in a DM + */ + user: APIUser; + channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction + */ +export type APIInteraction = APIGuildInteraction | APIDMInteraction; + +/** + * Like APIGuildInteraction, only with the `data` property always present + * + * @see APIGuildInteraction + */ +export type APIApplicationCommandGuildInteraction = Required; + +/** + * Like APIDMInteraction, only with the `data` property always present + * + * @see APIDMInteraction + */ +export type APIApplicationCommandDMInteraction = Required; + +/** + * Like APIInteraction, only with the `data` property always present + * + * @see APIInteraction + */ +export type APIApplicationCommandInteraction = + | APIApplicationCommandGuildInteraction + | APIApplicationCommandDMInteraction; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype + */ +export const enum InteractionType { + Ping = 1, + ApplicationCommand, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#guildapplicationcommandpermissions + */ +export interface APIGuildApplicationCommandPermissions { + /** + * The id of the command + */ + id: Snowflake; + /** + * The id of the application the command belongs to + */ + application_id: Snowflake; + /** + * The id of the guild + */ + guild_id: Snowflake; + /** + * The permissions for the command in the guild + */ + permissions: APIApplicationCommandPermission[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandpermissions + */ +export interface APIApplicationCommandPermission { + /** + * The id of the role or user + */ + id: Snowflake; + /** + * Role or user + */ + type: ApplicationCommandPermissionType; + /** + * `true` to allow, `false`, to disallow + */ + permission: boolean; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#applicationcommandpermissiontype + */ +export const enum ApplicationCommandPermissionType { + Role = 1, + User, +} + +/** + * https://discord.com/developers/docs/resources/channel#channel-object + */ +export interface APIInteractionDataResolvedChannel extends Required { + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/resources/guild#guild-member-object + */ +export interface APIInteractionDataResolvedGuildMember extends Omit { + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-applicationcommandinteractiondata + */ +export interface APIApplicationCommandInteractionData { + id: Snowflake; + name: string; + options?: APIApplicationCommandInteractionDataOption[]; + resolved?: { + users?: Record; + roles?: Record; + members?: Record; + channels?: Record; + }; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-applicationcommandinteractiondataoption + */ +export type APIApplicationCommandInteractionDataOption = + | ApplicationCommandInteractionDataOptionSubCommand + | ApplicationCommandInteractionDataOptionSubCommandGroup + | APIApplicationCommandInteractionDataOptionWithValues; + +export interface ApplicationCommandInteractionDataOptionSubCommand { + name: string; + type: ApplicationCommandOptionType.SubCommand; + options: APIApplicationCommandInteractionDataOptionWithValues[]; +} + +export interface ApplicationCommandInteractionDataOptionSubCommandGroup { + name: string; + type: ApplicationCommandOptionType.SubCommandGroup; + options: ApplicationCommandInteractionDataOptionSubCommand[]; +} + +export type APIApplicationCommandInteractionDataOptionWithValues = + | ApplicationCommandInteractionDataOptionString + | ApplicationCommandInteractionDataOptionRole + | ApplicationCommandInteractionDataOptionChannel + | ApplicationCommandInteractionDataOptionUser + | ApplicationCommandInteractionDataOptionMentionable + | ApplicationCommandInteractionDataOptionInteger + | ApplicationCommandInteractionDataOptionBoolean; + +export type ApplicationCommandInteractionDataOptionString = InteractionDataOptionBase< + ApplicationCommandOptionType.String, + string +>; + +export type ApplicationCommandInteractionDataOptionRole = InteractionDataOptionBase< + ApplicationCommandOptionType.Role, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionChannel = InteractionDataOptionBase< + ApplicationCommandOptionType.Channel, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionUser = InteractionDataOptionBase< + ApplicationCommandOptionType.User, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionMentionable = InteractionDataOptionBase< + ApplicationCommandOptionType.Mentionable, + Snowflake +>; + +export type ApplicationCommandInteractionDataOptionInteger = InteractionDataOptionBase< + ApplicationCommandOptionType.Integer, + number +>; + +export type ApplicationCommandInteractionDataOptionBoolean = InteractionDataOptionBase< + ApplicationCommandOptionType.Boolean, + boolean +>; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response + */ +export type APIInteractionResponse = + | APIInteractionResponsePong + | APIInteractionResponseChannelMessageWithSource + | APIInteractionResponseDeferredChannelMessageWithSource; + +export interface APIInteractionResponsePong { + type: InteractionResponseType.Pong; +} + +export interface APIInteractionResponseChannelMessageWithSource { + type: InteractionResponseType.ChannelMessageWithSource; + data: APIInteractionApplicationCommandCallbackData; +} + +export interface APIInteractionResponseDeferredChannelMessageWithSource { + type: InteractionResponseType.DeferredChannelMessageWithSource; + data?: Pick; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionresponsetype + */ +export const enum InteractionResponseType { + /** + * ACK a `Ping` + */ + Pong = 1, + /** + * Respond to an interaction with a message + */ + ChannelMessageWithSource = 4, + /** + * ACK an interaction and edit to a response later, the user sees a loading state + */ + DeferredChannelMessageWithSource, +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionapplicationcommandcallbackdata + */ +export type APIInteractionApplicationCommandCallbackData = Omit< + RESTPostAPIWebhookWithTokenJSONBody, + 'username' | 'avatar_url' +> & { flags?: MessageFlags }; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#messageinteraction + */ +export interface APIMessageInteraction { + /** + * ID of the interaction + */ + id: Snowflake; + /** + * The type of interaction + */ + type: InteractionType; + /** + * The name of the ApplicationCommand + */ + name: string; + /** + * The user who invoked the interaction + */ + user: APIUser; +} + +/** + * @internal + */ +interface InteractionDataOptionBase { + name: string; + type: T; + value: D; +} diff --git a/payloads/v9/invite.ts b/payloads/v9/invite.ts new file mode 100644 index 00000000..156e55fd --- /dev/null +++ b/payloads/v9/invite.ts @@ -0,0 +1,100 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/invite + */ + +import type { APIPartialChannel } from './channel'; +import type { APIPartialGuild } from './guild'; +import type { APIApplication } from './oauth2'; +import type { APIUser } from './user'; + +/** + * https://discord.com/developers/docs/resources/invite#invite-object + */ +export interface APIInvite { + /** + * The invite code (unique ID) + */ + code: string; + /** + * The guild this invite is for + * + * See https://discord.com/developers/docs/resources/guild#guild-object + */ + guild?: APIPartialGuild; + /** + * The channel this invite is for + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channel: Required; + /** + * The user who created the invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + inviter?: APIUser; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-target-user-types + */ + target_type?: InviteTargetType; + /** + * The user whose stream to display for this voice channel stream invite + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + target_user?: APIUser; + /** + * The embedded application to open for this voice channel embedded application invite + * + * See https://discord.com/developers/docs/topics/oauth2#application + */ + target_application?: Partial; + /** + * Approximate count of online members, returned from the `GET /invites/` endpoint when `with_counts` is `true` + */ + approximate_presence_count?: number; + /** + * Approximate count of total members, returned from the `GET /invites/` endpoint when `with_counts` is `true` + */ + approximate_member_count?: number; + /** + * The expiration date of this invite, returned from the `GET /invites/` endpoint when `with_expiration` is `true` + */ + expires_at?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ +export const enum InviteTargetType { + Stream = 1, + EmbeddedApplication, +} + +/** + * https://discord.com/developers/docs/resources/invite#invite-metadata-object + */ +export interface APIExtendedInvite extends APIInvite { + /** + * Number of times this invite has been used + */ + uses: number; + /** + * Max number of times this invite can be used + */ + max_uses: number; + /** + * Duration (in seconds) after which the invite expires + */ + max_age: number; + /** + * Whether this invite only grants temporary membership + */ + temporary: boolean; + /** + * When this invite was created + */ + created_at: string; +} diff --git a/payloads/v9/oauth2.ts b/payloads/v9/oauth2.ts new file mode 100644 index 00000000..a0a45bb2 --- /dev/null +++ b/payloads/v9/oauth2.ts @@ -0,0 +1,209 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/oauth2 + */ + +import type { Snowflake } from '../../globals'; +import type { APITeam } from './teams'; +import type { APIUser } from './user'; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-application-information-response-structure + */ +export interface APIApplication { + /** + * The id of the app + */ + id: Snowflake; + /** + * The name of the app + */ + name: string; + /** + * The icon hash of the app + */ + icon: string | null; + /** + * The description of the app + */ + description: string; + /** + * An array of rpc origin urls, if rpc is enabled + */ + rpc_origins?: string[]; + /** + * When `false` only app owner can join the app's bot to guilds + */ + bot_public: boolean; + /** + * When `true` the app's bot will only join upon completion of the full oauth2 code grant flow + */ + bot_require_code_grant: boolean; + /** + * The url of the application's terms of service + */ + terms_of_service_url?: string; + /** + * The url of the application's privacy policy + */ + privacy_policy_url?: string; + /** + * Partial user object containing info on the owner of the application + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + owner: APIUser; + /** + * If this application is a game sold on Discord, this field will be the summary field for the store page + * of its primary sku + */ + summary: string; + /** + * The hexadecimal encoded key for verification in interactions and the GameSDK's GetTicket function + * + * See https://discord.com/developers/docs/game-sdk/applications#get-ticket + */ + verify_key: string; + /** + * The team this application belongs to + * + * See https://discord.com/developers/docs/topics/teams#data-models-team-object + */ + team: APITeam | null; + /** + * If this application is a game sold on Discord, this field will be the guild to which it has been linked + */ + guild_id?: Snowflake; + /** + * If this application is a game sold on Discord, this field will be the id of the "Game SKU" that is created, if exists + */ + primary_sku_id?: Snowflake; + /** + * If this application is a game sold on Discord, this field will be the URL slug that links to the store page + */ + slug?: string; + /** + * If this application is a game sold on Discord, this field will be the hash of the image on store embeds + */ + cover_image?: string; + /** + * The application's public flags + */ + flags: ApplicationFlags; +} + +export const enum ApplicationFlags { + ManagedEmoji = 1 << 2, + GroupDMCreate = 1 << 4, + RPCHasConnected = 1 << 11, + GatewayPresence = 1 << 12, + GatewayPresenceLimited = 1 << 13, + GatewayGuildMembers = 1 << 14, + GatewayGuildMembersLimited = 1 << 15, + VerificationPendingGuildLimit = 1 << 16, + Embedded = 1 << 17, +} + +export const enum OAuth2Scopes { + /** + * For oauth2 bots, this puts the bot in the user's selected guild by default + */ + Bot = 'bot', + /** + * Allows [/users/@me/connections](https://discord.com/developers/docs/resources/user#get-user-connections) + * to return linked third-party accounts + * + * See https://discord.com/developers/docs/resources/user#get-user-connections + */ + Connections = 'connections', + /** + * Enables [/users/@me](https://discord.com/developers/docs/resources/user#get-current-user) to return an `email` + * + * See https://discord.com/developers/docs/resources/user#get-current-user + */ + Email = 'email', + /** + * Allows [/users/@me](https://discord.com/developers/docs/resources/user#get-current-user) without `email` + * + * See https://discord.com/developers/docs/resources/user#get-current-user + */ + Identify = 'identify', + /** + * Allows [/users/@me/guilds](https://discord.com/developers/docs/resources/user#get-current-user-guilds) + * to return basic information about all of a user's guilds + * + * See https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ + Guilds = 'guilds', + /** + * Allows [/guilds/{guild.id}/members/{user.id}](https://discord.com/developers/docs/resources/guild#add-guild-member) + * to be used for joining users to a guild + * + * See https://discord.com/developers/docs/resources/guild#add-guild-member + */ + GuildsJoin = 'guilds.join', + /** + * Allows your app to join users to a group dm + * + * See https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ + GroupDMJoins = 'gdm.join', + /** + * For local rpc server api access, this allows you to read messages from all client channels + * (otherwise restricted to channels/guilds your app creates) + */ + MessagesRead = 'messages.read', + /** + * For local rpc server access, this allows you to control a user's local Discord client - whitelist only + */ + RPC = 'rpc', + /** + * For local rpc server api access, this allows you to receive notifications pushed out to the user - whitelist only + */ + RPCNotificationsRead = 'rpc.notifications.read', + /** + * This generates a webhook that is returned in the oauth token response for authorization code grants + */ + WebhookIncoming = 'webhook.incoming', + /** + * Allows your app to upload/update builds for a user's applications - whitelist only + */ + ApplicationsBuildsUpload = 'applications.builds.upload', + /** + * Allows your app to read build data for a user's applications + */ + ApplicationsBuildsRead = 'applications.builds.read', + /** + * Allows your app to read and update store data (SKUs, store listings, achievements, etc.) for a user's applications + */ + ApplicationsStoreUpdate = 'applications.store.update', + /** + * Allows your app to read entitlements for a user's applications + */ + ApplicationsEntitlements = 'applications.entitlements', + /** + * Allows your app to know a user's friends and implicit relationships - whitelist only + */ + RelationshipsRead = 'relationships.read', + /** + * Allows your app to fetch data from a user's "Now Playing/Recently Played" list - whitelist only + */ + ActivitiesRead = 'activities.read', + /** + * Allows your app to update a user's activity - whitelist only (NOT REQUIRED FOR GAMESDK ACTIVITY MANAGER) + * + * See https://discord.com/developers/docs/game-sdk/activities + */ + ActivitiesWrite = 'activities.write', + /** + * Allows your app to create Slash Commands in the authorized guild + * + * See https://discord.com/developers/docs/interactions/slash-commands + */ + ApplicationsCommands = 'applications.commands', + /** + * Allows your app to update Slash Commands via this bearer token + * + * See https://discord.com/developers/docs/interactions/slash-commands + */ + ApplicationsCommandsUpdate = 'applications.commands.update', +} diff --git a/payloads/v9/permissions.ts b/payloads/v9/permissions.ts new file mode 100644 index 00000000..774b0590 --- /dev/null +++ b/payloads/v9/permissions.ts @@ -0,0 +1,119 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/permissions + */ + +import type { Permissions, Snowflake } from '../../globals'; + +/** + * https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags + * + * These flags are exported as `BigInt`s and NOT numbers. Wrapping them in `Number()` + * may cause issues, try to use BigInts as much as possible or modules that can + * replicate them in some way + */ +export const PermissionFlagsBits = { + CreateInstantInvite: 1n << 0n, + KickMembers: 1n << 1n, + BanMembers: 1n << 2n, + Administrator: 1n << 3n, + ManageChannels: 1n << 4n, + ManageGuild: 1n << 5n, + AddReactions: 1n << 6n, + ViewAuditLog: 1n << 7n, + PrioritySpeaker: 1n << 8n, + Stream: 1n << 9n, + ViewChannel: 1n << 10n, + SendMessages: 1n << 11n, + SendTTSMessages: 1n << 12n, + ManageMessages: 1n << 13n, + EmbedLinks: 1n << 14n, + AttachFiles: 1n << 15n, + ReadMessageHistory: 1n << 16n, + MentionEveryone: 1n << 17n, + UseExternalEmojis: 1n << 18n, + ViewGuildInsights: 1n << 19n, + Connect: 1n << 20n, + Speak: 1n << 21n, + MuteMembers: 1n << 22n, + DeafenMembers: 1n << 23n, + MoveMembers: 1n << 24n, + UseVAD: 1n << 25n, + ChangeNickname: 1n << 26n, + ManageNicknames: 1n << 27n, + ManageRoles: 1n << 28n, + ManageWebhooks: 1n << 29n, + ManageEmojis: 1n << 30n, + UseSlashCommands: 1n << 31n, + RequestToSpeak: 1n << 32n, + ManageThreads: 1n << 34n, + UsePublicThreads: 1n << 35n, + UsePrivateThreads: 1n << 36n, +} as const; + +/** + * Freeze the object of bits, preventing any modifications to it + * @internal + */ +Object.freeze(PermissionFlagsBits); + +/** + * https://discord.com/developers/docs/topics/permissions#role-object + */ +export interface APIRole { + /** + * Role id + */ + id: Snowflake; + /** + * Role name + */ + name: string; + /** + * Integer representation of hexadecimal color code + */ + color: number; + /** + * If this role is pinned in the user listing + */ + hoist: boolean; + /** + * Position of this role + */ + position: number; + /** + * Permission bit set + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + permissions: Permissions; + /** + * Whether this role is managed by an integration + */ + managed: boolean; + /** + * Whether this role is mentionable + */ + mentionable: boolean; + /** + * The tags this role has + */ + tags?: APIRoleTags; +} + +/** + * https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure + */ +export interface APIRoleTags { + /** + * The id of the bot this role belongs to + */ + bot_id?: Snowflake; + /** + * Whether this is the guild's premium subscriber role + */ + premium_subscriber?: null; + /** + * The id of the integration this role belongs to + */ + integration_id?: Snowflake; +} diff --git a/payloads/v9/teams.ts b/payloads/v9/teams.ts new file mode 100644 index 00000000..cadf539b --- /dev/null +++ b/payloads/v9/teams.ts @@ -0,0 +1,62 @@ +/** + * Types extracted from https://discord.com/developers/docs/topics/teams + */ + +import type { Snowflake } from '../../globals'; +import type { APIUser } from './user'; + +/** + * https://discord.com/developers/docs/topics/teams#data-models-team-object + */ +export interface APITeam { + /** + * A hash of the image of the team's icon + */ + icon: string | null; + /** + * The unique id of the team + */ + id: Snowflake; + /** + * The members of the team + */ + members: APITeamMember[]; + /** + * The user id of the current team owner + */ + owner_user_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/topics/teams#data-models-team-members-object + */ +export interface APITeamMember { + /** + * The user's membership state on the team + * + * See https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum + */ + membership_state: TeamMemberMembershipState; + /** + * Will always be `["*"]` + */ + permissions: ['*']; + /** + * The id of the parent team of which they are a member + */ + team_id: Snowflake; + /** + * The avatar, discriminator, id, and username of the user + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/teams#data-models-membership-state-enum + */ +export const enum TeamMemberMembershipState { + Invited = 1, + Accepted, +} diff --git a/payloads/v9/template.ts b/payloads/v9/template.ts new file mode 100644 index 00000000..0ebac393 --- /dev/null +++ b/payloads/v9/template.ts @@ -0,0 +1,65 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/template + */ + +import type { Snowflake } from '../../globals'; +import type { RESTPostAPIGuildsJSONBody } from '../../rest/v9/index'; +import type { APIUser } from './user'; + +/** + * https://discord.com/developers/docs/resources/template#template-object + */ +export interface APITemplate { + /** + * The template code (unique ID) + */ + code: string; + /** + * Template name + */ + name: string; + /** + * The description for the template + */ + description: string | null; + /** + * Number of times this template has been used + */ + usage_count: number; + /** + * The ID of the user who created the template + */ + creator_id: Snowflake; + /** + * The user who created the template + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + creator: APIUser; + /** + * When this template was created + */ + created_at: string; + /** + * When this template was last synced to the source guild + */ + updated_at: string; + /** + * The ID of the guild this template is based on + */ + source_guild_id: Snowflake; + /** + * The guild snapshot this template contains + */ + serialized_source_guild: APITemplateSerializedSourceGuild; + /** + * Whether the template has unsynced changes + */ + is_dirty: boolean | null; +} + +export interface APITemplateSerializedSourceGuild extends Omit { + description: string | null; + preferred_locale: string; + icon_hash: string | null; +} diff --git a/payloads/v9/user.ts b/payloads/v9/user.ts new file mode 100644 index 00000000..15b1914e --- /dev/null +++ b/payloads/v9/user.ts @@ -0,0 +1,157 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/user + */ + +import type { Snowflake } from '../../globals'; +import type { APIGuildIntegration } from './guild'; + +/** + * https://discord.com/developers/docs/resources/user#user-object + */ +export interface APIUser { + /** + * The user's id + */ + id: Snowflake; + /** + * The user's username, not unique across the platform + */ + username: string; + /** + * The user's 4-digit discord-tag + */ + discriminator: string; + /** + * The user's avatar hash + * + * See https://discord.com/developers/docs/reference#image-formatting + */ + avatar: string | null; + /** + * Whether the user belongs to an OAuth2 application + */ + bot?: boolean; + /** + * Whether the user is an Official Discord System user (part of the urgent message system) + */ + system?: boolean; + /** + * Whether the user has two factor enabled on their account + */ + mfa_enabled?: boolean; + /** + * The user's chosen language option + */ + locale?: string; + /** + * Whether the email on this account has been verified + */ + verified?: boolean; + /** + * The user's email + */ + email?: string | null; + /** + * The flags on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-user-flags + */ + flags?: UserFlags; + /** + * The type of Nitro subscription on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-premium-types + */ + premium_type?: UserPremiumType; + /** + * The public flags on a user's account + * + * See https://discord.com/developers/docs/resources/user#user-object-user-flags + */ + public_flags?: UserFlags; +} + +/** + * https://discord.com/developers/docs/resources/user#user-object-user-flags + */ +export const enum UserFlags { + None = 0, + DiscordEmployee = 1 << 0, + PartneredServerOwner = 1 << 1, + DiscordHypeSquadEvents = 1 << 2, + BugHunterLevel1 = 1 << 3, + HypeSquadHouseBravery = 1 << 6, + HypeSquadHouseBrilliance = 1 << 7, + HypeSquadHouseBalance = 1 << 8, + EarlySupporter = 1 << 9, + TeamUser = 1 << 10, + BugHunterLevel2 = 1 << 14, + VerifiedBot = 1 << 16, + EarlyVerifiedBotDeveloper = 1 << 17, +} + +/** + * https://discord.com/developers/docs/resources/user#user-object-premium-types + */ +export const enum UserPremiumType { + None, + NitroClassic, + Nitro, +} + +/** + * https://discord.com/developers/docs/resources/user#connection-object + */ +export interface APIConnection { + /** + * ID of the connection account + */ + id: string; + /** + * The username of the connection account + */ + name: string; + /** + * The service of the connection + */ + type: string; + /** + * Whether the connection is revoked + */ + revoked?: boolean; + /** + * An array of partial server integrations + * + * See https://discord.com/developers/docs/resources/guild#integration-object + */ + integrations?: Partial[]; + /** + * Whether the connection is verified + */ + verified: boolean; + /** + * Whether friend sync is enabled for this connection + */ + friend_sync: boolean; + /** + * Whether activities related to this connection will be shown in presence updates + */ + show_activity: boolean; + /** + * Visibility of this connection + * + * See https://discord.com/developers/docs/resources/user#connection-object-visibility-types + */ + visibility: ConnectionVisibility; +} + +export const enum ConnectionVisibility { + /** + * Invisible to everyone except the user themselves + */ + None, + /** + * Visible to everyone + */ + Everyone, +} diff --git a/payloads/v9/voice.ts b/payloads/v9/voice.ts new file mode 100644 index 00000000..4e7d68ce --- /dev/null +++ b/payloads/v9/voice.ts @@ -0,0 +1,96 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/voice + */ + +import type { Snowflake } from '../../globals'; +import type { APIGuildMember } from './guild'; + +/** + * https://discord.com/developers/docs/resources/voice#voice-state-object + */ +export interface GatewayVoiceState { + /** + * The guild id this voice state is for + */ + guild_id?: Snowflake; + /** + * The channel id this user is connected to + */ + channel_id: Snowflake | null; + /** + * The user id this voice state is for + */ + user_id: Snowflake; + /** + * The guild member this voice state is for + * + * See https://discord.com/developers/docs/resources/guild#guild-member-object + */ + member?: APIGuildMember; + /** + * The session id for this voice state + */ + session_id: string; + /** + * Whether this user is deafened by the server + */ + deaf: boolean; + /** + * Whether this user is muted by the server + */ + mute: boolean; + /** + * Whether this user is locally deafened + */ + self_deaf: boolean; + /** + * Whether this user is locally muted + */ + self_mute: boolean; + /** + * Whether this user is streaming using "Go Live" + */ + self_stream?: boolean; + /** + * Whether this user's camera is enabled + */ + self_video: boolean; + /** + * Whether this user is muted by the current user + */ + suppress: boolean; + /** + * The time at which the user requested to speak + */ + request_to_speak_timestamp: string | null; +} + +/** + * https://discord.com/developers/docs/resources/voice#voice-region-object + */ +export interface APIVoiceRegion { + /** + * Unique ID for the region + */ + id: string; + /** + * Name of the region + */ + name: string; + /** + * `true` if this is a vip-only server + */ + vip: boolean; + /** + * `true` for a single server that is closest to the current user's client + */ + optimal: boolean; + /** + * Whether this is a deprecated voice region (avoid switching to these) + */ + deprecated: boolean; + /** + * Whether this is a custom voice region (used for events/etc) + */ + custom: boolean; +} diff --git a/payloads/v9/webhook.ts b/payloads/v9/webhook.ts new file mode 100644 index 00000000..b63549d7 --- /dev/null +++ b/payloads/v9/webhook.ts @@ -0,0 +1,75 @@ +/** + * Types extracted from https://discord.com/developers/docs/resources/webhook + */ + +import type { Snowflake } from '../../globals'; +import type { APIPartialChannel, APIPartialGuild, APIUser } from './index'; + +/** + * https://discord.com/developers/docs/resources/webhook#webhook-object + */ +export interface APIWebhook { + /** + * The id of the webhook + */ + id: Snowflake; + /** + * The type of the webhook + * + * See https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types + */ + type: WebhookType; + /** + * The guild id this webhook is for + */ + guild_id?: Snowflake; + /** + * The channel id this webhook is for + */ + channel_id: Snowflake; + /** + * The user this webhook was created by (not returned when getting a webhook with its token) + * + * See https://discord.com/developers/docs/resources/user#user-object + */ + user?: APIUser; + /** + * The default name of the webhook + */ + name: string | null; + /** + * The default avatar of the webhook + */ + avatar: string | null; + /** + * The secure token of the webhook (returned for Incoming Webhooks) + */ + token?: string; + /** + * The bot/OAuth2 application that created this webhook + */ + application_id: Snowflake | null; + /** + * The guild of the channel that this webhook is following (returned for Channel Follower Webhooks) + */ + source_guild?: APIPartialGuild; + /** + * The channel that this webhook is following (returned for Channel Follower Webhooks) + */ + source_channel?: APIPartialChannel; + /** + * The url used for executing the webhook (returned by the webhooks OAuth2 flow) + */ + url?: string; +} + +export const enum WebhookType { + /** + * Incoming Webhooks can post messages to channels with a generated token + */ + Incoming = 1, + /** + * Channel Follower Webhooks are internal webhooks used with Channel Following to post new messages into channels + */ + ChannelFollower, +} diff --git a/rest/common.ts b/rest/common.ts index 0ec8491b..63955d8e 100644 --- a/rest/common.ts +++ b/rest/common.ts @@ -105,6 +105,10 @@ export const enum RESTJSONErrorCodes { InvalidStickerSent = 50081, + InvalidActionOnArchivedThread = 50083, + InvalidThreadNotificationSettings, + ParameterEarlierThanCreation, + TwoFactorAuthenticationIsRequired = 60003, ReactionWasBlocked = 90001, diff --git a/rest/index.ts b/rest/index.ts index d1dccbf4..996962f4 100644 --- a/rest/index.ts +++ b/rest/index.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8/index'; +export * from './v9/index'; diff --git a/rest/v9/auditLog.ts b/rest/v9/auditLog.ts new file mode 100644 index 00000000..b6685869 --- /dev/null +++ b/rest/v9/auditLog.ts @@ -0,0 +1,28 @@ +import type { Snowflake } from '../../globals'; +import type { APIAuditLog, AuditLogEvent } from '../../payloads/v9/auditLog'; + +/** + * https://discord.com/developers/docs/resources/audit-log#get-guild-audit-log + */ +export interface RESTGetAPIAuditLogQuery { + /** + * Filter the log for actions made by a user + */ + user_id?: Snowflake; + /** + * The type of audit log events + */ + action_type?: AuditLogEvent; + /** + * Filter the log before a certain entry ID + */ + before?: Snowflake; + /** + * How many entries are returned (default 50, minimum 1, maximum 100) + * + * @default 50 + */ + limit?: number; +} + +export type RESTGetAPIAuditLogResult = APIAuditLog; diff --git a/rest/v9/channel.ts b/rest/v9/channel.ts new file mode 100644 index 00000000..702bf3df --- /dev/null +++ b/rest/v9/channel.ts @@ -0,0 +1,553 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { + APIAllowedMentions, + APIChannel, + APIEmbed, + APIExtendedInvite, + APIFollowedChannel, + APIMessage, + APIMessageReference, + APIOverwrite, + APIThreadList, + APIThreadMember, + APIUser, + ChannelType, + InviteTargetType, + MessageFlags, + OverwriteType, + ThreadAutoArchiveDuration, + VideoQualityMode, +} from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel + */ +export type RESTGetAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export interface RESTPatchAPIChannelJSONBody { + /** + * 2-100 character channel name + * + * Channel types: all + */ + name?: string; + + /** + * The type of channel; only conversion between `text` and `news` + * is supported and only in guilds with the "NEWS" feature + * + * Channel types: text, news + */ + type?: ChannelType.GuildNews | ChannelType.GuildText; + /** + * The position of the channel in the left-hand listing + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + position?: number | null; + /** + * 0-1024 character channel topic + * + * Channel types: text, news + */ + topic?: string | null; + /** + * Whether the channel is nsfw + * + * Channel types: text, news, store + */ + nsfw?: boolean | null; + /** + * 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_CHANNELS`, + * are unaffected + * + * Channel types: text, newsThread, publicThread, privateThread + */ + rate_limit_per_user?: number | null; + /** + * The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers) + * + * Channel types: voice + */ + bitrate?: number | null; + /** + * The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit + * + * Channel types: voice + */ + user_limit?: number | null; + /** + * Channel or category-specific permissions + * + * Channel types: all excluding newsThread, publicThread, privateThread + */ + permission_overwrites?: APIOverwrite[] | null; + /** + * ID of the new parent category for a channel + * + * Channel types: text, news, store, voice + */ + parent_id?: Snowflake | null; + /** + * Voice region id for the voice or stage channel, automatic when set to `null` + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + rtc_region?: string | null; + /** + * The camera video quality mode of the voice channel + * + * See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes + */ + video_quality_mode?: VideoQualityMode | null; + /** + * Whether the thread should be archived + * + * Channel types: newsThread, publicThread, privateThread + */ + archived?: boolean; + /** + * The amount of time in minutes to wait before automatically archiving the thread + * + * Channel types: newsThread, publicThread, privateThread + */ + auto_archive_duration?: ThreadAutoArchiveDuration; + /** + * Whether the thread should be locked + * + * Channel types: newsThread, publicThread, privateThread + */ + locked?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/channel#modify-channel + */ +export type RESTPatchAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#deleteclose-channel + */ +export type RESTDeleteAPIChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export interface RESTGetAPIChannelMessagesQuery { + /** + * Get messages around this message ID + */ + around?: Snowflake; + /** + * Get messages before this message ID + */ + before?: Snowflake; + /** + * Get messages after this message ID + */ + after?: Snowflake; + /** + * Max number of messages to return (1-100) + * + * @default 50 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-messages + */ +export type RESTGetAPIChannelMessagesResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-message + */ +export type RESTGetAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ +export type APIMessageReferenceSend = Partial & + Required> & { + /** + * Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message + * + * @default true + */ + fail_if_not_exists?: boolean; + }; + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export interface RESTPostAPIChannelMessageJSONBody { + /** + * The message contents (up to 2000 characters) + */ + content?: string; + /** + * A nonce that can be used for optimistic message sending + */ + nonce?: number | string; + /** + * `true` if this is a TTS message + */ + tts?: boolean; + /** + * Embedded `rich` content + * + * See https://discord.com/developers/docs/resources/channel#embed-object + */ + embed?: APIEmbed; + /** + * Allowed mentions for a message + * + * See https://discord.com/developers/docs/resources/channel#allowed-mentions-object + */ + allowed_mentions?: APIAllowedMentions; + /** + * Include to make your message a reply + * + * See https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure + */ + message_reference?: APIMessageReferenceSend; +} + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIChannelMessageJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/channel#create-message + */ +export type RESTPostAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#crosspost-message + */ +export type RESTPostAPIChannelMessageCrosspostResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#create-reaction + */ +export type RESTPutAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-own-reaction + */ +export type RESTDeleteAPIChannelMessageOwnReaction = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-user-reaction + */ +export type RESTDeleteAPIChannelMessageUserReactionResult = never; + +/* + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export interface RESTGetAPIChannelMessageReactionUsersQuery { + /** + * Get users after this user ID + */ + after?: Snowflake; + /** + * Max number of users to return (1-100) + * + * @default 25 + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#get-reactions + */ +export type RESTGetAPIChannelMessageReactionUsersResult = APIUser[]; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions + */ +export type RESTDeleteAPIChannelAllMessageReactionsResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-all-reactions-for-emoji + */ +export type RESTDeleteAPIChannelMessageReactionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export interface RESTPatchAPIChannelMessageJSONBody { + /** + * The new message contents (up to 2000 characters) + */ + content?: string | null; + /** + * Embedded `rich` content + */ + embed?: APIEmbed | null; + /** + * Edit the flags of a message (only `SUPPRESS_EMBEDS` can currently be set/unset) + * + * When specifying flags, ensure to include all previously set flags/bits + * in addition to ones that you are modifying + */ + flags?: MessageFlags | null; + /** + * Allowed mentions for the message + */ + allowed_mentions?: APIAllowedMentions | null; +} + +/** + * https://discord.com/developers/docs/resources/channel#edit-message + */ +export type RESTPatchAPIChannelMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/channel#delete-message + */ +export type RESTDeleteAPIChannelMessageResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export interface RESTPostAPIChannelMessagesBulkDeleteJSONBody { + /** + * An array of message ids to delete (2-100) + */ + messages: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/channel#bulk-delete-messages + */ +export type RESTPostAPIChannelMessagesBulkDeleteResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export interface RESTPutAPIChannelPermissionJSONBody { + /** + * The bitwise value of all allowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + allow: Permissions; + /** + * The bitwise value of all disallowed permissions + * + * See https://en.wikipedia.org/wiki/Bit_field + */ + deny: Permissions; + /** + * `0` for a role or `1` for a member + */ + type: OverwriteType; +} + +/** + * https://discord.com/developers/docs/resources/channel#edit-channel-permissions + */ +export type RESTPutAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-channel-invites + */ +export type RESTGetAPIChannelInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export interface RESTPostAPIChannelInviteJSONBody { + /** + * Duration of invite in seconds before expiry, or 0 for never + * + * @default 86400 (24 hours) + */ + max_age?: number; + /** + * Max number of uses or 0 for unlimited + * + * @default 0 + */ + max_uses?: number; + /** + * Whether this invite only grants temporary membership + * + * @default false + */ + temporary?: boolean; + /** + * If true, don't try to reuse a similar invite + * (useful for creating many unique one time use invites) + * + * @default false + */ + unique?: boolean; + /** + * The type of target for this voice channel invite + * + * See https://discord.com/developers/docs/resources/invite#invite-object-invite-target-types + */ + target_type?: InviteTargetType; + /** + * The id of the user whose stream to display for this invite + * - Required if `target_type` is 1 + * - The user must be streaming in the channel + */ + target_user_id?: Snowflake; + /** + * The id of the embedded application to open for this invite + * - Required if `target_type` is 2 + * - The application must have the `EMBEDDED` flag + */ + target_application_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#create-channel-invite + */ +export type RESTPostAPIChannelInviteResult = APIExtendedInvite; + +/** + * https://discord.com/developers/docs/resources/channel#delete-channel-permission + */ +export type RESTDeleteAPIChannelPermissionResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export interface RESTPostAPIChannelFollowersJSONBody { + /** + * ID of target channel + */ + webhook_channel_id: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/channel#follow-news-channel + */ +export type RESTPostAPIChannelFollowersResult = APIFollowedChannel; + +/** + * https://discord.com/developers/docs/resources/channel#trigger-typing-indicator + */ +export type RESTPostAPIChannelTypingResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#get-pinned-messages + */ +export type RESTGetAPIChannelPinsResult = APIMessage[]; + +/** + * https://discord.com/developers/docs/resources/channel#add-pinned-channel-message + */ +export type RESTPutAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#delete-pinned-channel-message + */ +export type RESTDeleteAPIChannelPinResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export interface RESTPutAPIChannelRecipientJSONBody { + /** + * Access token of a user that has granted your app the `gdm.join` scope + */ + access_token: string; + /** + * Nickname of the user being added + */ + nick?: string; +} + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-add-recipient + */ +export type RESTPutAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#group-dm-remove-recipient + */ +export type RESTDeleteAPIChannelRecipientResult = unknown; + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-with-message + */ +export interface RESTPostAPIChannelThreadsJSONBody { + /** + * 2-100 character thread name + */ + name: string; + /** + * The amount of time in minutes to wait before automatically archiving the thread + */ + auto_archive_duration: ThreadAutoArchiveDuration; +} + +/** + * https://discord.com/developers/docs/resources/channel#start-thread-with-message + */ +export type RESTPostAPIChannelThreadsResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/channel#join-thread + */ +export type RESTPutAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#leave-thread + */ +export type RESTDeleteAPIChannelThreadMembersResult = never; + +/** + * https://discord.com/developers/docs/resources/channel#list-thread-members + */ +export type RESTGetAPIChannelThreadMembersResult = APIThreadMember[]; + +/* + * https://discord.com/developers/docs/resources/channel#list-public-archived-threads + */ +export interface RESTGetAPIChannelThreadsArchivedQuery { + /** + * Get threads before this id or ISO8601 timestamp + */ + before?: Snowflake | string; + /** + * Max number of thread to return + */ + limit?: number; +} + +/** + * https://discord.com/developers/docs/resources/channel#list-active-threads + */ +export type RESTGetAPIChannelThreadsResult = APIThreadList; + +/** + * https://discord.com/developers/docs/resources/channel#list-joined-private-archived-threads + */ +export type RESTGetAPIChannelUsersThreadsArchivedResult = APIThreadList; diff --git a/rest/v9/emoji.ts b/rest/v9/emoji.ts new file mode 100644 index 00000000..83bd8ffb --- /dev/null +++ b/rest/v9/emoji.ts @@ -0,0 +1,61 @@ +import type { Snowflake } from '../../globals'; +import type { APIEmoji } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/emoji#list-guild-emojis + */ +export type RESTGetAPIGuildEmojisResult = APIEmoji[]; + +/** + * https://discord.com/developers/docs/resources/emoji#get-guild-emoji + */ +export type RESTGetAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji-json-params + */ +export interface RESTPostAPIGuildEmojiJSONBody { + /** + * Name of the emoji + */ + name: string; + /** + * The 128x128 emoji image + * + * https://discord.com/developers/docs/reference#image-data + */ + image: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/emoji#create-guild-emoji + */ +export type RESTPostAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export interface RESTPatchAPIGuildEmojiJSONBody { + /** + * Name of the emoji + */ + name?: string; + /** + * Roles for which this emoji will be whitelisted + */ + roles?: Snowflake[] | null; +} + +/** + * https://discord.com/developers/docs/resources/emoji#modify-guild-emoji + */ +export type RESTPatchAPIGuildEmojiResult = APIEmoji; + +/** + * https://discord.com/developers/docs/resources/emoji#delete-guild-emoji + */ +export type RESTDeleteAPIGuildEmojiResult = never; diff --git a/rest/v9/gateway.ts b/rest/v9/gateway.ts new file mode 100644 index 00000000..61d329ae --- /dev/null +++ b/rest/v9/gateway.ts @@ -0,0 +1,11 @@ +import type { APIGatewayBotInfo, APIGatewayInfo } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway + */ +export type RESTGetAPIGatewayResult = APIGatewayInfo; + +/** + * https://discord.com/developers/docs/topics/gateway#get-gateway-bot + */ +export type RESTGetAPIGatewayBotResult = APIGatewayBotInfo; diff --git a/rest/v9/guild.ts b/rest/v9/guild.ts new file mode 100644 index 00000000..abc1ed72 --- /dev/null +++ b/rest/v9/guild.ts @@ -0,0 +1,780 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { + APIBan, + APIChannel, + APIExtendedInvite, + APIGuild, + APIGuildIntegration, + APIGuildMember, + APIGuildMembershipScreening, + APIGuildPreview, + APIGuildWelcomeScreen, + APIGuildWidget, + APIGuildWidgetSettings, + APIRole, + APIVoiceRegion, + GuildDefaultMessageNotifications, + GuildExplicitContentFilter, + GuildFeature, + GuildSystemChannelFlags, + GuildVerificationLevel, + GuildWidgetStyle, +} from '../../payloads/v9/index'; +import type { RESTPutAPIChannelPermissionJSONBody } from './channel'; + +export interface APIGuildCreateOverwrite extends RESTPutAPIChannelPermissionJSONBody { + id: number | string; +} + +export type APIGuildCreatePartialChannel = Partial< + Pick +> & { + name: string; + id?: number | string; + parent_id?: number | string | null; + permission_overwrites?: APIGuildCreateOverwrite[]; +}; + +export interface APIGuildCreateRole extends RESTPostAPIGuildRoleJSONBody { + id: number | string; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export interface RESTPostAPIGuildsJSONBody { + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter; + /** + * New guild roles + * + * **When using this parameter, the first member of the array is used to change properties of the guild's @everyone role. + * If you are trying to bootstrap a guild with additional roles, keep this in mind.** + * + * *When using this parameter, the required `id` field within each role object is an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to overwrite a role's permissions + * in a channel when also passing in channels with the channels array.* + * + * See https://discord.com/developers/docs/topics/permissions#role-object + */ + roles?: APIGuildCreateRole[]; + /** + * New guild's channels + * + * **When using the channels parameter, the `position` field is ignored, and none of the default channels are created.** + * + * *When using the channels parameter, the `id` field within each channel object may be set to an integer placeholder, + * and will be replaced by the API upon consumption. Its purpose is to allow you to create `GUILD_CATEGORY` channels + * by setting the `parent_id` field on any children to the category's id field. + * Category channels must be listed before any children.* + * + * See https://discord.com/developers/docs/resources/channel#channel-object + */ + channels?: APIGuildCreatePartialChannel[]; + /** + * ID for afk channel + */ + afk_channel_id?: number | Snowflake | null; + /** + * AFK timeout in seconds + */ + afk_timeout?: number; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id?: number | Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild + */ +export type RESTPostAPIGuildsResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export interface RESTGetAPIGuildQuery { + /** + * When `true`, will return approximate member and presence counts for the guild + * + * @default false + */ + with_counts?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild + */ +export type RESTGetAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-preview + */ +export type RESTGetAPIGuildPreviewResult = APIGuildPreview; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export interface RESTPatchAPIGuildJSONBody { + /** + * New name for the guild (2-100 characters) + */ + name?: string; + /** + * Voice region id + * + * See https://discord.com/developers/docs/resources/voice#voice-region-object + */ + region?: string | null; + /** + * Verification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-verification-level + */ + verification_level?: GuildVerificationLevel | null; + /** + * Default message notification level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-default-message-notification-level + */ + default_message_notifications?: GuildDefaultMessageNotifications | null; + /** + * Explicit content filter level + * + * See https://discord.com/developers/docs/resources/guild#guild-object-explicit-content-filter-level + */ + explicit_content_filter?: GuildExplicitContentFilter | null; + /** + * ID for afk channel + */ + afk_channel_id?: Snowflake | null; + /** + * AFK timeout in seconds + */ + afk_timeout?: number; + /** + * base64 1024x1024 png/jpeg/gif image for the guild icon (can be animated gif when the guild has `ANIMATED_ICON` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string | null; + /** + * User id to transfer guild ownership to (must be owner) + */ + owner_id?: Snowflake; + /** + * base64 16:9 png/jpeg image for the guild splash (when the guild has `INVITE_SPLASH` feature) + * + * See https://discord.com/developers/docs/reference#image-data + */ + splash?: string | null; + /** + * base64 png/jpeg image for the guild discovery splash (when the guild has `DISCOVERABLE` feature) + */ + discovery_splash?: string | null; + /** + * base64 16:9 png/jpeg image for the guild banner (when the guild has `BANNER` feature) + */ + banner?: string | null; + /** + * The id of the channel where guild notices such as welcome messages and boost events are posted + */ + system_channel_id?: Snowflake | null; + /** + * System channel flags + * + * See https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags + */ + system_channel_flags?: GuildSystemChannelFlags; + /** + * The id of the channel where Community guilds display rules and/or guidelines + */ + rules_channel_id?: Snowflake | null; + /** + * The id of the channel where admins and moderators of Community guilds receive notices from Discord + */ + public_updates_channel_id?: Snowflake | null; + /** + * The preferred locale of a Community guild used in server discovery and notices from Discord; defaults to "en-US" + * + * @default "en-US" (if the value is set to `null`) + */ + preferred_locale?: string | null; + /** + * Enabled guild features + * + * See https://discord.com/developers/docs/resources/guild#guild-object-guild-features + */ + features?: GuildFeature[]; + /** + * The description for the guild, if the guild is discoverable + */ + description?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild + */ +export type RESTPatchAPIGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild + */ +export type RESTDeleteAPIGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-channels + */ +export type RESTGetAPIGuildChannelsResult = APIChannel[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelJSONBody = Omit; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-channel + */ +export type RESTPostAPIGuildChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsJSONBody = Array<{ + /** + * Channel id + */ + id: Snowflake; + /** + * Sorting position of the channel + */ + position: number; + /** + * Sync channel overwrites with the new parent, when moving to a new `parent_id` + */ + lock_permissions?: boolean; + /** + * The new parent id of this channel + */ + parent_id?: Snowflake | null; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-channel-positions + */ +export type RESTPatchAPIGuildChannelPositionsResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-member + */ +export type RESTGetAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export interface RESTGetAPIGuildMembersQuery { + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; + /** + * The highest user id in the previous page + * + * @default 0 + */ + after?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/guild#list-guild-members + */ +export type RESTGetAPIGuildMembersResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#search-guild-members + */ +export interface RESTGetAPIGuildMembersSearchQuery { + /** + * Query string to match username(s) and nickname(s) against + */ + query: string; + /** + * Max number of members to return (1-1000) + * + * @default 1 + */ + limit?: number; +} + +export type RESTGetAPIGuildMembersSearchResult = APIGuildMember[]; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export interface RESTPutAPIGuildMemberJSONBody { + /** + * An oauth2 access token granted with the `guilds.join` to the bot's application for the user you want to add to the guild + */ + access_token: string; + /** + * Value to set users nickname to + * + * Requires `MANAGE_NICKNAMES` permission + */ + nick?: string; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[]; + /** + * Whether the user is muted in voice channels + * + * Requires `MUTE_MEMBERS` permission + */ + mute?: boolean; + /** + * Whether the user is deafened in voice channels + * + * Requires `DEAFEN_MEMBERS` permission + */ + deaf?: boolean; +} + +export type RESTPutAPIGuildMemberResult = APIGuildMember | undefined; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-member + */ +export interface RESTPatchAPIGuildMemberJSONBody { + /** + * Value to set users nickname to + * + * Requires `MANAGE_NICKNAMES` permission + */ + nick?: string | null; + /** + * Array of role ids the member is assigned + * + * Requires `MANAGE_ROLES` permission + */ + roles?: Snowflake[] | null; + /** + * Whether the user is muted in voice channels. Will throw a 400 if the user is not in a voice channel + * + * Requires `MUTE_MEMBERS` permission + */ + mute?: boolean | null; + /** + * Whether the user is deafened in voice channels. Will throw a 400 if the user is not in a voice channel + * + * Requires `DEAFEN_MEMBERS` permission + */ + deaf?: boolean | null; + /** + * ID of channel to move user to (if they are connected to voice) + * + * Requires `MOVE_MEMBERS` permission + */ + channel_id?: Snowflake | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member + */ +export type RESTPatchAPIGuildMemberResult = APIGuildMember; + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + */ +export interface RESTPatchAPICurrentGuildMemberNicknameJSONBody { + /** + * Value to set users nickname to + * + * Requires `CHANGE_NICKNAME` permission + */ + nick?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-current-user-nick + */ +export type RESTPatchAPICurrentGuildMemberNicknameResult = Required; + +/** + * https://discord.com/developers/docs/resources/guild#add-guild-member-role + */ +export type RESTPutAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member-role + */ +export type RESTDeleteAPIGuildMemberRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-member + */ +export type RESTDeleteAPIGuildMemberResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-bans + */ +export type RESTGetAPIGuildBansResult = APIBan[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-ban + */ +export type RESTGetAPIGuildBanResult = APIBan; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export interface RESTPutAPIGuildBanJSONBody { + /** + * Number of days to delete messages for (0-7) + */ + delete_message_days?: number; + /** + * Reason for the ban + */ + reason?: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-ban + */ +export type RESTPutAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#remove-guild-ban + */ +export type RESTDeleteAPIGuildBanResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-roles + */ +export type RESTGetAPIGuildRolesResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export interface RESTPostAPIGuildRoleJSONBody { + /** + * Name of the role + * + * @default "new role" + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + * + * @default "​default role permissions in guild" + */ + permissions?: Permissions | null; + /** + * RGB color value + * + * @default 0 + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + * + * @default false + */ + hoist?: boolean | null; + /** + * Whether the role should be mentionable + * + * @default false + */ + mentionable?: boolean | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#create-guild-role + */ +export type RESTPostAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsJSONBody = Array<{ + /** + * Role id + */ + id: Snowflake; + /** + * Sorting position of the role + */ + position?: number; +}>; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role-positions + */ +export type RESTPatchAPIGuildRolePositionsResult = APIRole[]; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export interface RESTPatchAPIGuildRoleJSONBody { + /** + * Name of the role + */ + name?: string | null; + /** + * Bitwise value of the enabled/disabled permissions + */ + permissions?: Permissions | null; + /** + * RGB color value + */ + color?: number | null; + /** + * Whether the role should be displayed separately in the sidebar + */ + hoist?: boolean | null; + /** + * Whether the role should be mentionable + */ + mentionable?: boolean | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-role + */ +export type RESTPatchAPIGuildRoleResult = APIRole; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-role + */ +export type RESTDeleteAPIGuildRoleResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountQuery { + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Role(s) to include + * + * While this is typed as a string, it represents an array of + * role IDs delimited by commas + * + * See https://discord.com/developers/docs/resources/guild#get-guild-prune-count-query-string-params + */ + include_roles?: string; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-prune-count + */ +export interface RESTGetAPIGuildPruneCountResult { + pruned: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export interface RESTPostAPIGuildPruneJSONBody { + /** + * Number of days to count prune for (1 or more) + * + * @default 7 + */ + days?: number; + /** + * Whether `pruned is returned, discouraged for large guilds + * + * @default true + */ + compute_prune_count?: boolean; + /** + * Role(s) to include + */ + include_roles?: Snowflake[]; +} + +/** + * https://discord.com/developers/docs/resources/guild#begin-guild-prune + */ +export interface RESTPostAPIGuildPruneResult { + pruned: number | null; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-voice-regions + */ +export type RESTGetAPIGuildVoiceRegionsResult = APIVoiceRegion[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-invites + */ +export type RESTGetAPIGuildInvitesResult = APIExtendedInvite[]; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-integrations + */ +export type RESTGetAPIGuildIntegrationsResult = APIGuildIntegration[]; + +/** + * https://discord.com/developers/docs/resources/guild#delete-guild-integration + */ +export type RESTDeleteAPIGuildIntegrationResult = never; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-settings + */ +export type RESTGetAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsJSONBody = Partial; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-widget + */ +export type RESTPatchAPIGuildWidgetSettingsResult = APIGuildWidgetSettings; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget + */ +export type RESTGetAPIGuildWidgetJSONResult = APIGuildWidget; + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-vanity-url + */ +export interface RESTGetAPIGuildVanityUrlResult { + code: string | null; + uses: number; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-widget-image + */ +export interface RESTGetAPIGuildWidgetImageQuery { + /** + * Style of the widget image returned + * + * @default "shield" + */ + style?: GuildWidgetStyle; +} + +/** + * Note: while the return type is `ArrayBuffer`, the expected result is + * a buffer of sorts (depends if in browser or on node.js/deno). + */ +export type RESTGetAPIGuildWidgetImageResult = ArrayBuffer; + +export type RESTGetAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +export interface RESTPatchAPIGuildMemberVerificationJSONBody { + /** + * Whether Membership Screening is enabled + */ + enabled?: boolean; + /** + * Array of field objects serialized in a string + */ + form_fields?: string; + /** + * The server description to show in the screening form + */ + description?: string | null; +} + +export type RESTPatchAPIGuildMemberVerificationResult = APIGuildMembershipScreening; + +export interface RESTPatchAPIGuildVoiceStateCurrentMemberJSONBody { + /** + * The id of the channel the user is currently in + */ + channel_id: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; + /** + * Sets the user's request to speak + */ + request_to_speak_timestamp?: string | null; +} + +export interface RESTPatchAPIGuildVoiceStateUserJSONBody { + /** + * The id of the channel the user is currently in + */ + channel_id: Snowflake; + /** + * Toggles the user's suppress state + */ + suppress?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/guild#get-guild-welcome-screen + */ +export type RESTGetAPIGuildWelcomeScreenResult = APIGuildWelcomeScreen; + +/** + * https://discord.com/developers/docs/resources/guild#modify-guild-welcome-screen + */ +export interface RESTPatchAPIGuildWelcomeScreenJSONBody extends Nullable> { + /** + * Whether the welcome screen is enabled + */ + enabled?: boolean | null; +} + +type Nullable = { + [P in keyof T]: T[P] | null; +}; diff --git a/rest/v9/index.ts b/rest/v9/index.ts new file mode 100644 index 00000000..6a3c8e1f --- /dev/null +++ b/rest/v9/index.ts @@ -0,0 +1,743 @@ +import type { Snowflake } from '../../globals'; + +export * from '../common'; + +export * from './auditLog'; +export * from './channel'; +export * from './emoji'; +export * from './gateway'; +export * from './guild'; +export * from './interactions'; +export * from './invite'; +export * from './oauth2'; +export * from './template'; +export * from './user'; +export * from './voice'; +export * from './webhook'; + +export const APIVersion = '9'; + +export const Routes = { + /** + * Route for: + * - GET `/guilds/{guild.id}/audit-logs` + */ + guildAuditLog(guildID: Snowflake) { + return `/guilds/${guildID}/audit-logs` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}` + * - PATCH `/channels/{channel.id}` + * - DELETE `/channels/{channel.id}` + */ + channel(channelID: Snowflake) { + return `/channels/${channelID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages` + * - POST `/channels/{channel.id}/messages` + */ + channelMessages(channelID: Snowflake) { + return `/channels/${channelID}/messages` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}` + * - PATCH `/channels/{channel.id}/messages/{message.id}` + * - DELETE `/channels/{channel.id}/messages/{message.id}` + */ + channelMessage(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/{message.id}/crosspost` + */ + channelMessageCrosspost(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/crosspost` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageOwnReaction(channelID: Snowflake, messageID: Snowflake, emoji: string) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}/@me` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{user.id}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageUserReaction(channelID: Snowflake, messageID: Snowflake, emoji: string, userID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}/${userID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions/{emoji}` + * + * **Note**: You need to URL encode the emoji yourself + */ + channelMessageReaction(channelID: Snowflake, messageID: Snowflake, emoji: string) { + return `/channels/${channelID}/messages/${messageID}/reactions/${emoji}` as const; + }, + + /** + * Route for: + * - DELETE `/channels/{channel.id}/messages/{message.id}/reactions` + */ + channelMessageAllReactions(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/messages/${messageID}/reactions` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/messages/bulk-delete` + */ + channelBulkDelete(channelID: Snowflake) { + return `/channels/${channelID}/messages/bulk-delete` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/permissions/{overwrite.id}` + * - DELETE `/channels/{channel.id}/permissions/{overwrite.id}` + */ + channelPermission(channelID: Snowflake, overwriteID: Snowflake) { + return `/channels/${channelID}/permissions/${overwriteID}` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/invites` + * - POST `/channels/{channel.id}/invites` + */ + channelInvites(channelID: Snowflake) { + return `/channels/${channelID}/invites` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/followers` + */ + channelFollowers(channelID: Snowflake) { + return `/channels/${channelID}/followers` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/typing` + */ + channelTyping(channelID: Snowflake) { + return `/channels/${channelID}/typing` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/pins` + */ + channelPins(channelID: Snowflake) { + return `/channels/${channelID}/pins` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/pins/{message.id}` + * - DELETE `/channels/{channel.id}/pins/{message.id}` + */ + channelPin(channelID: Snowflake, messageID: Snowflake) { + return `/channels/${channelID}/pins/${messageID}` as const; + }, + + /** + * Route for: + * - PUT `/channels/{channel.id}/recipients/{user.id}` + * - DELETE `/channels/{channel.id}/recipients/{user.id}` + */ + channelRecipient(channelID: Snowflake, userID: Snowflake) { + return `/channels/${channelID}/recipients/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis` + * - POST `/guilds/{guild.id}/emojis` + */ + guildEmojis(guildID: Snowflake) { + return `/guilds/${guildID}/emojis` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/emojis/{emoji.id}` + * - PATCH `/guilds/{guild.id}/emojis/{emoji.id}` + * - DELETE `/guilds/{guild.id}/emojis/{emoji.id}` + */ + guildEmoji(guildID: Snowflake, emojiID: Snowflake) { + return `/guilds/${guildID}/emojis/${emojiID}` as const; + }, + + /** + * Route for: + * - POST `/guilds` + */ + guilds() { + return '/guilds' as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}` + * - PATCH `/guilds/{guild.id}` + * - DELETE `/guilds/{guild.id}` + */ + guild(guildID: Snowflake) { + return `/guilds/${guildID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/preview` + */ + guildPreview(guildID: Snowflake) { + return `/guilds/${guildID}/preview` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/channels` + * - POST `/guilds/{guild.id}/channels` + * - PATCH `/guilds/{guild.id}/channels` + */ + guildChannels(guildID: Snowflake) { + return `/guilds/${guildID}/channels` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/{user.id}` + * - PUT `/guilds/{guild.id}/members/{user.id}` + * - PATCH `/guilds/{guild.id}/members/{user.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}` + */ + guildMember(guildID: Snowflake, userID: Snowflake) { + return `/guilds/${guildID}/members/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members` + */ + guildMembers(guildID: Snowflake) { + return `/guilds/${guildID}/members` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/members/search` + */ + guildMembersSearch(guildID: Snowflake) { + return `/guilds/${guildID}/members/search` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/members/@me/nick` + */ + guildCurrentMemberNickname(guildID: Snowflake) { + return `/guilds/${guildID}/members/@me/nick` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/members/{user.id}/roles/{role.id}` + */ + guildMemberRole(guildID: Snowflake, memberID: Snowflake, roleID: Snowflake) { + return `/guilds/${guildID}/members/${memberID}/roles/${roleID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans` + */ + guildBans(guildID: Snowflake) { + return `/guilds/${guildID}/bans` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/bans/{user.id}` + * - PUT `/guilds/{guild.id}/bans/{user.id}` + * - DELETE `/guilds/{guild.id}/bans/{user.id}` + */ + guildBan(guildID: Snowflake, userID: Snowflake) { + return `/guilds/${guildID}/bans/${userID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/roles` + * - POST `/guilds/{guild.id}/roles` + * - PATCH `/guilds/{guild.id}/roles` + */ + guildRoles(guildID: Snowflake) { + return `/guilds/${guildID}/roles` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/roles/{role.id}` + * - DELETE `/guilds/{guild.id}/roles/{role.id}` + */ + guildRole(guildID: Snowflake, roleID: Snowflake) { + return `/guilds/${guildID}/roles/${roleID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/prune` + * - POST `/guilds/{guild.id}/prune` + */ + guildPrune(guildID: Snowflake) { + return `/guilds/${guildID}/prune` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/regions` + */ + guildVoiceRegions(guildID: Snowflake) { + return `/guilds/${guildID}/regions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/invites` + */ + guildInvites(guildID: Snowflake) { + return `/guilds/${guildID}/invites` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/integrations` + */ + guildIntegrations(guildID: Snowflake) { + return `/guilds/${guildID}/integrations` as const; + }, + + /** + * Route for: + * - DELETE `/guilds/{guild.id}/integrations/{integration.id}` + */ + guildIntegration(guildID: Snowflake, integrationID: Snowflake) { + return `/guilds/${guildID}/integrations/${integrationID}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget` + * - PATCH `/guilds/{guild.id}/widget` + */ + guildWidgetSettings(guildID: Snowflake) { + return `/guilds/${guildID}/widget` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.json` + */ + guildWidgetJSON(guildID: Snowflake) { + return `/guilds/${guildID}/widget.json` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/vanity-url` + */ + guildVanityUrl(guildID: Snowflake) { + return `/guilds/${guildID}/vanity-url` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/widget.png` + */ + guildWidgetImage(guildID: Snowflake) { + return `/guilds/${guildID}/widget.png` as const; + }, + + /** + * Route for: + * - GET `/invites/{invite.code}` + * - DELETE `/invites/{invite.code}` + */ + invite(code: string) { + return `/invites/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/templates/{template.code}` + * - POST `/guilds/templates/{template.code}` + */ + template(code: string) { + return `/guilds/templates/${code}` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/templates` + * - POST `/guilds/{guild.id}/templates` + */ + guildTemplates(guildID: Snowflake) { + return `/guilds/${guildID}/templates` as const; + }, + + /** + * Route for: + * - PUT `/guilds/{guild.id}/templates/{template.code}` + * - PATCH `/guilds/{guild.id}/templates/{template.code}` + * - DELETE `/guilds/{guild.id}/templates/{template.code}` + */ + guildTemplate(guildID: Snowflake, code: string) { + return `/guilds/${guildID}/templates/${code}` as const; + }, + + /** + * Route for: + * - POST `/channels/{channel.id}/threads` + * - POST `/channels/{channel.id}/messages/{message.id}/threads` + */ + threads(parentID: Snowflake, messageID?: Snowflake) { + const parts = ['', 'channels', parentID]; + + if (messageID) parts.push('messages', messageID); + + parts.push('threads'); + + return parts.join('/') as `/channels/${Snowflake}/threads` | `/channels/${Snowflake}/messages/${Snowflake}/threads`; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/threads/active` + * - GET `/channels/{channel.id}/threads/archived/public` + * - GET `/channels/{channel.id}/threads/archived/private` + */ + channelThreads(channelID: Snowflake, archived?: 'public' | 'private') { + const parts = ['', 'channels', channelID, 'threads']; + + if (archived) parts.push('archived', archived); + else parts.push('active'); + + return parts.join('/') as + | `/channels/${Snowflake}/threads/active` + | `/channels/${Snowflake}/threads/archived/${'public' | 'private'}`; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/users/@me/threads/archived/prviate` + */ + channelJoinedArhivedThreads(channelID: Snowflake) { + return `/channels/${channelID}/users/@me/threads/archived/private` as const; + }, + + /** + * Route for: + * - GET `/channels/{thread.id}/thread-members` + * - PUT `/channels/{thread.id}/thread-members/@me` + * - PUT `/channels/{thread.id}/thread-members/{user.id}` + * - DELETE `/channels/{thread.id}/thread-members/@me` + * - DELETE `/channels/{thread.id}/thread-members/{user.id}` + */ + threadMembers(threadID: Snowflake, userID?: Snowflake | '@me') { + const parts = ['', 'channels', threadID, 'thread-members']; + + if (userID) parts.push(userID); + + return parts.join('/') as + | `/channels/${Snowflake}/thread-members` + | `/channels/${Snowflake}/thread-members/${Snowflake | '@me'}`; + }, + + /** + * Route for: + * - GET `/users/@me` + * - GET `/users/{user.id}` + * - PATCH `/users/@me` + * + * @param [userID='@me'] The user ID, defaulted to `@me` + */ + user(userID: Snowflake | '@me' = '@me') { + return `/users/${userID}` as const; + }, + + /** + * Route for: + * - GET `/users/@me/guilds` + */ + userGuilds() { + return `/users/@me/guilds` as const; + }, + + /** + * Route for: + * - DELETE `/users/@me/guilds/{guild.id}` + */ + userGuild(guildID: Snowflake) { + return `/users/@me/guilds/${guildID}` as const; + }, + + /** + * Route for: + * - POST `/users/@me/channels` + */ + userChannels() { + return `/users/@me/channels` as const; + }, + + /** + * Route for: + * - GET `/users/@me/connections` + */ + userConnections() { + return `/users/@me/connections` as const; + }, + + /** + * Route for: + * - GET `/voice/regions` + */ + voiceRegions() { + return `/voice/regions` as const; + }, + + /** + * Route for: + * - GET `/channels/{channel.id}/webhooks` + * - POST `/channels/{channel.id}/webhooks` + */ + channelWebhooks(channelID: Snowflake) { + return `/channels/${channelID}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/webhooks` + */ + guildWebhooks(guildID: Snowflake) { + return `/guilds/${guildID}/webhooks` as const; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}` + * - GET `/webhooks/{webhook.id}/{webhook.token}` + * - PATCH `/webhooks/{webhook.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}` + * - DELETE `/webhooks/{webhook.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}` + * - POST `/webhooks/{webhook.id}/{webhook.token}` + * + * - POST `/webhooks/{application.id}/{interaction.token}` + */ + webhook(webhookID: Snowflake, webhookToken?: string) { + const parts = ['', 'webhooks', webhookID]; + + if (webhookToken) parts.push(webhookToken); + + return parts.join('/') as `/webhooks/${Snowflake}` | `/webhooks/${Snowflake}/${string}`; + }, + + /** + * Route for: + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - GET `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - PATCH `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/@original` + * - DELETE `/webhooks/{webhook.id}/{webhook.token}/messages/{message.id}` + * + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/@original` + * - PATCH `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * - DELETE `/webhooks/{application.id}/{interaction.token}/messages/{message.id}` + * + * @param [messageID='@original'] The message ID to change, defaulted to `@original` + */ + webhookMessage(webhookID: Snowflake, webhookToken: string, messageID: Snowflake | '@original' = '@original') { + return `/webhooks/${webhookID}/${webhookToken}/messages/${messageID}` as const; + }, + + /** + * Route for: + * - POST `/webhooks/{webhook.id}/{webhook.token}/github` + * - POST `/webhooks/{webhook.id}/{webhook.token}/slack` + */ + webhookPlatform(webhookID: Snowflake, webhookToken: string, platform: 'github' | 'slack') { + return `/webhooks/${webhookID}/${webhookToken}/${platform}` as const; + }, + + /** + * Route for: + * - GET `/gateway` + */ + gateway() { + return `/gateway` as const; + }, + + /** + * Route for: + * - GET `/gateway/bot` + */ + gatewayBot() { + return `/gateway/bot` as const; + }, + + /** + * Route for: + * - GET `/oauth2/applications/@me` + */ + oauth2CurrentApplication() { + return `/oauth2/applications/@me` as const; + }, + + /** + * Route for: + * - GET `/oauth2/@me` + */ + oauth2CurrentAuthorization() { + return `/oauth2/@me` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands` + * - PUT `/applications/{application.id}/commands` + * - POST `/applications/{application.id}/commands` + */ + applicationCommands(applicationID: Snowflake) { + return `/applications/${applicationID}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/commands/{command.id}` + */ + applicationCommand(applicationID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/commands/${commandID}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands` + * - POST `/applications/{application.id}/guilds/{guild.id}/commands` + */ + applicationGuildCommands(applicationID: Snowflake, guildID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - PATCH `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + * - DELETE `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` + */ + applicationGuildCommand(applicationID: Snowflake, guildID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}` as const; + }, + + /** + * Route for: + * - POST `/interactions/{interaction.id}/{interaction.token}/callback` + */ + interactionCallback(interactionID: Snowflake, interactionToken: string) { + return `/interactions/${interactionID}/${interactionToken}/callback` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/member-verification` + * - PATCH `/guilds/{guild.id}/member-verification` + */ + guildMemberVerification(guildID: Snowflake) { + return `/guilds/${guildID}/member-verification` as const; + }, + + /** + * Route for: + * - PATCH `/guilds/{guild.id}/voice-states/@me` + * - PATCH `/guilds/{guild.id}/voice-states/{user.id}` + */ + guildVoiceState(guildID: Snowflake, userID: Snowflake | '@me' = '@me') { + return `/guilds/${guildID}/voice-states/${userID}` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/permissions` + */ + guildApplicationCommandsPermissions(applicationID: Snowflake, guildID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/permissions` as const; + }, + + /** + * Route for: + * - GET `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + * - PUT `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions` + */ + applicationCommandPermissions(applicationID: Snowflake, guildID: Snowflake, commandID: Snowflake) { + return `/applications/${applicationID}/guilds/${guildID}/commands/${commandID}/permissions` as const; + }, + + /** + * Route for: + * - GET `/guilds/{guild.id}/welcome-screen` + * - PATCH `/guilds/{guild.id}/welcome-screen` + */ + guildWelcomeScreen(guildID: Snowflake) { + return `/guilds/${guildID}/welcome-screen` as const; + }, +}; + +export const RouteBases = { + api: 'https://discord.com/api', + cdn: 'https://cdn.discordapp.com', + invite: 'https://discord.gg', + template: 'https://discord.new', + gift: 'https://discord.gift', +} as const; + +// Freeze bases object +Object.freeze(RouteBases); + +export const OAuth2Routes = { + authorizationURL: `https://discord.com/api/v${APIVersion}/oauth2/authorize`, + tokenURL: `https://discord.com/api/v${APIVersion}/oauth2/token`, + /** + * See https://tools.ietf.org/html/rfc7009 + */ + tokenRevocationURL: `https://discord.com/api/v${APIVersion}/oauth2/token/revoke`, +} as const; + +// Freeze OAuth2 route object +Object.freeze(OAuth2Routes); diff --git a/rest/v9/interactions.ts b/rest/v9/interactions.ts new file mode 100644 index 00000000..943d7b55 --- /dev/null +++ b/rest/v9/interactions.ts @@ -0,0 +1,147 @@ +import type { + APIApplicationCommand, + APIApplicationCommandPermission, + APIGuildApplicationCommandPermissions, + APIInteractionResponse, +} from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-global-application-commands + */ +export type RESTGetAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-global-application-command + */ +export type RESTGetAPIApplicationCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsJSONBody = Omit; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-global-application-command + */ +export type RESTPostAPIApplicationCommandsResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandJSONBody = Partial; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-global-application-command + */ +export type RESTPatchAPIApplicationCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-commands + */ +export type RESTGetAPIApplicationGuildCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-command + */ +export type RESTGetAPIApplicationGuildCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-guild-application-command + */ +export type RESTPostAPIApplicationGuildCommandsResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandJSONBody = Partial; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-guild-application-command + */ +export type RESTPatchAPIApplicationGuildCommandResult = APIApplicationCommand; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsJSONBody = RESTPostAPIApplicationCommandsJSONBody[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#bulk-overwrite-global-application-commands + */ +export type RESTPutAPIApplicationGuildCommandsResult = APIApplicationCommand[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackJSONBody = APIInteractionResponse; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#create-interaction-response + */ +export type RESTPostAPIInteractionCallbackFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIInteractionCallbackJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-guild-application-command-permissions + */ +export type RESTGetAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#get-application-command-permissions + */ +export type RESTGetAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-application-command-permissions + */ +export interface RESTPutAPIApplicationCommandPermissionsJSONBody { + permissions: APIApplicationCommandPermission[]; +} + +/** + * https://discord.com/developers/docs/interactions/slash-commands#edit-application-command-permissions + */ +export type RESTPutAPIApplicationCommandPermissionsResult = APIGuildApplicationCommandPermissions; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsJSONBody = Pick< + APIGuildApplicationCommandPermissions, + 'id' | 'permissions' +>[]; + +/** + * https://discord.com/developers/docs/interactions/slash-commands#batch-edit-application-command-permissions + */ +export type RESTPutAPIGuildApplicationCommandsPermissionsResult = APIGuildApplicationCommandPermissions[]; diff --git a/rest/v9/invite.ts b/rest/v9/invite.ts new file mode 100644 index 00000000..33f31414 --- /dev/null +++ b/rest/v9/invite.ts @@ -0,0 +1,22 @@ +import type { APIInvite } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/invite#get-invite + */ +export interface RESTGetAPIInviteQuery { + /** + * Whether the invite should contain approximate member counts + */ + with_counts?: boolean; + /** + * Whether the invite should contain the expiration date + */ + with_expiration?: boolean; +} + +export type RESTGetAPIInviteResult = APIInvite; + +/** + * https://discord.com/developers/docs/resources/invite#delete-invite + */ +export type RESTDeleteAPIInviteResult = APIInvite; diff --git a/rest/v9/oauth2.ts b/rest/v9/oauth2.ts new file mode 100644 index 00000000..8eb51e99 --- /dev/null +++ b/rest/v9/oauth2.ts @@ -0,0 +1,199 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { APIApplication, APIGuild, APIUser, APIWebhook, OAuth2Scopes } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-application-information + */ +export type RESTGetAPIOAuth2CurrentApplicationResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#get-current-authorization-information + */ +export interface RESTGetAPIOAuth2CurrentAuthorizationResult { + /** + * the current application + */ + application: Partial; + /** + * the scopes the user has authorized the application for + */ + scopes: OAuth2Scopes[]; + /** + * when the access token expires + */ + expires: string; + /** + * the user who has authorized, if the user has authorized with the `identify` scope + */ + user?: APIUser; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant + */ +export interface RESTOAuth2AuthorizationQuery { + response_type: 'code'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTOAuth2AuthorizationQueryResult { + code: string; + state?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-redirect-url-example + */ +export interface RESTPostOAuth2AccessTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'authorization_code'; + code: string; + redirect_uri?: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-access-token-response + */ +export interface RESTPostOAuth2AccessTokenResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#authorization-code-grant-refresh-token-exchange-example + */ +export interface RESTPostOAuth2RefreshTokenURLEncodedData { + client_id: Snowflake; + client_secret: string; + grant_type: 'refresh_token'; + refresh_token: string; +} + +export type RESTPostOAuth2RefreshTokenResult = RESTPostOAuth2AccessTokenResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant + */ +export interface RESTOAuth2ImplicitAuthorizationQuery { + response_type: 'token'; + client_id: Snowflake; + scope: string; + redirect_uri?: string; + state?: string; + prompt?: 'consent' | 'none'; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#implicit-grant-redirect-url-example + */ +export type RESTOAuth2ImplicitAuthorizationURLFragmentResult = Omit; + +/** + * https://discord.com/developers/docs/topics/oauth2#client-credentials-grant + */ +export interface RESTPostOAuth2ClientCredentialsURLEncodedData { + grant_type: 'client_credentials'; + scope: string; +} + +export type RESTPostOAuth2ClientCredentialsResult = RESTOAuth2ImplicitAuthorizationURLFragmentResult; + +/** + * https://discord.com/developers/docs/topics/oauth2#bot-authorization-flow-bot-auth-parameters + */ +export interface RESTOAuth2BotAuthorizationQuery { + /** + * Your app's client id + */ + client_id: Snowflake; + /** + * Needs to include bot for the bot flow + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The permissions you're requesting + * + * See https://discord.com/developers/docs/topics/permissions + */ + permissions?: Permissions; + /** + * Pre-fills the dropdown picker with a guild for the user + */ + guild_id?: Snowflake; + /** + * `true` or `false`—disallows the user from changing the guild dropdown + */ + disable_guild_select?: boolean; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization + */ +export interface RESTOAuth2AdvancedBotAuthorizationQuery { + client_id: Snowflake; + /** + * This assumes you include the `bot` scope alongside others (like `identify` for example) + */ + scope: + | OAuth2Scopes.Bot + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}` + | `${OAuth2Scopes.Bot}${' ' | '%20'}${string}` + | `${string}${' ' | '%20'}${OAuth2Scopes.Bot}${string}${' ' | '%20'}`; + /** + * The required permissions bitfield, stringified + */ + permissions?: Permissions; + guild_id?: Snowflake; + disable_guild_select?: boolean; + response_type: string; + redirect_uri?: string; +} + +export interface RESTOAuth2AdvancedBotAuthorizationQueryResult { + code: string; + state?: string; + guild_id: Snowflake; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#advanced-bot-authorization-extended-bot-authorization-access-token-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + guild: APIGuild; +} + +/** + * https://discord.com/developers/docs/topics/oauth2#webhooks-webhook-token-response-example + */ +export interface RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; + webhook: APIWebhook; +} + +export type RESTPostOAuth2AccessTokenWithBotAndGuildsAndWebhookIncomingScopeResult = RESTPostOAuth2AccessTokenWithBotAndGuildsScopeResult & + RESTPostOAuth2AccessTokenWithBotAndWebhookIncomingScopeResult; diff --git a/rest/v9/template.ts b/rest/v9/template.ts new file mode 100644 index 00000000..3cc873c8 --- /dev/null +++ b/rest/v9/template.ts @@ -0,0 +1,70 @@ +import type { APIGuild, APITemplate } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/template#get-template + */ +export type RESTGetAPITemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#create-guild-from-template + */ +export interface RESTPostAPITemplateCreateGuildJSONBody { + /** + * Name of the guild (2-100 characters) + */ + name: string; + /** + * base64 1024x1024 png/jpeg image for the guild icon + * + * See https://discord.com/developers/docs/reference#image-data + */ + icon?: string; +} +/** + * https://discord.com/developers/docs/resources/template#create-guild-from-template + */ +export type RESTPostAPITemplateCreateGuildResult = APIGuild; + +/** + * https://discord.com/developers/docs/resources/template#get-guild-templates + */ +export type RESTGetAPIGuildTemplatesResult = APITemplate[]; + +/** + * https://discord.com/developers/docs/resources/template#create-guild-template + */ +export interface RESTPostAPIGuildTemplatesJSONBody { + /** + * Name of the template (1-100 characters) + */ + name: string; + /** + * Description for the template (0-120 characters) + */ + description?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/template#create-guild-template + */ +export type RESTPostAPIGuildTemplatesResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#sync-guild-template + */ +export type RESTPutAPIGuildTemplateSyncResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateJSONBody = Partial; + +/** + * https://discord.com/developers/docs/resources/template#modify-guild-template + */ +export type RESTPatchAPIGuildTemplateResult = APITemplate; + +/** + * https://discord.com/developers/docs/resources/template#delete-guild-template + */ +export type RESTDeleteAPIGuildTemplateResult = APITemplate; diff --git a/rest/v9/user.ts b/rest/v9/user.ts new file mode 100644 index 00000000..927ffc20 --- /dev/null +++ b/rest/v9/user.ts @@ -0,0 +1,90 @@ +import type { Permissions, Snowflake } from '../../globals'; +import type { APIChannel, APIConnection, APIUser, GuildFeature } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user + */ +export type RESTGetAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-user + */ +export type RESTGetAPIUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export interface RESTPatchAPICurrentUserJSONBody { + /** + * User's username, if changed may cause the user's discriminator to be randomized + */ + username?: string; + /** + * If passed, modifies the user's avatar + */ + avatar?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/user#modify-current-user + */ +export type RESTPatchAPICurrentUserResult = APIUser; + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export interface RESTGetAPICurrentUserGuildsQuery { + /** + * Get guilds before this guild ID + */ + before?: Snowflake; + /** + * Get guilds after this guild ID + */ + after?: Snowflake; + /** + * Max number of guilds to return (1-100) + * + * @default 100 + */ + limit?: number; +} + +export interface RESTAPIPartialCurrentUserGuild { + id: Snowflake; + name: string; + icon: string | null; + owner: boolean; + features: GuildFeature[]; + permissions: Permissions; +} + +/** + * https://discord.com/developers/docs/resources/user#get-current-user-guilds + */ +export type RESTGetAPICurrentUserGuildsResult = RESTAPIPartialCurrentUserGuild[]; + +/** + * https://discord.com/developers/docs/resources/user#leave-guild + */ +export type RESTDeleteAPICurrentUserGuildResult = never; + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export interface RESTPostAPICurrentUserCreateDMChannelJSONBody { + /** + * The recipient to open a DM channel with + */ + recipient_id: string; +} + +/** + * https://discord.com/developers/docs/resources/user#create-dm + */ +export type RESTPostAPICurrentUserCreateDMChannelResult = APIChannel; + +/** + * https://discord.com/developers/docs/resources/user#get-user-connections + */ +export type RESTGetAPICurrentUserConnectionsResult = APIConnection[]; diff --git a/rest/v9/voice.ts b/rest/v9/voice.ts new file mode 100644 index 00000000..f6c994b0 --- /dev/null +++ b/rest/v9/voice.ts @@ -0,0 +1,6 @@ +import type { APIVoiceRegion } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/voice#list-voice-regions + */ +export type GetAPIVoiceRegionsResult = APIVoiceRegion[]; diff --git a/rest/v9/webhook.ts b/rest/v9/webhook.ts new file mode 100644 index 00000000..fa5a6cf3 --- /dev/null +++ b/rest/v9/webhook.ts @@ -0,0 +1,252 @@ +import type { Snowflake } from '../../globals'; +import type { APIAllowedMentions, APIEmbed, APIMessage, APIWebhook } from '../../payloads/v9/index'; + +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export interface RESTPostAPIChannelWebhookJSONBody { + /** + * Name of the webhook (1-80 characters) + */ + name: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; +} + +/** + * https://discord.com/developers/docs/resources/webhook#create-webhook + */ +export type RESTPostAPIChannelWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-channel-webhooks + */ +export type RESTGetAPIChannelWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-guild-webhooks + */ +export type RESTGetAPIGuildWebhooksResult = APIWebhook[]; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook + */ +export type RESTGetAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-with-token + */ +export type RESTGetAPIWebhookWithTokenResult = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export interface RESTPatchAPIWebhookJSONBody { + /** + * The default name of the webhook + */ + name?: string; + /** + * Image for the default webhook avatar + * + * See https://discord.com/developers/docs/reference#image-data + */ + avatar?: string | null; + /** + * The new channel id this webhook should be moved to + */ + channel_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook + */ +export type RESTPatchAPIWebhookResult = APIWebhook; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenJSONBody = Omit; + +/** + * https://discord.com/developers/docs/resources/webhook#modify-webhook-with-token + */ +export type RESTPatchAPIWebhookWithTokenResult = RESTGetAPIWebhookWithTokenResult; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook + */ +export type RESTDeleteAPIWebhookResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-with-token + */ +export type RESTDeleteAPIWebhookWithTokenResult = never; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export interface RESTPostAPIWebhookWithTokenJSONBody { + /** + * The message contents (up to 2000 characters) + */ + content?: string; + /** + * Override the default username of the webhook + */ + username?: string; + /** + * Override the default avatar of the webhook + */ + avatar_url?: string; + /** + * `true` if this is a TTS message + */ + tts?: boolean; + /** + * Embedded `rich` content + */ + embeds?: APIEmbed[]; + /** + * Allowed mentions for the message + */ + allowed_mentions?: APIAllowedMentions; + /** + * The thread to post this message in + */ + thread_id?: Snowflake; +} + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPostAPIWebhookWithTokenJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export interface RESTPostAPIWebhookWithTokenQuery { + /** + * Waits for server confirmation of message send before response, and returns the created message body + * (defaults to `false`; when `false` a message that is not saved does not return an error) + * + * @default false + */ + wait?: boolean; +} + +/** + * https://discord.com/developers/docs/resources/webhook#execute-webhook + */ +export type RESTPostAPIWebhookWithTokenResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenSlackResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenSlackWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubQuery = RESTPostAPIWebhookWithTokenQuery; + +/** + * https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook + */ +export type RESTPostAPIWebhookWithTokenGitHubResult = never; + +/** + * Received when a call to https://discord.com/developers/docs/resources/webhook#execute-webhook receives + * the `wait` query parameter set to `true` + * + * See https://discord.com/developers/docs/resources/webhook#execute-githubcompatible-webhook-querystring-params + */ +export type RESTPostAPIWebhookWithTokenGitHubWaitResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageJSONBody = Nullable< + Pick +>; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageFormDataBody = + | { + /** + * JSON stringified message body + */ + payload_json?: string; + /** + * The file contents + */ + file: unknown; + } + | (RESTPatchAPIWebhookWithTokenMessageJSONBody & { + /** + * The file contents + */ + file: unknown; + }); + +/** + * https://discord.com/developers/docs/resources/webhook#get-webhook-message + */ +export type RESTGetAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#edit-webhook-message + */ +export type RESTPatchAPIWebhookWithTokenMessageResult = APIMessage; + +/** + * https://discord.com/developers/docs/resources/webhook#delete-webhook-message + */ +export type RESTDeleteAPIWebhookWithTokenMessageResult = never; + +type Nullable = { + [P in keyof T]: T[P] | null; +}; diff --git a/rpc/index.ts b/rpc/index.ts index 3c7abb25..6a0cacf7 100644 --- a/rpc/index.ts +++ b/rpc/index.ts @@ -1,4 +1,4 @@ // This file exports all the types available in the recommended API version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8'; +export * from './v9'; diff --git a/rpc/v9.ts b/rpc/v9.ts new file mode 100644 index 00000000..89812d85 --- /dev/null +++ b/rpc/v9.ts @@ -0,0 +1,33 @@ +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc-rpc-error-codes + */ +export const enum RPCErrorCodes { + UnknownError = 1000, + InvalidPayload = 4000, + InvalidCommand = 4002, + InvalidGuild, + InvalidEvent, + InvalidChannel, + InvalidPermissions, + InvalidClientID, + InvalidOrigin, + InvalidToken, + InvalidUser, + OAuth2Error = 5000, + SelectChannelTimedOut, + GetGuildTimedOut, + SelectVoiceForceRequired, + CaptureShortcutAlreadyListening, +} + +/** + * https://discord.com/developers/docs/topics/opcodes-and-status-codes#rpc-rpc-close-event-codes + */ +export const enum RPCCloseEventCodes { + InvalidClientID = 4000, + InvalidOrigin, + RateLimited, + TokenRevoked, + InvalidVersion, + InvalidEncoding, +} diff --git a/scripts/deno.mjs b/scripts/deno.mjs index 06369b1d..3e20aec2 100644 --- a/scripts/deno.mjs +++ b/scripts/deno.mjs @@ -108,6 +108,7 @@ const globalFileResults = await Promise.allSettled( [ 'v6.ts', // 'v8.ts', + 'v9.ts', ].map((version) => convertFile(new URL(version, baseDirectory), new URL(version, denoPath))), ); diff --git a/scripts/versions.mjs b/scripts/versions.mjs index 2a271ee5..931a80e7 100644 --- a/scripts/versions.mjs +++ b/scripts/versions.mjs @@ -15,6 +15,7 @@ await Promise.allSettled( [ 'v6', // 'v8', + 'v9', // Voice 'v4', diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 5297607b..9aa161a0 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -8,6 +8,7 @@ "globals.ts", "v6.ts", "v8.ts", + "v9.ts", "gateway/**/*.ts", "payloads/**/*.ts", "rest/**/*.ts", diff --git a/tsconfig.json b/tsconfig.json index 6f363592..c5cdb8c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,7 @@ "globals.ts", "v6.ts", "v8.ts", + "v9.ts", "gateway/**/*.ts", "payloads/**/*.ts", "rest/**/*.ts", diff --git a/utils/index.ts b/utils/index.ts index e508a181..d4a71bfc 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -1,4 +1,4 @@ // This file exports all the utility functions available in the recommended API / Gateway version // Thereby, things MAY break in the future. Try sticking to imports from a specific version -export * from './v8'; +export * from './v9'; diff --git a/utils/v9.ts b/utils/v9.ts new file mode 100644 index 00000000..5d6dbea1 --- /dev/null +++ b/utils/v9.ts @@ -0,0 +1,48 @@ +import { + APIApplicationCommandDMInteraction, + APIApplicationCommandGuildInteraction, + APIApplicationCommandInteraction, + APIDMInteraction, + APIGuildInteraction, + APIInteraction, +} from '../payloads/v9/index'; + +/** + * A type-guard check for guild interactions. + * @param interaction The interaction to check against the + * @returns A boolean that indicates if the interaction was received from a guild + */ +export function isGuildInteraction(interaction: APIInteraction): interaction is APIGuildInteraction { + return Reflect.has(interaction, 'guild_id'); +} + +/** + * A type-guard check for DM interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the interaction was received from a direct message + */ +export function isDMInteraction(interaction: APIInteraction): interaction is APIDMInteraction { + return !isGuildInteraction(interaction); +} + +/** + * A type-guard check for guild application command interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the command interaction was received from a guild + */ +export function isApplicationCommandGuildInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandGuildInteraction { + return isGuildInteraction(interaction); +} + +/** + * A type-guard check for direct message application command interactions. + * @param interaction The interaction to check against + * @returns A boolean that indicates if the command interaction was received from a direct message + */ +export function isApplicationCommandDMInteraction( + interaction: APIApplicationCommandInteraction, +): interaction is APIApplicationCommandDMInteraction { + return !isGuildInteraction(interaction); +} diff --git a/v9.ts b/v9.ts new file mode 100644 index 00000000..be98939e --- /dev/null +++ b/v9.ts @@ -0,0 +1,6 @@ +export * from './globals'; +export * from './gateway/v9'; +export * from './payloads/v9/index'; +export * from './rest/v9/index'; +export * from './rpc/v9'; +export * as Utils from './utils/v9';