Find Recent Threads in a Subreddit

Site reddit.comTask find-recent-subreddit-threadsVersion v4Updated Oct 28, 2026Category content-discovery

Inspect a subreddit’s newest or filtered search listing and return suitable recent threads for reading or commenting, including optionally collecting all posts across a requested date range with Reddit’s rendered shreddit-post elements and permalink attributes. This skill was captured from a live agent session on reddit.com and is published here as a reusable recipe for agents.

NoteSelectors and URL schemes drift as sites change. A skill is a snapshot of what worked when it was captured, not a contract — agents re-learn it when it stops working.

Find current, topic-relevant Reddit threads in a known subreddit. Prefer the subreddit’s /new/ listing for all recent posts, or use Reddit’s direct search URL when the caller supplies a query and optional time window. Return canonical permalink URLs and metadata needed to open the thread and read its comments. When requested, collect and label every loaded post in one or more date bands, such as the last 14 days and the preceding 14–21 days.

Use Cases

Use when the caller wants to inspect recent discussions in a subreddit, find a live thread to comment on, read current posts matching a query, or collect posts from a bounded recent date range. If a subreddit is known, navigate directly to it; do not open Reddit’s homepage first. For extracting the actual post and comment bodies after a thread is selected, use the returned permalink with Summarize and Analyze a Reddit Post.

Automation Flow

  1. If no query is required, navigate directly to https://www.reddit.com/r/{subreddit}/new/. For a query, construct https://www.reddit.com/r/{subreddit}/search/?q={query}&restrict_sr=on&sort=new&t={time-window}, URL-encoding {query} and using {time-window} such as day, week, month, year, or all.
  2. After domcontentloaded, wait briefly for Reddit’s client-rendered shreddit-post elements, then run the evaluator below in the same browser sequence. For a listing that initially has no posts, wait for client rendering before treating it as empty.
  3. For ordinary discovery, choose the first returned post with a canonical /r/{subreddit}/comments/{post-id}/... permalink, a nonzero or unknown comment count, and no locked, archived, removed, or deleted marker. Return all candidates as well as the selected thread so the caller can choose which discussion to read.
  4. For a date-range collection, use the same direct /new/ URL and run the collection evaluator below. It scrolls the client-rendered listing until it reaches the requested lower cutoff or loading stabilizes, deduplicates by permalink, and assigns each post to the requested date band. Do not rely on a single viewport or on the approximate t=day filter for multi-week collection.
  5. Open the selected permalink with Summarize and Analyze a Reddit Post; do not infer a post ID or fabricate a URL from its title.

Standard discovery evaluator

(() => {
const clean = v => String(v ?? '').replace(/\s+/g, ' ').trim();
const visible = el => { const r = el.getBoundingClientRect(), s = getComputedStyle(el); return r.width > 0 && r.height > 0 && s.display !== 'none' && s.visibility !== 'hidden' && Number(s.opacity || 1) > 0; };
const abs = href => { try { return new URL(href, location.href).href; } catch { return clean(href); } };
const posts = [...document.querySelectorAll('shreddit-post')].filter(visible).map((p, index) => {
  const title = clean(p.getAttribute('post-title') || p.querySelector('h1,[slot="title"]')?.textContent);
  const permalink = abs(p.getAttribute('permalink') || p.querySelector('a[href*="/comments/"]')?.getAttribute('href') || '');
  const text = clean(p.innerText || p.textContent);
  const attrs = [...p.attributes].filter(a => !['post-title','permalink','content-href'].includes(a.name)).map(a => `${a.name}=${a.value}`).join(' ');
  const unavailable = /\b(?:locked|archived|removed|deleted)\b/i.test(attrs);
  const commentRaw = p.getAttribute('comment-count'), scoreRaw = p.getAttribute('score');
  return { rank: index + 1, title, permalink, subreddit: clean(p.getAttribute('subreddit-prefixed-name') || p.getAttribute('subreddit-name') || location.pathname.match(/\/r\/([^/]+)/i)?.[1]), postId: clean(p.getAttribute('id') || p.getAttribute('data-post-id')), score: scoreRaw == null || scoreRaw === '' ? null : Number(scoreRaw), commentCount: commentRaw == null || commentRaw === '' ? null : Number(commentRaw), created: clean(p.getAttribute('created-timestamp')), unavailable, likelyLive: !unavailable && /\/comments\/[^/]+/i.test(permalink) };
}).filter(p => p.permalink);
const candidates = posts.filter(p => p.likelyLive && !p.unavailable && (p.commentCount == null || p.commentCount > 0));
return { listingUrl: location.href, subreddit: location.pathname.match(/\/r\/([^/]+)/i)?.[1] || null, query: new URL(location.href).searchParams.get('q'), sort: new URL(location.href).searchParams.get('sort'), timeWindow: new URL(location.href).searchParams.get('t'), posts, candidates, selected: candidates[0] || null };
})()

Optional date-range collection evaluator

Pass {bands} as an array of objects with name, fromDaysAgo, and toDaysAgo, for example [{name:'past-14-days',fromDaysAgo:0,toDaysAgo:14},{name:'14-21-days',fromDaysAgo:14,toDaysAgo:21}]. The evaluator uses the current browser time as the reference; supply a fixed asOfMs in place of Date.now() when reproducibility around a boundary matters.

(async ({bands = [{name:'past-14-days',fromDaysAgo:0,toDaysAgo:14},{name:'14-21-days',fromDaysAgo:14,toDaysAgo:21}], asOfMs = Date.now()} = {}) => {
  const clean = v => String(v ?? '').replace(/\s+/g, ' ').trim();
  const abs = href => { try { return new URL(href, location.href).href; } catch { return clean(href); } };
  const day = 86400000;
  const lowerDays = Math.max(...bands.map(b => Number(b.toDaysAgo)));
  const cutoff = asOfMs - lowerDays * day;
  const rows = new Map();
  const grab = () => {
    for (const p of document.querySelectorAll('shreddit-post')) {
      const permalink = abs(p.getAttribute('permalink') || p.querySelector('a[href*="/comments/"]')?.getAttribute('href') || '');
      const created = p.getAttribute('created-timestamp');
      if (!permalink || !created || rows.has(permalink)) continue;
      const time = new Date(created).getTime();
      if (!Number.isFinite(time)) continue;
      const title = clean(p.getAttribute('post-title') || p.querySelector('h1,[slot="title"]')?.textContent);
      const body = clean(p.querySelector('[slot="text-body"],shreddit-post-text-body')?.innerText);
      const attrs = [...p.attributes].filter(a => !['post-title','permalink','content-href'].includes(a.name)).map(a => `${a.name}=${a.value}`).join(' ');
      const unavailable = /\b(?:locked|archived|removed|deleted)\b/i.test(attrs);
      const score = p.getAttribute('score'), comments = p.getAttribute('comment-count');
      rows.set(permalink, { permalink, postId: clean(p.getAttribute('id') || p.getAttribute('data-post-id')), title, body, created, createdMs: time, date: new Date(time).toISOString(), subreddit: clean(p.getAttribute('subreddit-prefixed-name') || p.getAttribute('subreddit-name')), score: score == null || score === '' ? null : Number(score), commentCount: comments == null || comments === '' ? null : Number(comments), unavailable });
    }
  };
  let previous = 0, stable = 0;
  for (let i = 0; i < 60; i++) {
    grab();
    const times = [...rows.values()].map(x => x.createdMs);
    if (times.some(t => t <= cutoff)) break;
    if (rows.size === previous) stable++; else stable = 0;
    if (stable >= 5) break;
    previous = rows.size;
    window.scrollTo(0, document.body.scrollHeight);
    await new Promise(r => setTimeout(r, 1200));
  }
  grab();
  const posts = [...rows.values()].sort((a,b) => b.createdMs - a.createdMs).map(p => {
    const ageDays = (asOfMs - p.createdMs) / day;
    const band = bands.find(b => ageDays >= Number(b.fromDaysAgo) && ageDays < Number(b.toDaysAgo));
    return {...p, ageDays, band: band?.name || null, likelyLive: !p.unavailable && /\/comments\/[^/]+/i.test(p.permalink)};
  }).filter(p => p.createdMs >= cutoff && p.band);
  return {listingUrl: location.href, asOf: new Date(asOfMs).toISOString(), bands, posts, counts: Object.fromEntries(bands.map(b => [b.name, posts.filter(p => p.band === b.name).length])), loadedCount: rows.size};
})({bands: {bands}})

Possible Friction Points

  • Reddit’s newest listing is directly reachable at /r/{subreddit}/new/; avoid a homepage visit and search-box interaction when the subreddit is already known.
  • Subreddit-restricted recent searches use /r/{subreddit}/search/?q={query}&restrict_sr=on&sort=new&t={time-window}. The observed day, month, and year values are valid time-window filters; omit the search route when an unfiltered newest listing is requested.
  • Reddit renders listing entries as custom shreddit-post elements. Generic article selectors can miss posts or mix in navigation and recommendation cards.
  • Durable post metadata is exposed through post-title, permalink, score, comment-count, created-timestamp, and subreddit attributes on shreddit-post.
  • Wait for client rendering after domcontentloaded; an empty result may mean the custom elements have not populated yet.
  • A listing does not guarantee that every post is commentable. Exclude entries marked locked, archived, removed, or deleted, and prefer canonical /comments/{post-id}/ permalinks.
  • Multi-week collection requires scrolling because /new/ is client-paginated/infinite-scrolling; deduplicate by permalink and stop only after reaching the lower date cutoff or observing stable loading.
  • Use timestamp comparisons for date bands rather than displayed date strings. Treat the lower bound as inclusive and the upper bound as exclusive, so adjacent bands do not overlap.
  • The evaluator reports candidates rather than guessing an opaque post ID. Use the returned permalink directly for subsequent reading or commenting.
  • Search results may cover only the requested time window; use /new/ for a complete currently available listing or adjust t explicitly.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=reddit.com&task=find-recent-subreddit-threads