Comments for Jekyll Blogs

jekyll comments blogging 30 comments suggest edit

If you are a long time reader of my blog, you might notice something different starting today. No, the content hasn’t gotten any better. What’s new is the comment system.

The Graffiti Tunnel 38 by Greger Ravik - CC BY 2.0

A long time ago, I migrated comments on my blog to Disqus using this technique to preserve the existing comments. Overall, I’ve been pretty happy with Disqus.

However, they’ve made some recent changes that lead me to consider other options. For one thing, they started adding ads to the free version of Disqus. That doesn’t bother me too much, they are a business after all and they need to make money. I’m just not a fan of the type of clickbait ads warning you about what information the internet has about you, better click here and search your name to find out! No thank you.

It’s possible to pay for an ad-free version of Disqus, but if I’m going to pay, I might as well consider my options. Not only that, but I’ve long had a nagging worry about storing comments outside of my blog. Disqus has a nice export feature, but will they always?

A Jekyll-based solution

That’s when Damien Guard mentioned to me that he’s working on a Jekyll-based comment system.

But wait, you say. Jekyll is a static-site generator. How can you build a comment system? So astute. What Damien realized is we can use data files in Jekyll to store comments and some liquid templates to render them. That all can be static.

The dynamic part is the bit of code that’ll receive a comment form submission and create the appropriate data file in your Jekyll repository. Fortunately, that’s pretty easy using something like an Azure Function or AWS Lambda combined with the GitHub API.

This is what Damien built. He wrote an Azure function that calls the GitHub API using Octokit.net (Install-Package octokit when using NuGet) to create a Pull Request that contains a data file with the content info rendered as Yaml.

Making it Haacked.com

I wrote an importer that takes the Disqus export file and creates all the Jekyll data files. In my case, that ended up creating 25,381 files since there are that many comments on my blog. Wow!

You can see the work I did on haacked.com to implement Damien’s comment system for my blog in this Pull Request. It’s hard to look at the changes because there are so many file changes, but this PR contains four commits:

  1. The changes to my Jekyll templates.
  2. Import all of the comments.
  3. This blog post announcing the change.
  4. A commit where I update the post to link to the third commit. Obviously I can’t link to this fourth commit without creating a fifth commit unless I can break SHA1 and guess the commit SHA of the blog post before I commit.

The first commit is the most interesting for anyone looking to implement this system for their own blog.

The other part you’ll need is to set up an Azure Function. You can pretty much fork my repository and make that the source for your Azure Function. In your Jekyll site’s _config.yml make sure the comments.receiver setting points to your function not mine.

Comment Spam

One thing we lose with this approach is a robust comment spam filter. There are two things that mitigate this - first, when you click to send a comment, the button asks you to click again to confirm sending the comment. This is a poor person’s implementation of spam filtering, but seems to get the job done.

The other part of it is by the very design, all comments are moderated because I have to merge the Pull Request created any time someone submits a comment. However, once I have robust comment spam filters implemented in the Azure function, I could decide to auto-merge those pull requests or even bypass the creation of a pull request. That would simply require that I change the Azure function.

Feedback

As you can see by all the effort I’ve put in over the years to preserve the comments you’ve made on my blog, I value your input. Well, most of it. So next time you leave a comment, consider how important they are to me. Let me know what you think about this new comment system in the comments. And in the off chance you can’t leave a comment because of a bug, open an issue on GitHub.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

30 responses

  1. Avatar for haacked
    haacked June 25th, 2018

    This is a great idea!

  2. Avatar for Damien Guard
    Damien Guard June 25th, 2018

    Yes, it is a great idea!

  3. Avatar for Matthew Abbott
    Matthew Abbott June 25th, 2018

    A typical approach for poor man’s comment filtering would be to include a Honeypot. If the honeypot had a value, ditch the comment as it is likely automated crap.

    Make the honeypot a visibly hidden (but not input:hidden)

  4. Avatar for Dennis
    Dennis June 25th, 2018

    (thumbsup)

  5. Avatar for Arnab
    Arnab June 25th, 2018

    Just checking your comment system.

  6. Avatar for Pedro Lamas
    Pedro Lamas June 25th, 2018

    I would think you can use the Content Moderator from Azure Cognitive Services to do the spam filtering for you! :)

  7. Avatar for smack0007
    smack0007 June 25th, 2018

    I’ve been looking for a reason to leave a comment on your blog for years.

  8. Avatar for Travis Laborde
    Travis Laborde June 25th, 2018

    so, someone can increase their “open source contributor” rankings by commenting on your blog? nice! I’ve contributed to the Haacked Blog!

  9. Avatar for Mohamoud
    Mohamoud June 25th, 2018

    Great read and an excellent idea :) I also appreciate caring about what kinds of Ads your audience are exposed to.  Wish more blogs do the same.

    Thanks also Phil for sharing this project; I always learn something  new from your blog AND from the comments aswell :) 

  10. Avatar for Stephen Cleary
    Stephen Cleary June 25th, 2018

    How wild. I am in the process of migrating away from Disqus on my blog (stephencleary.com) to a very similar solution, for very similar reasons!

    Tip: You can use Staticman instead of running your own Function. I’ve been using Staticman and am very pleased with it. It has reCAPTCHA integration built-in.

  11. Avatar for haacked
    haacked June 25th, 2018

    I realize now that if I have a popular blog post, I will have a lot of PRs to merge!

    I would think you can use the Content Moderator from Azure Cognitive Services to do the spam filtering for you! :)

    Pedro, I may give that a try!

    A typical approach for poor man’s comment filtering would be to include a Honeypot.

    You mean, like this? https://haacked.com/archive/2007/09/11/honeypot-captcha.aspx/

    I’ll probably add something like that too.

  12. Avatar for haacked
    haacked June 25th, 2018

    so, someone can increase their “open source contributor” rankings by commenting on your blog? nice! I’ve contributed to the Haacked Blog!

    Unfortunately, no. The comments are made under my account. Someday I might allow folks to authenticate using their GitHub account to leave a comment, in which case I would create the commit as your user.

  13. Avatar for James
    James June 26th, 2018

    This seems like a big security hole. You’re creating pull-requests out of user data and as evidenced by a pull-request currently there it will display pictures embedded in the post. I can already think of a couple ways to make this go badly.

    At the very least the Pull Request comment should not include the message. Although now I think about it I should go find the repo for the comment system and post that there.

  14. Avatar for haacked
    haacked June 26th, 2018

    At the very least the Pull Request comment should not include the message. Although now I think about it I should go find the repo for the comment system and post that there.

    The whole point of having the comment and avatar in the PR comment is so I can review it before I merge it into my blog. I could omit the comment from the PR, but it’s still visible in a direct link to the yml file.

    https://github.com/Haacked/haacked.com/blob/45d69864e491b9f4a2bf6e6e5dea1202a3cfad39/_data/comments/comments-for-jekyll-blogs/b9421556.yml

    I think a lot of folks who implement such a comment system will have their blog repositories be private. I think the issue I’m running into is I want my blog repository to be public so people can submit fixes.

    One thing I could do is have comments go to a private fork of my repo and then I merge in comments after reviewing them.

  15. Avatar for Elliot Blackburn
    Elliot Blackburn June 27th, 2018

    Someday I might allow folks to authenticate using their GitHub account to leave a comment

    This could be a good way to “trust” users in the future, you could then auto-merge PR’s from those users without checking them yourself by having a .github/trusted.yaml file with their github usernames and use some probot implementation to do the review and merge.

  16. Avatar for Darek Kay
    Darek Kay June 28th, 2018

    I’ve evaluated a lot of different comment systems for static blogs: https://darekkay.com/blog/static-site-comments/

    As you want to utilize GitHub, you might also want to try StaticMan or Gitment. But if you stick to your solution instead, feel free to make a quick update in a few months about your lessons learned (how well does it work? is the spam really manageable? etc.)

  17. Avatar for Imaya
    Imaya June 30th, 2018

    Really nice. Let the testing begin.. Test 1 :)

  18. Avatar for Michael
    Michael June 30th, 2018

    Phil, nice to run into you again. I have been a silent follower of your content back in my .NET days. I had to double check to see if was the same person but how many Haacks are there? Anyhow, I’m investigating the same solution for my Hugo blog which led me to your article. I do like the pull-request idea of Staticman but wish it was more comprehensive and supported Bitbucket. I’m seriously thinking about scratching this itch myself. How big do you believe the need is out there?

  19. Avatar for DAn
    DAn July 2nd, 2018

    That’s rad

  20. Avatar for Jarod
    Jarod July 4th, 2018

    This is a really nice write-up. Also, thanks to commenters for mentioning Staticman.

  21. Avatar for Daniel15
    Daniel15 July 8th, 2018

    One thing we lose with this approach is a robust comment spam filter. There are two things that mitigate this - first, when you click to send a comment, the button asks you to click again to confirm sending the comment. This is a poor person’s implementation of spam filtering, but seems to get the job done.

    Except that a lot of automated spammers just hit the comment API endpoint directly rather than actually using the UI, so a purely UI approach isn’t going to stop very much spam :)

    For basic spam protection, the best thing I found was to have a input field with a common name (like “name”, “subject”, whatever), position it off-screen it with CSS, label it as “do not fill in” so that people using screen readers also know not to fill it in, and discard any comments that have a value for the field. Most automated spammers fill in every form field.

  22. Avatar for gr0k
    gr0k August 9th, 2018

    Found this while trying to figure out how to add comments to my own Jekyll blog. I wanted to use staticman, but the first XSS comment I submitted to my blog popped an alert immediately, so I’ve steered away from that. Does this have any kind of filtering protections? Or does that have to be built into the azure function?

  23. Avatar for Gayan Weerakutti
    Gayan Weerakutti August 14th, 2018

    Thanks. Will try it on my blog.

  24. Avatar for haacked
    haacked August 22nd, 2018

    @grok I haven’t added any automatic filtering. Right now, it’s moderated by the fact that every comment becomes a pull request on the GitHub repository that hosts my Jekyll based blog.

    For example, here’s the pull request for your comment: https://github.com/Haacked/haacked.com/pull/419

    So it is moderated because if a comment is spam, I just close it instead of merging it.

  25. Avatar for Horace
    Horace August 23rd, 2018

    wow

  26. Avatar for Seanba
    Seanba September 11th, 2018

    Just leaving a comment to test this out. Apologies.

  27. Avatar for Sean
    Sean September 30th, 2018

    I like the changes you made to the Jekyll templates that fetch and remember the avatar image without sending any user identity up to the cloud (or back into your gh-pages PRs). I see your javascript employs the HAACK namespace and wanted to double-check that such code is still considered to be under the MIT license. (Thanks for showing your work all the same. I’m looking forward to getting my blog off the wordpress and webhosting teats.)

  28. Avatar for haacked
    haacked October 13th, 2018

    @Sean Which JavaScript code are you referring to? If it’s the code in my blog, then the footer makes it clear that the code is licensed under the MIT license.

  29. Avatar for Andrew Gunn
    Andrew Gunn November 2nd, 2018

    Nice idea.

    You could use Akismet to moderate comments automatically. When I get time, I’ll fork your repository and give it a go.

    https://akismet.com/development/api/

  30. Avatar for danrleywillyan
    danrleywillyan November 8th, 2018

    I use disqs, but it’s not working correctly, thanks for the great idea.