mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:00:43 +00:00
refactor: trim qqbot known user store
This commit is contained in:
@@ -13,7 +13,7 @@ import { debugLog, debugError } from "../utils/log.js";
|
||||
import { getQQBotDataDir, getQQBotDataPath } from "../utils/platform.js";
|
||||
|
||||
/** Persisted record for a user who has interacted with the bot. */
|
||||
export interface KnownUser {
|
||||
interface KnownUser {
|
||||
openid: string;
|
||||
type: ChatScope;
|
||||
nickname?: string;
|
||||
@@ -135,120 +135,3 @@ export function recordKnownUser(user: {
|
||||
isDirty = true;
|
||||
saveUsersToFile();
|
||||
}
|
||||
|
||||
/** Look up one known user. */
|
||||
export function getKnownUser(
|
||||
accountId: string,
|
||||
openid: string,
|
||||
type: ChatScope = "c2c",
|
||||
groupOpenid?: string,
|
||||
): KnownUser | undefined {
|
||||
return loadUsersFromFile().get(makeUserKey({ accountId, openid, type, groupOpenid }));
|
||||
}
|
||||
|
||||
/** List known users with optional filtering and sorting. */
|
||||
export function listKnownUsers(options?: {
|
||||
accountId?: string;
|
||||
type?: ChatScope;
|
||||
activeWithin?: number;
|
||||
limit?: number;
|
||||
sortBy?: "lastSeenAt" | "firstSeenAt" | "interactionCount";
|
||||
sortOrder?: "asc" | "desc";
|
||||
}): KnownUser[] {
|
||||
let users = Array.from(loadUsersFromFile().values());
|
||||
if (options?.accountId) {
|
||||
users = users.filter((u) => u.accountId === options.accountId);
|
||||
}
|
||||
if (options?.type) {
|
||||
users = users.filter((u) => u.type === options.type);
|
||||
}
|
||||
if (options?.activeWithin) {
|
||||
const cutoff = Date.now() - options.activeWithin;
|
||||
users = users.filter((u) => u.lastSeenAt >= cutoff);
|
||||
}
|
||||
const sortBy = options?.sortBy ?? "lastSeenAt";
|
||||
const sortOrder = options?.sortOrder ?? "desc";
|
||||
users.sort((a, b) => {
|
||||
const aV = a[sortBy] ?? 0;
|
||||
const bV = b[sortBy] ?? 0;
|
||||
return sortOrder === "asc" ? aV - bV : bV - aV;
|
||||
});
|
||||
if (options?.limit && options.limit > 0) {
|
||||
users = users.slice(0, options.limit);
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
/** Return summary stats for known users. */
|
||||
export function getKnownUsersStats(accountId?: string): {
|
||||
totalUsers: number;
|
||||
c2cUsers: number;
|
||||
groupUsers: number;
|
||||
activeIn24h: number;
|
||||
activeIn7d: number;
|
||||
} {
|
||||
const users = listKnownUsers({ accountId });
|
||||
const now = Date.now();
|
||||
const day = 86400000;
|
||||
return {
|
||||
totalUsers: users.length,
|
||||
c2cUsers: users.filter((u) => u.type === "c2c").length,
|
||||
groupUsers: users.filter((u) => u.type === "group").length,
|
||||
activeIn24h: users.filter((u) => now - u.lastSeenAt < day).length,
|
||||
activeIn7d: users.filter((u) => now - u.lastSeenAt < 7 * day).length,
|
||||
};
|
||||
}
|
||||
|
||||
/** Remove one user record. */
|
||||
export function removeKnownUser(
|
||||
accountId: string,
|
||||
openid: string,
|
||||
type: ChatScope = "c2c",
|
||||
groupOpenid?: string,
|
||||
): boolean {
|
||||
const cache = loadUsersFromFile();
|
||||
const key = makeUserKey({ accountId, openid, type, groupOpenid });
|
||||
if (cache.has(key)) {
|
||||
cache.delete(key);
|
||||
isDirty = true;
|
||||
saveUsersToFile();
|
||||
debugLog(`[known-users] Removed user ${openid}`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Clear all user records, optionally scoped to one account. */
|
||||
export function clearKnownUsers(accountId?: string): number {
|
||||
const cache = loadUsersFromFile();
|
||||
let count = 0;
|
||||
if (accountId) {
|
||||
for (const [key, user] of cache.entries()) {
|
||||
if (user.accountId === accountId) {
|
||||
cache.delete(key);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
count = cache.size;
|
||||
cache.clear();
|
||||
}
|
||||
if (count > 0) {
|
||||
isDirty = true;
|
||||
doSaveUsersToFile();
|
||||
debugLog(`[known-users] Cleared ${count} users`);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/** Return all groups in which a user has interacted. */
|
||||
export function getUserGroups(accountId: string, openid: string): string[] {
|
||||
return listKnownUsers({ accountId, type: "group" })
|
||||
.filter((u) => u.openid === openid && u.groupOpenid)
|
||||
.map((u) => u.groupOpenid!);
|
||||
}
|
||||
|
||||
/** Return all recorded members for one group. */
|
||||
export function getGroupMembers(accountId: string, groupOpenid: string): KnownUser[] {
|
||||
return listKnownUsers({ accountId, type: "group" }).filter((u) => u.groupOpenid === groupOpenid);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user