Reduce Reddit profile screening requests

This commit is contained in:
jjbrunton committed 2026-08-08 20:11:03 +01:00
1 parent 3d015c4e80
commit 1833e94a10
4 files changed
+97 -37

No files matched your search

+41 -37
View File
@@ -36,9 +36,12 @@ export class MonitorService {
this.logger.debug(`Checking r/${subreddit.name} (${subreddit.type}) for new posts...`);
const posts = await this.redditApi.getNewPosts(subreddit.name, 25, subreddit.type);
// Filter for valid, unprocessed posts
const validPosts: RedditPost[] = [];
for (const post of posts) {
// Reddit normally returns /new in descending order, but sort explicitly
// so we can stop as soon as the first fully eligible candidate is found.
// Previously we screened the entire batch before choosing one, causing up
// to two profile requests for every otherwise-valid post in the listing.
const newestFirst = [...posts].sort((a, b) => b.created_utc - a.created_utc);
for (const post of newestFirst) {
if (this.postsRepo.isProcessed(post.id)) {
continue;
}
@@ -60,16 +63,7 @@ export class MonitorService {
);
if (isSeller) {
this.logger.info(`Skipping post ${post.id} from u/${post.author} - seller signals detected`);
this.postsRepo.insert({
id: post.id,
subreddit: post.subreddit,
author: post.author,
title: post.title,
postUrl: this.redditApi.getPostUrl(post),
imageUrl: subreddit.type === 'image' ? this.redditApi.getImageUrl(post) : null,
processedAt: Date.now(),
});
this.postsRepo.setError(post.id, 'Seller signals detected');
this.recordRejection(post, subreddit.type, 'Seller signals detected');
continue;
}
}
@@ -81,41 +75,33 @@ export class MonitorService {
const tag = parseGenderTag(`${post.title}\n${post.selftext ?? ''}`);
if (!tag) {
this.logger.debug(`Skipping chat post ${post.id} - no gender tag in title/body`);
this.recordRejection(post, subreddit.type, 'No gender tag in title/body');
continue;
}
if (!targetGenders.includes(tag)) {
this.logger.debug(
`Skipping chat post ${post.id} - gender tag "${tag}" not in target list [${targetGenders.join(', ')}]`,
);
this.recordRejection(post, subreddit.type, `Gender tag "${tag}" not targeted`);
continue;
}
}
validPosts.push(post);
}
if (validPosts.length > 0) {
// Sort by creation time (newest first)
validPosts.sort((a, b) => b.created_utc - a.created_utc);
if (prioritizeRecent) {
const recent = validPosts.find((p) => p.created_utc >= recentCutoffSec);
if (recent) {
this.logger.info(`Found ${validPosts.length} new posts in r/${subreddit.name} (recent match)`);
return [recent];
}
// Remember the freshest non-recent candidate as a fallback and
// keep scanning other subs for an actually-recent post.
if (!fallback || validPosts[0].created_utc > fallback.created_utc) {
fallback = validPosts[0];
}
} else {
this.logger.info(`Found ${validPosts.length} new posts in r/${subreddit.name}`);
// Return just the first (newest) valid post
// This ensures we switch to a different random subreddit on the next poll cycle
// instead of processing a batch from the same subreddit
return [validPosts[0]];
// At this point the candidate has passed every check. Select it now
// rather than spending more Reddit requests screening users that
// cannot be acted on during this poll cycle.
if (!prioritizeRecent || post.created_utc >= recentCutoffSec) {
this.logger.info(
`Found eligible post in r/${subreddit.name}${prioritizeRecent ? ' (recent match)' : ''}`,
);
return [post];
}
// This is the newest eligible post in this subreddit. Keep it as a
// possible fallback, then move to the next subreddit to look for a
// recent candidate. Older posts in this batch cannot improve it.
if (!fallback || post.created_utc > fallback.created_utc) fallback = post;
break;
}
} catch (error) {
if (error instanceof RedditRateLimitError) throw error;
@@ -186,4 +172,22 @@ export class MonitorService {
private sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/** Persist a completed screening decision so later polls do not repeat it. */
private recordRejection(
post: RedditPost,
subredditType: 'image' | 'chat',
reason: string,
): void {
this.postsRepo.insert({
id: post.id,
subreddit: post.subreddit,
author: post.author,
title: post.title,
postUrl: this.redditApi.getPostUrl(post),
imageUrl: subredditType === 'image' ? this.redditApi.getImageUrl(post) : null,
processedAt: Date.now(),
});
this.postsRepo.setError(post.id, reason);
}
}