import { EventEmitter } from "node:events"; import BetterWs = require("./BetterWs"); import { Bucket, StateMachine } from "snowtransfer"; import { type GatewayPresenceUpdateData, type GatewayVoiceStateUpdateData, type GatewayRequestGuildMembersData, type GatewaySendPayload, GatewayRequestChannelInfoData } from "discord-api-types/v10"; import type { ConnectorEvents, IShardResumeData } from "./Types"; /** * Class used for acting based on received events. * * This class is automatically instantiated by the library and is documented for reference. * @since 0.1.4 */ declare class DiscordConnector extends EventEmitter { id: number; client: import("./Client"); /** The options used by the client */ options: DiscordConnector["client"]["options"]; /** The WebSocket this connector uses */ betterWs: BetterWs; /** A Timeout that, when triggered, will send an op 1 heartbeat. Is null if Discord hasn't told this connector how often to heartbeat */ heartbeatTimeout: globalThis.NodeJS.Timeout | null; /** How often this connector should heartbeat if not 0 */ heartbeatInterval: number; /** The _trace as sent by the Discord READY and RESUMED payloads */ _trace: string | null; /** The sequence, which is the number of events received by Discord within the session if any session */ seq: number; /** The status of this connector */ status: "connecting" | "identifying" | "resuming" | "ready" | "disconnected"; /** The session ID used for resuming or null if Discord hasn't sent one yet */ sessionId: string | null; /** The ms timestamp when this connector last received an op 11 heartbeat ack if not 0 */ lastACKAt: number; /** The ms timestamp when this connector last sent an op 1 heartbeat if not 0 */ lastHeartbeatSend: number; /** The time in milliseconds it took for Discord to send an op 11 heartbeat ack in response to an op 1 heartbeat */ latency: number; /** The address the WebSocket will use to connect to the Discord gateway if resuming */ resumeAddress: string | null; /** * Tracks the session lifecycle this connector is in and what operations are allowed. * States: disconnected, connecting (awaiting HELLO), identifying, resuming, ready, * closing (user-requested disconnect in flight), reconnecting (deliberate close that will reconnect). */ sm: StateMachine; /** The ratelimit bucket for how many packets this ws can send within a time frame. */ wsBucket: Bucket; /** The ratelimit bucket for how many presence update specific packets this ws can send within a time frame. Is still affected by the overall packet send bucket. */ presenceBucket: Bucket; /** The ratelimit bucket for when requesting all guild members from a guild. Is still affected by the overall packet send bucket. */ membersBucket: Bucket; /** A Timeout that, when triggered, closes the connection because op HELLO hasn't been received and may never be received */ private _openToHeartbeatTimeout; /** If an OP 2 IDENTIFY was already sent on the current ws connection and is still authoritative for it */ private _identifySent; /** A Timeout that, when triggered, sends the first heartbeat */ private _initialHeartbeatTimeout; /** * The address the WebSocket will use to connect to the Discord gateway if not resuming. * Always reads the client's current endpoint, so a later Client.fetchConnectInfo() call is picked up by existing shards. */ get identifyAddress(): string; /** If this connector is deliberately closing its connection right now in order to open a new one */ get reconnecting(): boolean; /** * Creates a new Discord Connector. * @param id id of the shard that created this class. * @param client Main client instance. */ constructor(id: number, client: import("./Client")); /** * Emit an error on the client if anyone listens for them, otherwise degrade to a debug event. * "error" with zero listeners throws by EventEmitter contract, and the connector emits from socket, * timer and bucket contexts where that throw would crash the process instead of reaching user code. * @since 0.19.0 */ private _clientError; /** * Set the status of this connector and notify listeners about the change. * @since 0.19.0 */ private _setStatus; /** * Pause all send ratelimit buckets, queueing further messages until resumed. * @since 0.19.0 */ private _pauseBuckets; /** * Resume all send ratelimit buckets. * @since 0.19.0 */ private _resumeBuckets; /** * Connect to Discord. * @since 0.1.4 */ connect(): Promise; /** * Snapshot of everything needed to resume this shard's session, e.g. in another process. * Only meaningful after the session was established and the connection wasn't closed with a * session-destroying code (1000/1001) - see disconnect(resumable). * @since 0.19.0 * @returns The resume data, or null if there is no session to resume. */ getResumeData(): IShardResumeData | null; /** * Seed this connector with resume data from a previous process, making the next connect * resume the session instead of identifying. If Discord no longer accepts the session, * the connector falls back to identifying automatically via INVALID_SESSION. * @since 0.19.0 * @param data Resume data as returned by getResumeData(). */ seedResumeData(data: IShardResumeData): void; /** * Close the websocket connection and disconnect. * @since 0.1.4 * @param resumable Whether to close with a code that keeps the session alive on Discord's end, * so it can be resumed later - also from another process via getResumeData()/seeded resume data. * The default close code 1000 destroys the session. */ disconnect(resumable?: boolean): Promise; /** * Called with a parsed Websocket message to execute further actions. * @since 0.1.4 * @param message Message that was received. */ private messageAction; /** * Deliberately close the connection with a resumable code, then reconnect and resume the session. * If the session turns out to not be resumable, the INVALID_SESSION flow falls back to identifying. * @since 0.3.0 */ private _reconnect; /** * Sets the this.heartbeatTimeout Interval. * @since 0.8.5 */ private setHeartBeat; /** * Clear the heart beat interval, set it to null and set the cached heartbeat_interval as 0. * @since 0.3.0 */ private clearHeartBeat; /** * Send an OP 2 IDENTIFY to the gateway. * @since 0.1.4 */ identify(): Promise; /** * Send an OP 6 RESUME to the gateway. * @since 0.1.4 */ resume(): Promise; /** * Send an OP 1 HEARTBEAT to the gateway. * @since 0.1.4 */ private heartbeat; /** * Handle dispatch events. * @since 0.1.4 * @param message Message received from the websocket. */ private handleDispatch; /** * Handle a close from the underlying websocket. * @since 0.1.4 * @param code Websocket close code. * @param reason Close reason if any. */ private handleWsClose; /** * Send an OP 3 PRESENCE_UPDATE to the gateway. * @since 0.3.0 * @param data Presence data to send. */ presenceUpdate(data: Partial): Promise; /** * Send an OP 4 VOICE_STATE_UPDATE to the gateway. * @since 0.1.4 * @param data Voice state update data to send. */ voiceStateUpdate(data: GatewayVoiceStateUpdateData & { self_deaf?: boolean; self_mute?: boolean; }): Promise; /** * Send an OP 8 REQUEST_GUILD_MEMBERS to the gateway. * @since 0.1.4 * @param data Data to send. */ requestGuildMembers(data: GatewayRequestGuildMembersData & { limit?: number; }): Promise; /** * Send an OP 31 REQUEST_SOUNDBOARD_SOUNDS to the gateway. * @since 0.19.0 * @param guilds The guilds to get the soundboard sounds from. */ requestSoundboardSounds(guilds: Array): Promise; /** * Send an OP 43 REQUEST_CHANNEL_INFO to the gateway. * @since 0.19.0 * @param data Data to send. */ requestChannelInfo(data: GatewayRequestChannelInfoData): Promise; /** * Sends a message to the server in the format of { op: number, d: any } (before any encoding/compression). * @since 0.12.0 * @param data Packet to send to Discord. * @returns A Promise that resolves when the message passes the bucket queue(s). */ sendMessage(data: GatewaySendPayload): Promise; /** * Checks presence data and fills in missing elements without touching the caller's object. * @since 0.1.4 * @param data Data to send. * @returns A new object with the fixed/checked data. */ private _checkPresenceData; /** * Checks voice state update data and fills in missing elements without touching the caller's object. * @since 0.1.4 * @param data Data to send. * @returns A new object with the fixed/checked data. */ private _checkVoiceStateUpdateData; /** * Checks request guild members data and fills in missing elements without touching the caller's object. * @since 0.1.4 * @param data Data to send. * @returns A new object with the fixed/checked data. */ private _checkRequestGuildMembersData; } export = DiscordConnector;