summary refs log tree commit diff
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2026-04-13 15:55:32 +0200
committerRory& <root@rory.gay>2026-04-13 15:55:32 +0200
commitad245d029f740edaf94c485c54b1455fd7b87c0d (patch)
treeb9e806a089ece342292e366823c8188f075c3d97
parentprep for presence (diff)
downloadserver-ts-ad245d029f740edaf94c485c54b1455fd7b87c0d.tar.xz
Mark users as offline when gateway connection is closed
Part of #1541

Co-authored-by: Davide <137603413+LW-Davide@users.noreply.github.com>
-rw-r--r--src/gateway/events/Close.ts31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/gateway/events/Close.ts b/src/gateway/events/Close.ts

index 8c375253..be6a7105 100644 --- a/src/gateway/events/Close.ts +++ b/src/gateway/events/Close.ts
@@ -18,6 +18,8 @@ import { WebSocket } from "@spacebar/gateway"; import { emitEvent, Member, PresenceUpdateEvent, Session, SessionsReplace, User, VoiceState, VoiceStateUpdateEvent } from "@spacebar/util"; +import { distributePresenceUpdate } from "../../util/util/Presence"; +import { randomString } from "@spacebar/api*"; export async function Close(this: WebSocket, code: number, reason: Buffer) { console.log("[WebSocket] closed", code, reason.toString()); @@ -28,7 +30,34 @@ export async function Close(this: WebSocket, code: number, reason: Buffer) { this.removeAllListeners(); if (this.session_id) { - // await Session.delete({ session_id: this.session_id }); + const authSessionId = this.session?.session_id; + const closedAt = Date.now(); + + setTimeout(async () => { + try { + if (authSessionId && this.user_id) { + const s = await Session.findOne({ + where: { user_id: this.user_id, session_id: authSessionId }, + }); + if (s && (s.last_seen?.getTime() ?? 0) <= closedAt) { + await Session.update({ user_id: this.user_id, session_id: authSessionId }, { status: "offline", activities: [], client_status: {} }); + await distributePresenceUpdate(this.user_id, { + event: "PRESENCE_UPDATE", + data: { + user: (await User.findOneOrFail({ where: { id: this.user_id } })).toPublicUser(), + status: this.session!.getPublicStatus(), + client_status: this.session!.client_status, + activities: this.session!.activities, + }, + origin: "GATEWAY_CLOSE", + transaction_id: `IDENT_${this.user_id}_${randomString()}`, + } satisfies PresenceUpdateEvent); + } + } + } catch (e) { + console.error("[WebSocket] Close session cleanup failed", code, e); + } + }, 10_000); const voiceState = await VoiceState.findOne({ where: { user_id: this.user_id },