Show per-account delivery status
This commit is contained in:
1 parent
9b86cee9be
commit
22eb32e5bf
14 files changed
+402
-13
No files matched your search
@@ -84,11 +84,15 @@ export function createConcreteRedditAccountRuntimeFactory(
|
||||
}
|
||||
|
||||
async function buildRuntime(
|
||||
{ config, logger, db, isBotRunning = () => true }: ConcreteRuntimeFactoryOptions,
|
||||
{ config, logger: rootLogger, db, isBotRunning = () => true }: ConcreteRuntimeFactoryOptions,
|
||||
session: VerifiedAccountSession,
|
||||
recipientDeduplicator: RecipientDeduplicator,
|
||||
redditRequestCoordinator: RedditRequestCoordinator,
|
||||
): Promise<RedditAccountRuntime> {
|
||||
const logger = rootLogger.child({
|
||||
accountId: session.accountId,
|
||||
redditUsername: session.redditUsername,
|
||||
});
|
||||
const browserProfileDir = accountBrowserProfileDir(
|
||||
path.resolve(process.cwd(), config.browser.sessionDir),
|
||||
session.accountId,
|
||||
|
||||
+57
-2
@@ -26,18 +26,64 @@ export function createStatsRouter(ctx: WebContext): Router {
|
||||
|
||||
router.get('/stats', (_req, res) => {
|
||||
const runtimes = runningRuntimes(ctx);
|
||||
const runtimeSnapshots = ctx.services.accountRuntimes?.list() ?? [];
|
||||
const messages = runtimes.length > 0
|
||||
? runtimes.flatMap((runtime) => runtime.resources.messagesRepo.getRecent(1000))
|
||||
: ctx.repos.messages.getRecent(1000);
|
||||
const totalSent = messages.length;
|
||||
const totalResponses = messages.filter((m) => m.gotResponse).length;
|
||||
|
||||
const cooldown = runtimes.map((runtime) => runtime.resources.chatService.getInvitationCooldown()).find(Boolean)
|
||||
const cooldownRuntime = runtimes.find((runtime) => runtime.resources.chatService.getInvitationCooldown());
|
||||
const cooldown = cooldownRuntime?.resources.chatService.getInvitationCooldown()
|
||||
?? ctx.services.chat?.getInvitationCooldown()
|
||||
?? null;
|
||||
const messagesThisHour = runtimes.length > 0
|
||||
? runtimes.reduce((total, runtime) => total + runtime.resources.rateLimiter.getStats().messagesThisHour, 0)
|
||||
: ctx.getMessagesThisHour();
|
||||
const accounts: BotStats['accounts'] = (ctx.services.redditAccounts?.list() ?? []).map((account) => {
|
||||
const snapshot = runtimeSnapshots.find((item) => item.accountId === account.accountId);
|
||||
const runtime = snapshot ? ctx.services.accountRuntimes?.get(snapshot.accountId) : null;
|
||||
const authenticated = runtime?.resources.accountAuth.isFullyAuthenticated() ?? false;
|
||||
const accountCooldown = runtime?.resources.chatService.getInvitationCooldown() ?? null;
|
||||
const timers = runtime?.resources.rateLimiter.getTimers() ?? {
|
||||
nextMessageAvailableAt: null,
|
||||
hourlyResetAt: Date.now() + 60 * 60_000,
|
||||
messagesRemaining: ctx.config.rateLimit.maxMessagesPerHour,
|
||||
};
|
||||
const messageStats = runtime?.resources.rateLimiter.getStats();
|
||||
const priority = runtime?.resources.conversationAutomation.getPriorityStatus();
|
||||
const runtimeState = snapshot?.state ?? 'stopped';
|
||||
const sendingState: BotStats['accounts'][number]['sendingState'] = runtimeState === 'failed'
|
||||
? 'runtime-failed'
|
||||
: account.status === 'login-required' || (runtimeState === 'running' && !authenticated)
|
||||
? 'login-required'
|
||||
: runtimeState !== 'running'
|
||||
? 'runtime-stopped'
|
||||
: accountCooldown
|
||||
? 'matrix-cooldown'
|
||||
: !ctx.getBotRunning()
|
||||
? 'bot-stopped'
|
||||
: (priority?.processing || (priority?.actionableBacklog ?? 0) > 0)
|
||||
? 'replies-prioritized'
|
||||
: timers.nextMessageAvailableAt !== null && timers.nextMessageAvailableAt > Date.now()
|
||||
? 'pacing'
|
||||
: 'ready';
|
||||
return {
|
||||
accountId: account.accountId,
|
||||
redditUsername: account.redditUsername,
|
||||
runtimeState,
|
||||
authenticated,
|
||||
sendingState,
|
||||
messagesThisHour: messageStats?.messagesThisHour ?? 0,
|
||||
maxMessagesPerHour: ctx.config.rateLimit.maxMessagesPerHour,
|
||||
nextMessageAvailableAt: timers.nextMessageAvailableAt,
|
||||
hourlyResetAt: timers.hourlyResetAt,
|
||||
messagesRemaining: timers.messagesRemaining,
|
||||
actionableReplies: priority?.actionableBacklog ?? 0,
|
||||
invitationCooldown: accountCooldown,
|
||||
failure: snapshot?.failure ?? null,
|
||||
};
|
||||
});
|
||||
|
||||
const stats: BotStats = {
|
||||
isRunning: ctx.getBotRunning(),
|
||||
@@ -53,8 +99,17 @@ export function createStatsRouter(ctx: WebContext): Router {
|
||||
subreddits: ctx.config.reddit.subreddits.map((s) => ({ name: s.name, type: s.type })),
|
||||
targetGenders: ctx.config.reddit.targetGenders,
|
||||
recentActivity: recentActivity(10),
|
||||
accounts,
|
||||
invitationCooldown: cooldown
|
||||
? { until: cooldown.until, reason: cooldown.reason, redditCode: cooldown.redditCode }
|
||||
? {
|
||||
until: cooldown.until,
|
||||
reason: cooldown.reason,
|
||||
redditCode: cooldown.redditCode,
|
||||
...(cooldownRuntime ? {
|
||||
accountId: cooldownRuntime.session.accountId,
|
||||
redditUsername: cooldownRuntime.session.redditUsername,
|
||||
} : {}),
|
||||
}
|
||||
: null,
|
||||
};
|
||||
|
||||
|
||||
@@ -10,11 +10,28 @@ export interface BotStats {
|
||||
subreddits: { name: string; type: 'image' | 'chat' }[];
|
||||
targetGenders: string[];
|
||||
recentActivity: ActivityItem[];
|
||||
accounts: Array<{
|
||||
accountId: string;
|
||||
redditUsername: string;
|
||||
runtimeState: 'created' | 'starting' | 'running' | 'stopping' | 'stopped' | 'failed';
|
||||
authenticated: boolean;
|
||||
sendingState: 'ready' | 'bot-stopped' | 'runtime-stopped' | 'runtime-failed' | 'login-required' | 'matrix-cooldown' | 'replies-prioritized' | 'pacing';
|
||||
messagesThisHour: number;
|
||||
maxMessagesPerHour: number;
|
||||
nextMessageAvailableAt: number | null;
|
||||
hourlyResetAt: number;
|
||||
messagesRemaining: number;
|
||||
actionableReplies: number;
|
||||
invitationCooldown: { until: number; reason: string; redditCode: string | null } | null;
|
||||
failure: string | null;
|
||||
}>;
|
||||
/** Non-null when Reddit has throttled new DM invitations. */
|
||||
invitationCooldown: {
|
||||
until: number;
|
||||
reason: string;
|
||||
redditCode: string | null;
|
||||
accountId?: string;
|
||||
redditUsername?: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user