import { GatewayOpcodes } from "../../types/shared.ts"; import { Shard, ShardSocketCloseCodes, ShardState } from "./types.ts"; export async function resume(shard: Shard): Promise { // gateway.debug("GW RESUMING", { shardId }); // It has been requested to resume the Shards session. // It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it. if (shard.isOpen()) { shard.close( ShardSocketCloseCodes.ResumeClosingOldConnection, "Reconnecting the shard, closing old connection.", ); } // Shard has never identified, so we cannot resume. if (!shard.sessionId) { // gateway.debug( // "GW DEBUG", // `[Error] Trying to resume a shard (id: ${shardId}) that was not first identified.`, // ); return await shard.identify(); // throw new Error(`[SHARD] Trying to resume a shard (id: ${shard.id}) which was never identified`); } shard.state = ShardState.Resuming; // Before we can resume, we need to create a new connection with Discord's gateway. await shard.connect(); shard.send({ op: GatewayOpcodes.Resume, d: { token: `Bot ${shard.gatewayConfig.token}`, session_id: shard.sessionId, seq: shard.previousSequenceNumber ?? 0, }, }, true); return new Promise((resolve) => { shard.resolves.set("RESUMED", () => resolve()); // If it is attempted to resume with an invalid session id, // Discord sends an invalid session payload // Not erroring here since it is easy that this happens, also it would be not catchable shard.resolves.set("INVALID_SESSION", () => { shard.resolves.delete("RESUMED"); resolve(); }); }); }