Show HN: In-browser script for getting your best/worst comments

3 years ago

I was curious to go back in time a bit and see how many downvotes my "worst" comments had received. Pleasantly surprised, it seems the minimum was just -4 which doesn't feel too bad. While doing this, I figured might as well look at the top ones as well, and ended up with a little script to automate it.

Before running the script, go to the "threads" page where your comment trees are listed, the link is in the top nav.

    // Maximum number of pages to fetch, in case you have a ton of them
    const MAX_PAGES = 100
    // Wanna be nicer to HNs infrastructure? Increase this number
    // If you decrease it too much, you WILL get rate-limited!
    const WAIT_TIME_MS = 1000

    const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

    const load_next_page = async (iteration_count = 0) => {
        const more_link = document.querySelector('.morelink')
        console.log('Now on page: ' + (iteration_count + 1));
        if (more_link && iteration_count < MAX_PAGES) {
            const href = more_link.href;
            const next_page = await fetch(href).then(r => r.text())
            const new_page = document.createElement('div')
            new_page.innerHTML = next_page
            document.body.appendChild(new_page)
            more_link.remove()
            await wait(WAIT_TIME_MS)
            await load_next_page(iteration_count + 1);
        } else {
            console.log('All pages loaded!')
            return
        }
    }

    const main = async () => {
        await load_next_page()
        console.log('Grabbing comments')
        const comheads = document.querySelectorAll('.comhead')
        console.log("Grabbing all comments")
        const username = document.querySelector('#me').innerText
        console.log("Filtering comments")
        const my_comments = Array.from(comheads).filter((el) => {
            return el.querySelector('.hnuser').innerText == username
        })
        console.log("Extracting scores and link")
        const comments = []
        my_comments.forEach((comment) => {
            window.comment = comment
            comments.push({
            link: comment.querySelector('.age a').href,
            score: parseInt(comment.querySelector('.score').innerText.split(' ')[0]),
            timestamp: comment.querySelector('.age').getAttribute('title'),
            onstory: comment.querySelector('.onstory a') ? comment.querySelector('.onstory a').innerText : null,
            intro: comment.parentElement.parentElement.querySelector('.commtext').innerText.slice(0, 100)
            })
        })
        console.log("Sorting")
        const sorted = comments.sort((a, b) => a.score < b.score)
        console.log()
        console.log('### Top ten comments ###')
        console.log()
        sorted.slice(0, 10).forEach((comment) => {
            console.log(`${comment.score} - ${comment.link} - ${comment.timestamp} - ${comment.onstory}`)
            console.log(JSON.stringify(comment.intro))
            console.log();
        })
        // console.log(JSON.stringify(sorted.slice(0, 10), null, 2))
        console.log('### Worst ten comments ###')
        console.log()
        sorted.slice(-10).forEach((comment) => {
            console.log(`${comment.score} - ${comment.link} - ${comment.timestamp} - ${comment.onstory}`)
            console.log(JSON.stringify(comment.intro))
            console.log();
        })
        // console.log(JSON.stringify(sorted.slice(-10), null, 2))
        window.localStorage.setItem('my_comments', JSON.stringify(sorted))
        console.log('Saved all comments in localStorage.my_comments')
    }

    main()

After running the script in your browser console, you'll end up with some output about your best and worst comments.

Every comment that was found is also saved in `localStorage.my_comments` in case you want to do some further processing, and we can also share snippets of code that uses that, so not everyone have to always re-run the collection.

By using `localStorage.my_comments`, here is another addon-script that formats the top/worst list for HN and puts the output into your clipboard:

    const comments = JSON.parse(window.localStorage.getItem('my_comments'))

    let text = 'My top 3 comments:\n\n'
    comments.slice(0, 3).forEach((comment) => {
        text = text + `- ${comment.score} - ${comment.link} - ${comment.timestamp} - Story: ${comment.onstory} - Comment: ${JSON.stringify(comment.intro)}\n\n`
    })
    text = text + 'My 3 worst comments:\n\n'
    comments.slice(-3).forEach((comment) => {
        text = text + `- ${comment.score} - ${comment.link} - ${comment.timestamp} - Story: ${comment.onstory} - Comment: ${JSON.stringify(comment.intro)}\n\n`
    })
    copy(text)

Please note that you need to run the script from the submission before you can run the above script.

Example output:

My top 3 comments:

- 180 - https://news.ycombinator.com/item?id=35153482 - 2023-03-14T15:49:54 - Story: null - Comment: "Ah, it seems you're one of many who confuses \"crypto\" with cryptography and cryptocurrency. Cryptogr"