diff --git a/src/agents/tools/discord-actions-guild.ts b/src/agents/tools/discord-actions-guild.ts index fc08f34f0..26e21c82e 100644 --- a/src/agents/tools/discord-actions-guild.ts +++ b/src/agents/tools/discord-actions-guild.ts @@ -55,7 +55,7 @@ export async function handleDiscordGuildAction( const member = accountId ? await fetchMemberInfoDiscord(guildId, userId, { accountId }) : await fetchMemberInfoDiscord(guildId, userId); - const presence = getPresence(userId); + const presence = getPresence(accountId, userId); const activities = presence?.activities ?? undefined; const status = presence?.status ?? undefined; return jsonResult({ ok: true, member, ...(presence ? { status, activities } : {}) }); diff --git a/src/discord/monitor/listeners.ts b/src/discord/monitor/listeners.ts index 205270440..770ae6d6c 100644 --- a/src/discord/monitor/listeners.ts +++ b/src/discord/monitor/listeners.ts @@ -276,10 +276,12 @@ type PresenceUpdateEvent = Parameters[0]; export class DiscordPresenceListener extends PresenceUpdateListener { private logger?: Logger; + private accountId?: string; - constructor(logger?: Logger) { + constructor(params: { logger?: Logger; accountId?: string }) { super(); - this.logger = logger; + this.logger = params.logger; + this.accountId = params.accountId; } async handle(data: PresenceUpdateEvent) { @@ -289,7 +291,11 @@ export class DiscordPresenceListener extends PresenceUpdateListener { ? String(data.user.id) : undefined; if (!userId) return; - setPresence(userId, data as import("discord-api-types/v10").GatewayPresenceUpdate); + setPresence( + this.accountId, + userId, + data as import("discord-api-types/v10").GatewayPresenceUpdate, + ); } catch (err) { const logger = this.logger ?? discordEventQueueLog; logger.error(danger(`discord presence handler failed: ${String(err)}`)); diff --git a/src/discord/monitor/presence-cache.ts b/src/discord/monitor/presence-cache.ts index 1153f7be8..e112297e8 100644 --- a/src/discord/monitor/presence-cache.ts +++ b/src/discord/monitor/presence-cache.ts @@ -4,24 +4,49 @@ import type { GatewayPresenceUpdate } from "discord-api-types/v10"; * In-memory cache of Discord user presence data. * Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled. */ -const presenceCache = new Map(); +const presenceCache = new Map>(); + +function resolveAccountKey(accountId?: string): string { + return accountId ?? "default"; +} /** Update cached presence for a user. */ -export function setPresence(userId: string, data: GatewayPresenceUpdate): void { - presenceCache.set(userId, data); +export function setPresence( + accountId: string | undefined, + userId: string, + data: GatewayPresenceUpdate, +): void { + const accountKey = resolveAccountKey(accountId); + let accountCache = presenceCache.get(accountKey); + if (!accountCache) { + accountCache = new Map(); + presenceCache.set(accountKey, accountCache); + } + accountCache.set(userId, data); } /** Get cached presence for a user. Returns undefined if not cached. */ -export function getPresence(userId: string): GatewayPresenceUpdate | undefined { - return presenceCache.get(userId); +export function getPresence( + accountId: string | undefined, + userId: string, +): GatewayPresenceUpdate | undefined { + return presenceCache.get(resolveAccountKey(accountId))?.get(userId); } -/** Clear all cached presence data. */ -export function clearPresences(): void { +/** Clear cached presence data. */ +export function clearPresences(accountId?: string): void { + if (accountId) { + presenceCache.delete(resolveAccountKey(accountId)); + return; + } presenceCache.clear(); } /** Get the number of cached presence entries. */ export function presenceCacheSize(): number { - return presenceCache.size; + let total = 0; + for (const accountCache of presenceCache.values()) { + total += accountCache.size; + } + return total; } diff --git a/src/discord/monitor/provider.ts b/src/discord/monitor/provider.ts index 7cac6b79e..ed5299cf7 100644 --- a/src/discord/monitor/provider.ts +++ b/src/discord/monitor/provider.ts @@ -542,7 +542,10 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { ); if (discordCfg.intents?.presence) { - registerDiscordListener(client.listeners, new DiscordPresenceListener(logger)); + registerDiscordListener( + client.listeners, + new DiscordPresenceListener({ logger, accountId: account.accountId }), + ); runtime.log?.("discord: GuildPresences intent enabled — presence listener registered"); }