Summarize and Analyze a Reddit Post

Site reddit.comTask summarize-reddit-postVersion v4Updated Sep 11, 2026Category content-analysis

Open a Reddit post or share link, use Reddit's direct JSON representation when available, extract the original content, media, and discussion context, and return structured material for detailed analysis. 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.

Extract the meaningful content of a Reddit post and supporting discussion without confusing the original post with comments, recommendations, navigation, or mixed page content. Return the title, author, subreddit, body, media references, and discussion context in a form suitable for detailed status-update analysis.

Use Cases

Use when the caller supplies a Reddit post URL, canonical URL, or share link such as /r/{subreddit}/s/{share-id} and asks to open, read, summarize, investigate, or understand the post. Share links must be resolved by Reddit; never guess a post ID from the share token. Use the media references when the post is image- or video-based, but distinguish directly observed post data from interpretation.

Automation Flow

  1. Use the supplied Reddit URL directly and construct its JSON variant by appending .json to the path, for example https://www.reddit.com/r/{subreddit}/comments/{post-id}/{slug}.json. For a share URL, use https://www.reddit.com/r/{subreddit}/s/{share-id}.json and let Reddit resolve it. If the supplied URL already ends in .json, use it unchanged. This avoids a homepage visit and usually returns both the post listing and discussion listing in one navigation.
  2. In one browser sequence, navigate to that JSON URL with waitUntil: "domcontentloaded", wait briefly for the response/viewer to populate, and run the evaluator below. It handles Reddit JSON responses and falls back to the rendered shreddit-post page if Reddit serves HTML instead.
  3. Ground the analysis primarily in title, body, mediaTopic, and mediaAssets. Use keyContext only as supporting discussion context, clearly distinguishing commenters' reactions from the post's claims. If the body is empty, report that the post is textless and rely on title, media metadata, linked media, and discussion context.
  4. When a post links to preview.redd.it, retain the direct media URL and its metadata as an evidence reference. Do not treat a media URL, filename, or image preview as proof of claims that are not represented in the extracted post or visible media.
(() => {
  const clean = v => String(v || '').replace(/\s+/g, ' ').trim();
  const absolute = u => { try { return new URL(u, location.href).href; } catch { return String(u || ''); } };
  const visible = el => {
    if (!el) return false;
    const r = el.getBoundingClientRect(), s = getComputedStyle(el);
    return r.width > 0 && r.height > 0 && s.display !== 'none' && s.visibility !== 'hidden';
  };
  const text = el => clean(el?.innerText || el?.textContent);
  const postData = x => x?.data?.children?.find(c => c?.kind === 't3')?.data;
  const mediaOf = post => {
    const out = [];
    const add = (url, type = 'unknown') => { if (url) out.push({url: absolute(url), type}); };
    add(post.url, post.post_hint || post.media?.type || 'linked-media');
    add(post.thumbnail, 'thumbnail');
    for (const p of post.preview?.images || []) {
      add(p?.source?.url, 'preview-source');
      for (const r of p?.resolutions || []) add(r?.url, 'preview-resolution');
    }
    if (post.media?.oembed?.thumbnail_url) add(post.media.oembed.thumbnail_url, 'oembed-thumbnail');
    return [...new Map(out.filter(x => x.url).map(x => [x.url, x])).values()];
  };
  let parsed = null;
  for (const el of [...document.querySelectorAll('pre,body')]) {
    try { const x = JSON.parse(el.textContent.trim()); if (x) { parsed = x; break; } } catch {}
  }
  if (parsed) {
    const listings = Array.isArray(parsed) ? parsed : [parsed];
    const post = listings.map(postData).find(Boolean);
    if (!post) throw new Error('Reddit JSON contained no post listing');
    const commentListing = listings.find(x => x?.data?.children?.some(c => c?.kind === 't1'));
    const comments = (commentListing?.data?.children || []).map(c => c.data).filter(Boolean).slice(0, 8).map(c => ({author: clean(c.author), text: clean(c.body), score: c.score ?? null})).filter(x => x.text);
    const mediaAssets = mediaOf(post);
    return {
      url: post.permalink ? new URL(post.permalink, 'https://www.reddit.com').href : location.href.replace(/\.json(?:\?.*)?$/, ''),
      resolvedUrl: location.href,
      subreddit: clean(post.subreddit_name_prefixed || post.subreddit),
      postId: clean(post.id),
      author: clean(post.author),
      title: clean(post.title),
      body: clean(post.selftext),
      mediaTopic: [...new Set([post.domain, post.post_hint, post.media?.type, post.link_flair_text, post.url].map(clean).filter(Boolean))],
      mediaAssets,
      keyContext: comments,
      pageTitle: clean(document.title)
    };
  }
  const post = [...document.querySelectorAll('shreddit-post')].find(visible);
  if (!post) throw new Error('Neither Reddit JSON nor rendered shreddit-post was found');
  const first = selectors => { for (const s of selectors) { const v = text(post.querySelector(s)); if (v) return v; } return ''; };
  const links = [...post.querySelectorAll('a[href]')].map(a => ({text: text(a), href: absolute(a.href)})).filter(x => x.href);
  const mediaAssets = links.filter(x => /(?:preview|i)\.redd\.it|\.(?:png|jpe?g|gif|webp|mp4)(?:[?#]|$)/i.test(x.href)).map(x => ({url: x.href, type: 'linked-media'}));
  const comments = [...document.querySelectorAll('shreddit-comment')].filter(visible).slice(0, 8).map(c => ({author: clean(c.getAttribute('author') || c.querySelector('a[href*="/user/"]')?.textContent), text: text(c.querySelector('[slot="comment"]') || c.querySelector('[data-testid="comment"]') || c)})).filter(x => x.text);
  return {
    url: links.find(x => /\/comments\//i.test(x.href))?.href || location.href,
    resolvedUrl: location.href,
    subreddit: clean(post.getAttribute('subreddit-name') || post.getAttribute('subreddit')),
    postId: clean(post.getAttribute('id') || post.getAttribute('data-post-id') || (location.pathname.match(/\/comments\/([^/]+)/i) || [])[1]),
    author: clean(post.getAttribute('author') || links.find(x => /\/user\//i.test(x.href))?.text),
    title: first(['[slot="title"]','h1']),
    body: first(['[slot="text-body"]','shreddit-post-text-body','[data-testid="post-content"]']),
    mediaTopic: links.filter(x => !/\/comments\//i.test(x.href) && !/\/user\//i.test(x.href)).slice(0, 10),
    mediaAssets,
    keyContext: comments,
    pageTitle: clean(document.title)
  };
})()

Possible Friction Points

  • Reddit share links use /r/{subreddit}/s/{share-id} and normally redirect to a canonical post; do not infer or fabricate the opaque post ID from the share token.
  • Appending .json to a supplied share or canonical post path is a useful direct endpoint. Reddit commonly returns an array containing a t3 post listing followed by a t1 comment listing.
  • A browser JSON viewer may expose the response in pre or body; parse the page text rather than selecting arbitrary visible page text.
  • If the JSON endpoint falls back to HTML, Reddit renders the post through the custom shreddit-post element; generic article selectors can mix the post with comments or recommendation cards.
  • Wait briefly after domcontentloaded for client rendering when using the HTML fallback.
  • Prefer JSON fields title, selftext, url, domain, post_hint, preview, and link_flair_text for media and topic identification. Preview URLs may be encoded or contain resizing parameters; preserve them as references rather than treating them as independent claims.
  • shreddit-comment elements or JSON t1 entries are supporting context only; visible comments may be incomplete and are not representative of the entire thread.
  • If Reddit shows access denial, a security challenge, a generic error, or a large login overlay, report that the post could not be read instead of summarizing surrounding page text.
  • A textless image post may have no selftext; analyze only the title, linked/preview media metadata, and available discussion unless visual media inspection is explicitly available.

Call it

GET https://production-sfo.browserless.io/skills?token=TOKEN-HERE&domain=reddit.com&task=summarize-reddit-post