From 81b3b28e0ebfb97f5181f4434941e9ffb0564288 Mon Sep 17 00:00:00 2001 From: Fleny Date: Tue, 5 Nov 2024 13:16:56 +0100 Subject: [PATCH] feat(bot,types): Add webhook events types (#3953) * Add webhook events types We will not support all the signing part for the handling of http requests, however we do still provide the types for these requests * Apply suggestions from code review Co-authored-by: Awesome Stickz * Use union on DiscordEventWebhookEventBody data --------- Co-authored-by: Awesome Stickz --- packages/bot/src/transformers/application.ts | 3 + .../src/transformers/reverse/application.ts | 3 + packages/bot/src/transformers/types.ts | 5 + packages/types/src/discord.ts | 160 +++++++++++++----- packages/types/src/discordeno.ts | 8 + 5 files changed, 133 insertions(+), 46 deletions(-) diff --git a/packages/bot/src/transformers/application.ts b/packages/bot/src/transformers/application.ts index f05465d55..172bed04f 100644 --- a/packages/bot/src/transformers/application.ts +++ b/packages/bot/src/transformers/application.ts @@ -66,6 +66,9 @@ export function transformApplication(bot: Bot, payload: { application: DiscordAp : undefined, } : undefined, + eventWebhooksUrl: payload.application.event_webhooks_url, + eventWebhooksStatus: payload.application.event_webhooks_status, + eventWebhooksTypes: payload.application.event_webhooks_types, } as Application return bot.transformers.customizers.application(bot, payload.application, application) diff --git a/packages/bot/src/transformers/reverse/application.ts b/packages/bot/src/transformers/reverse/application.ts index 8efe1927b..a1505db98 100644 --- a/packages/bot/src/transformers/reverse/application.ts +++ b/packages/bot/src/transformers/reverse/application.ts @@ -21,5 +21,8 @@ export function transformApplicationToDiscordApplication(bot: Bot, payload: Appl owner: payload.owner ? bot.transformers.reverse.user(bot, payload.owner) : undefined, team: payload.team ? bot.transformers.reverse.team(bot, payload.team) : null, guild_id: payload.guildId?.toString(), + event_webhooks_url: payload.eventWebhooksUrl, + event_webhooks_status: payload.eventWebhooksStatus, + event_webhooks_types: payload.eventWebhooksTypes, } } diff --git a/packages/bot/src/transformers/types.ts b/packages/bot/src/transformers/types.ts index e0f01a9ac..11ac9860a 100644 --- a/packages/bot/src/transformers/types.ts +++ b/packages/bot/src/transformers/types.ts @@ -15,6 +15,7 @@ import type { DefaultMessageNotificationLevels, DiscordActivityInstanceResource, DiscordActivityLocationKind, + DiscordApplicationEventWebhookStatus, DiscordApplicationIntegrationType, DiscordAuditLogChange, DiscordAutoModerationRuleTriggerMetadataPresets, @@ -32,6 +33,7 @@ import type { DiscordSkuType, DiscordTeamMemberRole, DiscordTemplateSerializedSourceGuild, + DiscordWebhookEventType, EmbedTypes, ExplicitContentFilterLevels, ForumLayout, @@ -175,6 +177,9 @@ export interface Application { integrationTypesConfig?: Partial> roleConnectionsVerificationUrl: string tags: string[] + eventWebhooksUrl?: string + eventWebhooksStatus: DiscordApplicationEventWebhookStatus + eventWebhooksTypes?: DiscordWebhookEventType[] } export interface ApplicationIntegrationTypeConfiguration { diff --git a/packages/types/src/discord.ts b/packages/types/src/discord.ts index 522d2a9fe..027b5e4c1 100644 --- a/packages/types/src/discord.ts +++ b/packages/types/src/discord.ts @@ -272,13 +272,13 @@ export interface DiscordIntegrationApplication { bot?: DiscordUser } -/** https://github.com/discord/discord-api-docs/blob/master/docs/topics/Gateway.md#integration-create-event-additional-fields */ +/** https://discord.com/developers/docs/events/gateway-events#integration-update-integration-update-event-additional-fields */ export interface DiscordIntegrationCreateUpdate extends DiscordIntegration { /** Id of the guild */ guild_id: string } -/** https://github.com/discord/discord-api-docs/blob/master/docs/topics/Gateway.md#integration-delete-event-fields */ +/** https://discord.com/developers/docs/events/gateway-events#integration-delete */ export interface DiscordIntegrationDelete { /** Integration id */ id: string @@ -288,13 +288,13 @@ export interface DiscordIntegrationDelete { application_id?: string } -/** https://discord.com/developers/docs/topics/gateway#guild-integrations-update */ +/** https://discord.com/developers/docs/events/gateway#guild-integrations-update */ export interface DiscordGuildIntegrationsUpdate { /** id of the guild whose integrations were updated */ guild_id: string } -/** https://discord.com/developers/docs/topics/gateway#typing-start */ +/** https://discord.com/developers/docs/events/gateway#typing-start */ export interface DiscordTypingStart { /** Unix time (in seconds) of when the user started typing */ timestamp: number @@ -404,6 +404,12 @@ export interface DiscordApplication { redirect_uris?: string[] /** Interactions endpoint URL for the app */ interactions_endpoint_url?: string | null + /** Event webhook URL for the app to receive webhook events */ + event_webhooks_url?: string | null + /** If webhook events are enabled for the app. 1 to disable, and 2 to enable. */ + event_webhooks_status: DiscordApplicationEventWebhookStatus + /** List of Webhook event types the app subscribes to */ + event_webhooks_types?: DiscordWebhookEventType[] } /** https://discord.com/developers/docs/resources/application#application-object-application-integration-type-configuration-object */ @@ -423,6 +429,16 @@ export enum DiscordApplicationIntegrationType { UserInstall = 1, } +/** https://discord.com/developers/docs/resources/application#application-object-application-event-webhook-status */ +export enum DiscordApplicationEventWebhookStatus { + /** Webhook events are disabled by developer */ + Disabled = 1, + /** Webhook events are enabled by developer */ + Enabled = 2, + /** Webhook events are disabled by Discord, usually due to inactivity */ + DisabledByDiscord = 3, +} + export type DiscordTokenExchange = DiscordTokenExchangeAuthorizationCode | DiscordTokenExchangeRefreshToken | DiscordTokenExchangeClientCredentials export interface DiscordTokenExchangeAuthorizationCode { @@ -582,7 +598,7 @@ export interface DiscordTeamMember { role: DiscordTeamMemberRole } -/** https://discord.com/developers/docs/topics/gateway#webhooks-update-webhook-update-event-fields */ +/** https://discord.com/developers/docs/events/gateway#webhooks-update-webhook-update-event-fields */ export interface DiscordWebhookUpdate { /** id of the guild */ guild_id: string @@ -1076,7 +1092,7 @@ export interface DiscordChannel { newly_created?: boolean } -/** https://discord.com/developers/docs/topics/gateway#presence-update */ +/** https://discord.com/developers/docs/events/gateway#presence-update */ export interface DiscordPresenceUpdate { /** Either "idle", "dnd", "online", or "offline" */ status: 'idle' | 'dnd' | 'online' | 'offline' @@ -1150,7 +1166,7 @@ export interface DiscordThreadMember { join_timestamp: string } -/** https://discord.com/developers/docs/topics/gateway-events#activity-object */ +/** https://discord.com/developers/docs/events/gateway-events#activity-object */ export interface DiscordActivity { /** The activity's name */ name: string @@ -1218,7 +1234,7 @@ export enum DiscordActivityLocationKind { PrivateChannel = 'pc', } -/** https://discord.com/developers/docs/topics/gateway#client-status-object */ +/** https://discord.com/developers/docs/events/gateway#client-status-object */ export interface DiscordClientStatus { /** The user's status set for an active desktop (Windows, Linux, Mac) application session */ desktop?: string @@ -1228,7 +1244,7 @@ export interface DiscordClientStatus { web?: string } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-timestamps */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-timestamps */ export interface DiscordActivityTimestamps { /** Unix time (in milliseconds) of when the activity started */ start?: number @@ -1236,7 +1252,7 @@ export interface DiscordActivityTimestamps { end?: number } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-emoji */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-emoji */ export interface DiscordActivityEmoji { /** The name of the emoji */ name: string @@ -1246,7 +1262,7 @@ export interface DiscordActivityEmoji { id?: string } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-party */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-party */ export interface DiscordActivityParty { /** Used to show the party's current and maximum size */ size?: [currentSize: number, maxSize: number] @@ -1254,7 +1270,7 @@ export interface DiscordActivityParty { id?: string } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-assets */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-assets */ export interface DiscordActivityAssets { /** Text displayed when hovering over the large image of the activity */ large_text?: string @@ -1266,7 +1282,7 @@ export interface DiscordActivityAssets { small_image?: string } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-secrets */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-secrets */ export interface DiscordActivitySecrets { /** The secret for joining a party */ join?: string @@ -1276,7 +1292,7 @@ export interface DiscordActivitySecrets { match?: string } -/** https://discord.com/developers/docs/topics/gateway#activity-object-activity-buttons */ +/** https://discord.com/developers/docs/events/gateway#activity-object-activity-buttons */ export interface DiscordActivityButton { /** The text shown on the button (1-32 characters) */ label: string @@ -1606,7 +1622,7 @@ export interface DiscordGetAnswerVotesResponse { users: DiscordUser[] } -/** https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-add */ +/** https://discord.com/developers/docs/events/gateway-events#message-poll-vote-add */ export interface DiscordPollVoteAdd { /** ID of the user. Usually a snowflake */ user_id: string @@ -1620,7 +1636,7 @@ export interface DiscordPollVoteAdd { answer_id: number } -/** https://discord.com/developers/docs/topics/gateway-events#message-poll-vote-remove */ +/** https://discord.com/developers/docs/events/gateway-events#message-poll-vote-remove */ export interface DiscordPollVoteRemove { /** ID of the user. Usually a snowflake */ user_id: string @@ -2246,7 +2262,7 @@ export interface DiscordAutoModerationActionMetadata { duration_seconds?: number } -/** https://discord.com/developers/docs/topics/gateway-events#auto-moderation-action-execution-auto-moderation-action-execution-event-fields */ +/** https://discord.com/developers/docs/events/gateway-events#auto-moderation-action-execution-auto-moderation-action-execution-event-fields */ export interface DiscordAutoModerationActionExecution { /** The id of the guild */ guild_id: string @@ -2534,7 +2550,7 @@ export enum DiscordScheduledEventRecurrenceRuleMonth { December, } -/** https://discord.com/developers/docs/topics/gateway#get-gateway-bot */ +/** https://discord.com/developers/docs/events/gateway#get-gateway-bot */ export interface DiscordGetGatewayBot { /** The WSS URL that can be used for connecting to the gateway */ url: string @@ -2544,7 +2560,7 @@ export interface DiscordGetGatewayBot { session_start_limit: DiscordSessionStartLimit } -/** https://discord.com/developers/docs/topics/gateway#session-start-limit-object */ +/** https://discord.com/developers/docs/events/gateway#session-start-limit-object */ export interface DiscordSessionStartLimit { /** The total number of session starts the current user is allowed */ total: number @@ -2869,7 +2885,7 @@ export interface DiscordFollowedChannel { webhook_id: string } -/** https://discord.com/developers/docs/topics/gateway#payloads-gateway-payload-structure */ +/** https://discord.com/developers/docs/events/gateway#payloads-gateway-payload-structure */ export interface DiscordGatewayPayload { /** opcode for the payload */ op: number @@ -2881,7 +2897,7 @@ export interface DiscordGatewayPayload { t: GatewayEventNames | null } -/** https://discord.com/developers/docs/topics/gateway#guild-members-chunk */ +/** https://discord.com/developers/docs/events/gateway#guild-members-chunk */ export interface DiscordGuildMembersChunk { /** The id of the guild */ guild_id: string @@ -2899,7 +2915,7 @@ export interface DiscordGuildMembersChunk { nonce?: string } -/** https://discord.com/developers/docs/topics/gateway#channel-pins-update */ +/** https://discord.com/developers/docs/events/gateway#channel-pins-update */ export interface DiscordChannelPinsUpdate { /** The id of the guild */ guild_id?: string @@ -2909,7 +2925,7 @@ export interface DiscordChannelPinsUpdate { last_pin_timestamp?: string | null } -/** https://discord.com/developers/docs/topics/gateway#guild-role-delete */ +/** https://discord.com/developers/docs/events/gateway#guild-role-delete */ export interface DiscordGuildRoleDelete { /** id of the guild */ guild_id: string @@ -2917,7 +2933,7 @@ export interface DiscordGuildRoleDelete { role_id: string } -/** https://discord.com/developers/docs/topics/gateway#guild-ban-add */ +/** https://discord.com/developers/docs/events/gateway#guild-ban-add */ export interface DiscordGuildBanAddRemove { /** id of the guild */ guild_id: string @@ -2925,10 +2941,10 @@ export interface DiscordGuildBanAddRemove { user: DiscordUser } -/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove */ +/** https://discord.com/developers/docs/events/gateway#message-reaction-remove */ export interface DiscordMessageReactionRemove extends Omit {} -/** https://discord.com/developers/docs/topics/gateway#message-reaction-add */ +/** https://discord.com/developers/docs/events/gateway#message-reaction-add */ export interface DiscordMessageReactionAdd { /** The id of the user */ user_id: string @@ -2952,7 +2968,7 @@ export interface DiscordMessageReactionAdd { type: DiscordReactionType } -/** https://discord.com/developers/docs/topics/gateway#voice-server-update */ +/** https://discord.com/developers/docs/events/gateway#voice-server-update */ export interface DiscordVoiceServerUpdate { /** Voice connection token */ token: string @@ -2962,7 +2978,7 @@ export interface DiscordVoiceServerUpdate { endpoint: string | null } -/** https://discord.com/developers/docs/topics/gateway-events#voice-channel-effect-send-voice-channel-effect-send-event-fields */ +/** https://discord.com/developers/docs/events/gateway-events#voice-channel-effect-send-voice-channel-effect-send-event-fields */ export interface DiscordVoiceChannelEffectSend { /** ID of the channel the effect was sent in */ channel_id: string @@ -2982,7 +2998,7 @@ export interface DiscordVoiceChannelEffectSend { sound_volume?: number } -/** https://discord.com/developers/docs/topics/gateway-events#voice-channel-effect-send-animation-types */ +/** https://discord.com/developers/docs/events/gateway-events#voice-channel-effect-send-animation-types */ export enum DiscordVoiceChannelEffectAnimationType { /** A fun animation, sent by a Nitro subscriber */ Premium = 0, @@ -2990,7 +3006,7 @@ export enum DiscordVoiceChannelEffectAnimationType { Basic = 1, } -/** https://discord.com/developers/docs/topics/gateway#invite-create */ +/** https://discord.com/developers/docs/events/gateway#invite-create */ export interface DiscordInviteCreate { /** The channel the invite is for */ channel_id: string @@ -3018,13 +3034,13 @@ export interface DiscordInviteCreate { uses: number } -/** https://discord.com/developers/docs/topics/gateway#hello */ +/** https://discord.com/developers/docs/events/gateway#hello */ export interface DiscordHello { /** The interval (in milliseconds) the client should heartbeat with */ heartbeat_interval: number } -/** https://discord.com/developers/docs/topics/gateway#ready */ +/** https://discord.com/developers/docs/events/gateway#ready */ export interface DiscordReady { /** Gateway version */ v: number @@ -3045,7 +3061,7 @@ export interface DiscordReady { /** https://discord.com/developers/docs/resources/guild#unavailable-guild-object */ export interface DiscordUnavailableGuild extends Pick {} -/** https://discord.com/developers/docs/topics/gateway#message-delete-bulk */ +/** https://discord.com/developers/docs/events/gateway#message-delete-bulk */ export interface DiscordMessageDeleteBulk { /** The ids of the messages */ ids: string[] @@ -3104,13 +3120,13 @@ export type DiscordTemplateSerializedSourceGuild = Omit< > } -/** https://discord.com/developers/docs/topics/gateway#guild-member-add */ +/** https://discord.com/developers/docs/events/gateway#guild-member-add */ export interface DiscordGuildMemberAdd extends DiscordMemberWithUser { /** id of the guild */ guild_id: string } -/** https://discord.com/developers/docs/topics/gateway#message-delete */ +/** https://discord.com/developers/docs/events/gateway#message-delete */ export interface DiscordMessageDelete { /** The id of the message */ id: string @@ -3120,7 +3136,7 @@ export interface DiscordMessageDelete { guild_id?: string } -/** https://discord.com/developers/docs/topics/gateway#thread-members-update-thread-members-update-event-fields */ +/** https://discord.com/developers/docs/events/gateway#thread-members-update-thread-members-update-event-fields */ export interface DiscordThreadMembersUpdate { /** The id of the thread */ id: string @@ -3134,7 +3150,7 @@ export interface DiscordThreadMembersUpdate { member_count: number } -/** https://discord.com/developers/docs/topics/gateway#thread-member-update */ +/** https://discord.com/developers/docs/events/gateway#thread-member-update */ export interface DiscordThreadMemberUpdate { /** The id of the thread */ id: string @@ -3146,7 +3162,7 @@ export interface DiscordThreadMemberUpdate { flags: number } -/** https://discord.com/developers/docs/topics/gateway#guild-role-create */ +/** https://discord.com/developers/docs/events/gateway#guild-role-create */ export interface DiscordGuildRoleCreate { /** The id of the guild */ guild_id: string @@ -3154,7 +3170,7 @@ export interface DiscordGuildRoleCreate { role: DiscordRole } -/** https://discord.com/developers/docs/topics/gateway#guild-emojis-update */ +/** https://discord.com/developers/docs/events/gateway#guild-emojis-update */ export interface DiscordGuildEmojisUpdate { /** id of the guild */ guild_id: string @@ -3162,7 +3178,7 @@ export interface DiscordGuildEmojisUpdate { emojis: DiscordEmoji[] } -/** https://discord.com/developers/docs/topics/gateway-events#guild-stickers-update */ +/** https://discord.com/developers/docs/events/gateway-events#guild-stickers-update */ export interface DiscordGuildStickersUpdate { /** id of the guild */ guild_id: string @@ -3170,7 +3186,7 @@ export interface DiscordGuildStickersUpdate { stickers: DiscordSticker[] } -/** https://discord.com/developers/docs/topics/gateway#guild-member-update */ +/** https://discord.com/developers/docs/events/gateway#guild-member-update */ export interface DiscordGuildMemberUpdate { /** The id of the guild */ guild_id: string @@ -3200,10 +3216,10 @@ export interface DiscordGuildMemberUpdate { flags?: number } -/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-all */ +/** https://discord.com/developers/docs/events/gateway#message-reaction-remove-all */ export interface DiscordMessageReactionRemoveAll extends Pick {} -/** https://discord.com/developers/docs/topics/gateway#guild-role-update */ +/** https://discord.com/developers/docs/events/gateway#guild-role-update */ export interface DiscordGuildRoleUpdate { /** The id of the guild */ guild_id: string @@ -3220,10 +3236,10 @@ export interface DiscordScheduledEventUserAdd { guild_id: string } -/** https://discord.com/developers/docs/topics/gateway#message-reaction-remove-emoji */ +/** https://discord.com/developers/docs/events/gateway#message-reaction-remove-emoji */ export type DiscordMessageReactionRemoveEmoji = Pick -/** https://discord.com/developers/docs/topics/gateway#guild-member-remove */ +/** https://discord.com/developers/docs/events/gateway#guild-member-remove */ export interface DiscordGuildMemberRemove { /** The id of the guild */ guild_id: string @@ -3248,7 +3264,7 @@ export interface DiscordScheduledEventUserRemove { guild_id: string } -/** https://discord.com/developers/docs/topics/gateway#invite-delete */ +/** https://discord.com/developers/docs/events/gateway#invite-delete */ export interface DiscordInviteDelete { /** The channel of the invite */ channel_id: string @@ -3750,3 +3766,55 @@ export interface DiscordBulkBan { /** list of user ids, that were not banned */ failed_users: string[] } + +/** https://discord.com/developers/docs/events/webhook-events#payload-structure */ +export interface DiscordEventWebhookEvent { + /** Version scheme for the webhook event. Currently always 1 */ + version: 1 + /** ID of your app */ + application_id: string + /** Type of webhook, either 0 for PING or 1 for webhook events */ + type: DiscordEventWebhookType + /** Event data payload */ + event?: DiscordEventWebhookEventBody +} + +/** https://discord.com/developers/docs/events/webhook-events#webhook-types */ +export enum DiscordEventWebhookType { + /** PING event sent to verify your Webhook Event URL is active */ + Ping = 0, + /** Webhook event (details for event in event body object) */ + Event = 1, +} + +/** https://discord.com/developers/docs/events/webhook-events#event-body-object */ +export interface DiscordEventWebhookEventBody { + /** Event type */ + type: DiscordWebhookEventType + /** Timestamp of when the event occurred in ISO8601 format */ + timestamp: string + /** Data for the event. The shape depends on the event type */ + data?: DiscordEventWebhookApplicationAuthorizedBody | DiscordEntitlement +} + +/** https://discord.com/developers/docs/events/webhook-events#event-types */ +export enum DiscordWebhookEventType { + /** Sent when an app was authorized by a user to a server or their account */ + ApplicationAuthorized = 'APPLICATION_AUTHORIZED', + /** Entitlement was created */ + EntitlementCreate = 'ENTITLEMENT_CREATE', + /** User was added to a Quest (currently unavailable) */ + QuestUserEnrollment = 'QUEST_USER_ENROLLMENT', +} + +/** https://discord.com/developers/docs/events/webhook-events#application-authorized-application-authorized-structure */ +export interface DiscordEventWebhookApplicationAuthorizedBody { + /** Installation context for the authorization. Either guild (0) if installed to a server or user (1) if installed to a user's account */ + integration_type?: DiscordApplicationIntegrationType + /** User who authorized the app */ + user: DiscordUser + /** List of scopes the user authorized */ + scopes: OAuth2Scope[] + /** Server which app was authorized for (when integration type is 0) */ + guild?: DiscordGuild +} diff --git a/packages/types/src/discordeno.ts b/packages/types/src/discordeno.ts index faa954827..563dbd88b 100644 --- a/packages/types/src/discordeno.ts +++ b/packages/types/src/discordeno.ts @@ -4,6 +4,7 @@ import type { AutoModerationTriggerTypes, DiscordApplicationCommandOption, DiscordApplicationCommandOptionChoice, + DiscordApplicationEventWebhookStatus, DiscordApplicationIntegrationType, DiscordAttachment, DiscordAutoModerationRuleTriggerMetadataPresets, @@ -23,6 +24,7 @@ import type { DiscordReactionType, DiscordRole, DiscordScheduledEventRecurrenceRule, + DiscordWebhookEventType, } from './discord.js' import type { AllowedMentionsTypes, @@ -1540,6 +1542,12 @@ export interface EditApplication { * There can only be a max of 5 tags */ tags?: string[] + /** Event webhook URL for the app to receive webhook events */ + eventWebhooksUrl?: string + /** If webhook events are enabled for the app. 1 to disable, and 2 to enable. */ + eventWebhooksStatus: DiscordApplicationEventWebhookStatus + /** List of Webhook event types the app subscribes to */ + eventWebhooksTypes?: DiscordWebhookEventType[] } /** https://discord.com/developers/docs/resources/poll#poll-create-request-object */