Adding Comment Capability
Hugo doesn’t provide comments out of the box. Wordpress did, but you had to make an account, which not everyone wanted to do. I could pay for a service that adds comments to my blog but the whole point of this blog is to get better at using AWS, so I’m going to roll my own comment engine. It seems like Hugo natively supports Disqus and can be configured to work with some alternatives to it, so to be clear, this is a learning project, not a recommendation for how to proceed. If you have a goal to get comments on your blog quickly, use one of the pre-built approaches. Since my goal is learning, not quickly achieving the comment feature, I’m going to proceed with building my own.
I have a few requirements:
- No login - you should be able to post a comment without proving who you are
- No spam - random folks and bots from the internet should not be able to post ads or whatever as comments
In order to achieve both of these, there has to be a review, so this post is about my early design for the comment posting and review system.
Let’s try to get more specific about the requirements of the system:
- It has to be able to list the comments that go on a particular post
- It has to accept comments on a post
- It has to let the blog author approve comments before they end up in list 1
I think to accept comments, I’ll render a form at the bottom of pages that posts back to the API Gateway and Lambda solution, and have the lambda trigger a state machine. One of the main use cases for state machine is human-in-the-loop approval systems, which is exactly what we’re building. The setup will look like this:
- User clicks “post comment”
- The Lambda starts a state machine
- The state machine emails me an email with an approve link, a deny link, and the text of the comment
- If I click the deny link, the step function just ends, and the comment never sees the light of day
- If I click the approve link, the step function sends the comment to a lambda.
- The lambda fetches all the comments for that post from DynamoDB, adds the new one, and writes it back.
One caveat to this system is that it assumes that a given post has a stable ID that persists forever.
I could use the post’s slug or title, but then if those ever changed, all the comments would be erased. A
better solution would be to give each post a UUID
Probably the mechanism for persisting that UUID would be
Hugo’s user-defined front-matter feature, but
generating it might require some customization. I’d prefer being able to teach
hugo new to generate a new
UUID and put it in the front matter when I run a post, but that may not be possible. If it’s not, I’ll probably
write a short script that invokes
hugo new and then edits the resulting file to add the UUID. That would
feel kind of hacky, but it would also work fine and be easy.
Now we have a list of code changes that we can get to work on:
- Add custom front-matter to all new posts, giving a UUID to each post
- Write a once-off script to add UUIDs to my existing posts
- Update my html templates so that this UUID gets render client side
- Set up an API Gateway endpoint for the blog
- Write a “getComments” lambda that takes a post UUID, queries DynamoDB for the record with that ID, and formats the result
- Write a “submitComment” lambda that takes a post UUID and JSON document representing a comment, and starts a state machine
- Write a “persistComment” lambda that takes a post UUID and JSON document representing a comment, and appends it to the list of comments about that post in DynamoDB
- Write a state machine that follows the flow described above.
Each of these changes could have its own blog post, so it looks like I have just accidentally planned a series of blog posts on enabling comments on blog posts. Hopefully by the end of it, you’ll be able to let me know what you think!
Till next time, happy learning!