types: add gateway types (#687)

This commit is contained in:
ayntee
2021-03-26 20:09:24 +04:00
committed by GitHub
parent b74f9af48f
commit 431d180957
2 changed files with 482 additions and 3 deletions
+212 -3
View File
@@ -1,4 +1,10 @@
import { getGatewayBot } from "./helpers/misc/get_gateway_bot.ts";
import {
DiscordGatewayIntents,
DiscordGetGatewayBot,
DiscordIdentify,
} from "./types/gateway.ts";
import { CamelCaseProps } from "./types/util.ts";
import { baseEndpoints, GATEWAY_VERSION } from "./util/constants.ts";
import { spawnShards } from "./ws/shard_manager.ts";
@@ -9,13 +15,14 @@ export let applicationID = "";
export let eventHandlers: EventHandlers = {};
export let botGatewayData: DiscordBotGatewayData;
export let botGatewayData: DiscordGetGatewayBot;
export let proxyWSURL = `wss://gateway.discord.gg`;
export let lastShardID = 0;
export const identifyPayload: DiscordIdentify = {
token: "",
compress: true,
large_threshold: 50,
properties: {
$os: "linux",
$browser: "Discordeno",
@@ -38,7 +45,12 @@ export async function startBot(config: BotConfig) {
proxyWSURL = botGatewayData.url;
identifyPayload.token = config.token;
identifyPayload.intents = config.intents.reduce(
(bits, next) => (bits |= typeof next === "string" ? Intents[next] : next),
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
lastShardID = botGatewayData.shards;
@@ -87,7 +99,12 @@ export async function startBigBrainBot(data: BigBrainBotConfig) {
}
identifyPayload.intents = data.intents.reduce(
(bits, next) => (bits |= typeof next === "string" ? Intents[next] : next),
(
bits,
next,
) => (bits |= typeof next === "string"
? DiscordGatewayIntents[next]
: next),
0,
);
@@ -105,3 +122,195 @@ export async function startBigBrainBot(data: BigBrainBotConfig) {
: botGatewayData.shards),
);
}
export interface EventHandlers {
rateLimit?: (data: RateLimitData) => unknown;
/** Sent when a new Slash Command is created, relevant to the current user. */
applicationCommandCreate?: (
data: CamelCaseProps<ApplicationCommandEvent>,
) => unknown;
/** Sent when a Slash Command relevant to the current user is updated. */
applicationCommandUpdate?: (
data: CamelCaseProps<ApplicationCommandEvent>,
) => unknown;
/** Sent when a Slash Command relevant to the current user is deleted. */
applicationCommandDelete?: (
data: CamelCaseProps<ApplicationCommandEvent>,
) => unknown;
/** Sent when properties about the user change. */
botUpdate?: (user: UserPayload) => unknown;
/** Sent when a new guild channel is created, relevant to the current user. */
channelCreate?: (channel: Channel) => unknown;
/** Sent when a channel is updated. This is not sent when the field `last_message_id` is altered. To keep track of the `last_message_id` changes, you must listen for `MESSAGE_CREATE` events. */
channelUpdate?: (channel: Channel, cachedChannel: Channel) => unknown;
/** Sent when a channel relevant to the current user is deleted. */
channelDelete?: (channel: Channel) => unknown;
/** Sent when a message is pinned or unpinned in a text channel. This is not sent when a pinned message is deleted. */
channelPinsUpdate?: (
channel: Channel,
guild?: Guild,
lastPinTimestamp?: string | null,
) => unknown;
debug?: (args: DebugArg) => unknown;
dispatchRequirements?: (data: DiscordPayload, shardID: number) => unknown;
/** Sent when a user is banned from a guild. */
guildBanAdd?: (guild: Guild, user: UserPayload, member?: Member) => unknown;
/** Sent when a user is unbanned from a guild. */
guildBanRemove?: (
guild: Guild,
user: UserPayload,
member?: Member,
) => unknown;
/**
* This event can be sent in three different scenarios:
* 1. When a user is initially connecting, to lazily load and backfill information for all unavailable guilds sent in the `READY` event. Guilds that are unavailable due to an outage will send a `GUILD_DELETE` event.
* 2. When a Guild becomes available again to the client.
* 3. When the current user joins a new Guild.
*/
guildCreate?: (guild: Guild) => unknown;
guildLoaded?: (guild: Guild) => unknown;
/** Sent when a guild is updated. */
guildUpdate?: (guild: Guild, changes: GuildUpdateChange[]) => unknown;
/** Sent when a guild becomes or was already unavailable due to an outage, or when the user leaves or is removed from a guild. If the `unavailable` field is not set, the user was removed from the guild. */
guildDelete?: (guild: Guild) => unknown;
/** Sent when a guild's emojis have been updated. */
guildEmojisUpdate?: (
guild: Guild,
emojis: Collection<string, Emoji>,
cachedEmojis: Collection<string, Emoji>,
) => unknown;
/** Sent when a guild integration is updated. */
guildIntegrationsUpdate?: (guild: Guild) => unknown;
/** Sent when a new user joins a guild. */
guildMemberAdd?: (guild: Guild, member: Member) => unknown;
/** Sent when a user is removed from a guild (leave/kick/ban). */
guildMemberRemove?: (
guild: Guild,
user: UserPayload,
member?: Member,
) => unknown;
/** Sent when a guild member is updated. This will also fire when the user object of a guild member changes. */
guildMemberUpdate?: (
guild: Guild,
member: Member,
cachedMember?: Member,
) => unknown;
heartbeat?: () => unknown;
/** Sent when a user in a guild uses a Slash Command. */
interactionCreate?: (
data: Omit<InteractionCommandPayload, "member"> & { member: Member },
) => unknown;
/** Sent when a message is created. */
messageCreate?: (message: Message) => unknown;
/** Sent when a message is deleted. */
messageDelete?: (partial: PartialMessage, message?: Message) => unknown;
/** Sent when a message is updated. */
messageUpdate?: (message: Message, cachedMessage: OldMessage) => unknown;
nicknameUpdate?: (
guild: Guild,
member: Member,
nickname: string,
oldNickname?: string,
) => unknown;
/** A user's presence is their current state on a guild. This event is sent when a user's presence or info, such as name or avatar, is updated. */
presenceUpdate?: (
presence: PresenceUpdatePayload,
oldPresence?: PresenceUpdatePayload,
) => unknown;
raw?: (data: DiscordPayload) => unknown;
rawGateway?: (data: unknown) => unknown;
ready?: () => unknown;
/** Sent when a user adds a reaction to a message. */
reactionAdd?: (
payload: MessageReactionUncachedPayload,
emoji: ReactionPayload,
userID: string,
message?: Message,
) => unknown;
/** Sent when a user removes a reaction from a message. */
reactionRemove?: (
payload: MessageReactionUncachedPayload,
emoji: ReactionPayload,
userID: string,
message?: Message,
) => unknown;
/** Sent when a user explicitly removes all reactions from a message. */
reactionRemoveAll?: (data: BaseMessageReactionPayload) => unknown;
/** Sent when a bot removes all instances of a given emoji from the reactions of a message. */
reactionRemoveEmoji?: (data: MessageReactionRemoveEmojiPayload) => unknown;
/** Sent when a guild role is created. */
roleCreate?: (guild: Guild, role: Role) => unknown;
/** Sent when a guild role is deleted. */
roleDelete?: (guild: Guild, role: Role) => unknown;
/** Sent when a guild role is updated. */
roleUpdate?: (guild: Guild, role: Role, cachedRole: Role) => unknown;
roleGained?: (guild: Guild, member: Member, roleID: string) => unknown;
roleLost?: (guild: Guild, member: Member, roleID: string) => unknown;
shardReady?: (shardID: number) => unknown;
shardFailedToLoad?: (
shardID: number,
guildIDs: Set<string>,
) => unknown;
/** Sent when a user starts typing in a channel. */
typingStart?: (data: TypingStartPayload) => unknown;
voiceChannelJoin?: (member: Member, channelID: string) => unknown;
voiceChannelLeave?: (member: Member, channelID: string) => unknown;
voiceChannelSwitch?: (
member: Member,
channelID: string,
oldChannelID: string,
) => unknown;
/** Sent when someone joins/leaves/moves voice channels. */
voiceStateUpdate?: (
member: Member,
voiceState: VoiceStateUpdatePayload,
) => unknown;
/** Sent when a guild's voice server is updated. This is sent when initially connecting to voice, and when the current voice instance fails over to a new server. */
voiceServerUpdate?: (
token: string,
guild: Guild,
endpoint: string,
) => unknown;
/** Sent when a guild channel's webhook is created, updated, or deleted. */
webhooksUpdate?: (channelID: string, guildID: string) => unknown;
/** Sent when a member has passed the guild's Membership Screening requirements */
membershipScreeningPassed?: (guild: Guild, member: Member) => unknown;
/** Sent when an integration is created on a server such as twitch, youtube etc.. */
integrationCreate?: (
data: CamelCaseProps<IntegrationCreateUpdateEvent>,
) => unknown;
/** Sent when an integration is updated. */
integrationUpdate?: (
data: CamelCaseProps<IntegrationCreateUpdateEvent>,
) => unknown;
/** Sent when an integration is deleted. */
integrationDelete?: (
data: CamelCaseProps<IntegrationDeleteEvent>,
) => undefined;
/** Sent when a new invite to a channel is created. */
inviteCreate?: (data: CamelCaseProps<InviteCreateEvent>) => unknown;
/** Sent when an invite is deleted. */
inviteDelete?: (data: CamelCaseProps<InviteDeleteEvent>) => unknown;
}
export interface BotConfig {
token: string;
compress?: boolean;
intents: (DiscordGatewayIntents | keyof typeof DiscordGatewayIntents)[];
eventHandlers?: EventHandlers;
}
export interface BigBrainBotConfig extends BotConfig {
/** The first shard to start at for this worker. Use this to control which shards to run in each worker. */
firstShardID: number;
/** The last shard to start for this worker. By default it will be 25 + the firstShardID. */
lastShardID?: number;
/** This can be used to forward the ws handling to a proxy. */
wsURL?: string;
/** This can be used to forward the REST handling to a proxy. */
restURL?: string;
/** This can be used to forward the CDN handling to a proxy. */
cdnURL?: string;
/** This is the authorization header that your rest proxy will validate */
restAuthorization?: string;
}
+270
View File
@@ -0,0 +1,270 @@
/** https://discord.com/developers/docs/topics/gateway#payloads-gateway-payload-structure */
export interface DiscordGatewayPayload {
/** opcode for the payload */
op: number;
/** Event data */
d: unknown | null;
/** Sequence number, used for resuming sessions and heartbeats */
s: number | null;
/** The event name for this payload */
t: string | null;
}
/** https://discord.com/developers/docs/topics/gateway#connecting-gateway-url-params */
export interface DiscordGatewayURLParams {
/** Gateway version to use */
v: string;
/** The encoding of received gateway packets */
encoding: string;
/** The (optional) compression of gateway packets */
compress?: string;
}
/** https://discord.com/developers/docs/topics/gateway#gateway-intents */
export enum DiscordGatewayIntents {
/**
* - GUILD_CREATE
* - GUILD_UPDATE
* - GUILD_DELETE
* - GUILD_ROLE_CREATE
* - GUILD_ROLE_UPDATE
* - GUILD_ROLE_DELETE
* - CHANNEL_CREATE
* - CHANNEL_UPDATE
* - CHANNEL_DELETE
* - CHANNEL_PINS_UPDATE
*/
GUILDS = 1 << 0,
/**
* - GUILD_MEMBER_ADD
* - GUILD_MEMBER_UPDATE
* - GUILD_MEMBER_REMOVE
*/
GUILD_MEMBERS = 1 << 1,
/**
* - GUILD_BAN_ADD
* - GUILD_BAN_REMOVE
*/
GUILD_BANS = 1 << 2,
/** - GUILD_EMOJIS_UPDATE */
GUILD_EMOJIS = 1 << 3,
/** - GUILD_INTEGRATIONS_UPDATE */
GUILD_INTEGRATIONS = 1 << 4,
/** - WEBHOOKS_UPDATE */
GUILD_WEBHOOKS = 1 << 5,
/**
* - INVITE_CREATE
* - INVITE_DELETE
*/
GUILD_INVITES = 1 << 6,
/** - VOICE_STATE_UPDATE */
GUILD_VOICE_STATES = 1 << 7,
/** - PRESENCE_UPDATE */
GUILD_PRESENCES = 1 << 8,
/**
* - MESSAGE_CREATE
* - MESSAGE_UPDATE
* - MESSAGE_DELETE
* - MESSAGE_DELETE_BULK
*/
GUILD_MESSAGES = 1 << 9,
/**
* - MESSAGE_REACTION_ADD
* - MESSAGE_REACTION_REMOVE
* - MESSAGE_REACTION_REMOVE_ALL
* - MESSAGE_REACTION_REMOVE_EMOJI
*/
GUILD_MESSAGE_REACTIONS = 1 << 10,
/** - TYPING_START */
GUILD_MESSAGE_TYPING = 1 << 11,
/**
* - MESSAGE_CREATE
* - MESSAGE_UPDATE
* - MESSAGE_DELETE
* - CHANNEL_PINS_UPDATE
*/
DIRECT_MESSAGES = 1 << 12,
/**
* - MESSAGE_REACTION_ADD
* - MESSAGE_REACTION_REMOVE
* - MESSAGE_REACTION_REMOVE_ALL
* - MESSAGE_REACTION_REMOVE_EMOJI
*/
DIRECT_MESSAGE_REACTIONS = 1 << 13,
/** - TYPING_START */
DIRECT_MESSAGE_TYPING = 1 << 14,
}
/** https://discord.com/developers/docs/topics/gateway#identify */
export interface DiscordIdentify {
/** Authentication token */
token: string;
/** Connection properties */
properties: DiscordIdentifyConnectionProperties;
/** Whether this connection supports compression of packets */
compress?: boolean;
/** Value between 50 and 250, total number of members where the gateway will stop sending offline members in the guild member list */
large_threshold: number;
/** Used for Guild Sharding */
shard?: [number, number];
/** Presence structure for initial presence information */
presence?: DiscordUpdateStatus;
/** Enables dispatching of guild subscription events (presence and typing events) */
guild_subscriptions?: boolean;
/** The Gateway Intents you wish to receive */
intents: number;
}
/** https://discord.com/developers/docs/topics/gateway#identify-identify-connection-properties */
export interface DiscordIdentifyConnectionProperties {
/** Operating system */
$os: string;
/** Library name */
$browser: string;
/** Library name */
$device: string;
}
/** https://discord.com/developers/docs/topics/gateway#resume */
export interface DiscordResume {
/** 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 DiscordRequestGuildMembers {
/** id of the guild to get members for */
guild_id: string;
/** 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?: string[];
/** Nonce to identify the Guild Members Chunk response */
nonce?: string;
}
/** https://discord.com/developers/docs/topics/gateway#update-voice-state */
export interface DiscordUpdateVoiceState {
/** id of the guild */
guild_id: string;
/** id of the voice channel client wants to join (null if disconnecting) */
channel_id: string | 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 DiscordUpdateStatus {
/** Unix time (in milliseconds) of when the client went idle, or null if the client is not idle */
since?: number;
/** null, or the user's activities */
activities: DiscordActivity[] | null;
/** The user's new status */
status: DiscordStatusTypes;
/** Whether or not the client is afk */
afk: boolean;
}
/** https://discord.com/developers/docs/topics/gateway#update-status-status-types */
export type DiscordStatusTypes =
| "online"
| "dnd"
| "idle"
| "invisible"
| "offline";
/** https://discord.com/developers/docs/topics/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 */
export interface DiscordReady {
/** Gateway version */
v: number;
/** Information about the user including email */
user: DiscordUser;
/** Empty array */
private_channels: [];
/** The guilds the user is in */
guilds: DiscordUnavailableGuild[];
/** Used for resuming connections */
session_id: string;
/** The shard information associated with this session, if sent when identifying */
shard?: [number, number];
/** Contains id and flags */
application:
& Partial<DiscordApplication>
& Pick<DiscordApplication, "id" | "flags">;
}
/** https://discord.com/developers/docs/topics/gateway#channel-pins-update */
export interface DiscordChannelPinsUpdate {
/** The id of the guild */
guild_id?: string;
/** The id of the channel */
channel_id: string;
/** The time at which the most recent pinned message was pinned */
last_pin_timestamp?: string | null;
}
/** https://discord.com/developers/docs/topics/gateway#guild-ban-add */
export interface DiscordGuildBanAddRemove {
/** id of the guild */
guild_id: string;
/** The (un)banned user */
user: DiscordUser;
}
/** https://discord.com/developers/docs/topics/gateway#guild-emojis-update */
export interface GuildEmojisUpdate {
/** id of the guild */
guild_id: string;
/** Array of emojis */
emojis: DiscordEmoji[];
}
/** https://discord.com/developers/docs/topics/gateway#guild-integrations-update */
export interface DiscordIntegrationsUpdate {
/** id of the guild whose integrations were updated */
guild_id: string;
}
/** https://discord.com/developers/docs/topics/gateway#guild-member-add */
export interface DiscordGuildMemberAdd extends DiscordMember {
/** id of the guild */
guild_id: string;
}
/** https://discord.com/developers/docs/topics/gateway#get-gateway-bot */
export interface DiscordGetGatewayBot {
/** The WSS URL that can be used for connecting to the gateway */
url: string;
/** The recommended number of shards to use when connecting */
shards: number;
/** Information on the current session start limit */
session_start_limit: DiscordSessionStartLimit;
}
/** https://discord.com/developers/docs/topics/gateway#session-start-limit-object */
export interface DiscordSessionStartLimit {
/** 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;
}