Black Friday Sale : Get 20% OFF on all plans. promo code: ENGBF2022

Recently, I built a Chrome extension that embdeds a bell into Hacker News, a social news website focusing on computer science and entrepreneurship.

The problem with HackerNews is that there is no way to figure out if someone has commented on your story or reply, thus losing the opportunity to participate in follow up conversations.

In this article, I will explain how I built the extension, and the backend in node.js without hammering the HN API.

Tech Stack

To build the backend process that polls Hacker News api and identify when a user needs to be notified, I used Node.js. For the front-end, we have to use Javascript.

The Logic

I was sure of one thing. We shouldn’t hammer the Hacker News api by creating a polling service for every user who install my extension. That would waste their resources. We should respect their choice of making the API freely available and that too without any rate limits!

Let’s look at the APIs provided by HN.

MaxItem API

https://hacker-news.firebaseio.com/v0/maxitem.json?print=pretty. This is the core of the notification system I built. It returns the id of latest item posted to Hacker News. Item means a new post or a reply.

So whenever a user creates a story, or comment on an existing story, the id of that item will be returned by this API. Our interest is in comments because that’s the event to notify someone.

If we can poll this API every few seconds, that’s all we need to get the latest comments (for all users). There is no need for every user to keep polling this API separately.

ViewItem API

View Item API returns the details of an item. So, If we pass the comment id to this API - https://hacker-news.firebaseio.com/v0/item/<itemId>.json?print=pretty, we will get the following response

{
  "by" : "norvig",
  "id" : 2921983,
  "kids" : [ 2922097, 2922429, 2924562, 2922709, 2922573, 2922140, 2922141 ],
  "parent" : 2921506,
  "text" : "Aw shucks, guys ... you make me blush with your compliments.<p>Tell you what, Ill make a deal: I'll keep writing if you keep reading. K?",
  "time" : 1314211127,
  "type" : "comment"
}

If you look at the response, you know who (by) posted this comment, and on which story (parent). And if we know the author of the parent item, that’s the user whom we need to notify of this comment.

Finding the parent post’s author

We can use the same API to find the parent item details. https://hacker-news.firebaseio.com/v0/item/<parentItem>.json?print=pretty

How to notify the parent user.

We have the parent user’s id and that user needs to be notified of the new reply to their post. But how? We only have their HN user id. This is where the front-end notification bell component helps.

With the Google Chrome extension, I added Engagespot realtime notification feed component into the user’s HackerNews top header. Engagespot needs a unique id to identify the user. With the chrome extension, I was able to fetch the user’s public HN username and used that as the unique id.

So, those users who installed the Google Chrome extension would be able to receive realtime notifications inside their Engagespot bell component.

But still there is another issue

We should send the notification to a HN user, only if the they use our plugin. Otheewise, if we simply call Engagespot Send Notification API for every new comment published on HN, we might hit Engagespot API limits and might be flagged for spam because most of the user’s wouldn’t exist within Engagespot.

So, we need to maintain a list of users who use our plugin and we should call Engagespot send api only if the target username is present in that list.

I didn’t want to have another database instance for this simple functionality. So I used a Redis store to keep the list.

Final Logic

When a new comment is posted to HackerNews by any user -> We fetch the parent item id -> Then we’ll find the parent item’s author -> Check if that username is present in our list of users -> If yes, we call Engagespot Send API with that username as recipient.

Frontend Notification Feed Component

This is straightforward. I saved the Engagespot browser Javascript UI Kit and packed it along with the Chrome Extension, since they do not allow external scripts.

Initialized Engagespot with the user’s HN username, which I could extract from the header. And to embed the bell icon, I inserted a placeholder div into the HN header.

Used the theme property to customize the notification feed to match Hacker News color.


const hnUserId = document.getElementById("me").innerText

Engagespot.render('#esBellIcon', {
      apiKey: 'ENGAGESPOT_API_KEY',
      userId: hnUserId,
      theme:{
        colors:{
            brandingPrimary:"#ff6600"
        }
      }
});

If you like to try the extension, it’s available on Chrome Web Store

The entire project is open source. You can find the source code on Github

Update cookies preferences