Discord: scope presence cache by account
This commit is contained in:
parent
5933593659
commit
8a8d1024b4
@ -55,7 +55,7 @@ export async function handleDiscordGuildAction(
|
|||||||
const member = accountId
|
const member = accountId
|
||||||
? await fetchMemberInfoDiscord(guildId, userId, { accountId })
|
? await fetchMemberInfoDiscord(guildId, userId, { accountId })
|
||||||
: await fetchMemberInfoDiscord(guildId, userId);
|
: await fetchMemberInfoDiscord(guildId, userId);
|
||||||
const presence = getPresence(userId);
|
const presence = getPresence(accountId, userId);
|
||||||
const activities = presence?.activities ?? undefined;
|
const activities = presence?.activities ?? undefined;
|
||||||
const status = presence?.status ?? undefined;
|
const status = presence?.status ?? undefined;
|
||||||
return jsonResult({ ok: true, member, ...(presence ? { status, activities } : {}) });
|
return jsonResult({ ok: true, member, ...(presence ? { status, activities } : {}) });
|
||||||
|
|||||||
@ -276,10 +276,12 @@ type PresenceUpdateEvent = Parameters<PresenceUpdateListener["handle"]>[0];
|
|||||||
|
|
||||||
export class DiscordPresenceListener extends PresenceUpdateListener {
|
export class DiscordPresenceListener extends PresenceUpdateListener {
|
||||||
private logger?: Logger;
|
private logger?: Logger;
|
||||||
|
private accountId?: string;
|
||||||
|
|
||||||
constructor(logger?: Logger) {
|
constructor(params: { logger?: Logger; accountId?: string }) {
|
||||||
super();
|
super();
|
||||||
this.logger = logger;
|
this.logger = params.logger;
|
||||||
|
this.accountId = params.accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async handle(data: PresenceUpdateEvent) {
|
async handle(data: PresenceUpdateEvent) {
|
||||||
@ -289,7 +291,11 @@ export class DiscordPresenceListener extends PresenceUpdateListener {
|
|||||||
? String(data.user.id)
|
? String(data.user.id)
|
||||||
: undefined;
|
: undefined;
|
||||||
if (!userId) return;
|
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) {
|
} catch (err) {
|
||||||
const logger = this.logger ?? discordEventQueueLog;
|
const logger = this.logger ?? discordEventQueueLog;
|
||||||
logger.error(danger(`discord presence handler failed: ${String(err)}`));
|
logger.error(danger(`discord presence handler failed: ${String(err)}`));
|
||||||
|
|||||||
@ -4,24 +4,49 @@ import type { GatewayPresenceUpdate } from "discord-api-types/v10";
|
|||||||
* In-memory cache of Discord user presence data.
|
* In-memory cache of Discord user presence data.
|
||||||
* Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
|
* Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
|
||||||
*/
|
*/
|
||||||
const presenceCache = new Map<string, GatewayPresenceUpdate>();
|
const presenceCache = new Map<string, Map<string, GatewayPresenceUpdate>>();
|
||||||
|
|
||||||
|
function resolveAccountKey(accountId?: string): string {
|
||||||
|
return accountId ?? "default";
|
||||||
|
}
|
||||||
|
|
||||||
/** Update cached presence for a user. */
|
/** Update cached presence for a user. */
|
||||||
export function setPresence(userId: string, data: GatewayPresenceUpdate): void {
|
export function setPresence(
|
||||||
presenceCache.set(userId, data);
|
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. */
|
/** Get cached presence for a user. Returns undefined if not cached. */
|
||||||
export function getPresence(userId: string): GatewayPresenceUpdate | undefined {
|
export function getPresence(
|
||||||
return presenceCache.get(userId);
|
accountId: string | undefined,
|
||||||
|
userId: string,
|
||||||
|
): GatewayPresenceUpdate | undefined {
|
||||||
|
return presenceCache.get(resolveAccountKey(accountId))?.get(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear all cached presence data. */
|
/** Clear cached presence data. */
|
||||||
export function clearPresences(): void {
|
export function clearPresences(accountId?: string): void {
|
||||||
|
if (accountId) {
|
||||||
|
presenceCache.delete(resolveAccountKey(accountId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
presenceCache.clear();
|
presenceCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the number of cached presence entries. */
|
/** Get the number of cached presence entries. */
|
||||||
export function presenceCacheSize(): number {
|
export function presenceCacheSize(): number {
|
||||||
return presenceCache.size;
|
let total = 0;
|
||||||
|
for (const accountCache of presenceCache.values()) {
|
||||||
|
total += accountCache.size;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -542,7 +542,10 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (discordCfg.intents?.presence) {
|
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");
|
runtime.log?.("discord: GuildPresences intent enabled — presence listener registered");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user