A while ago I described a way to turn Github issues into blog comment threads. I’ve been using it without issue, but it’s fairly barebones; I never tried implementing a text box and submit button via the blog post (users had to go to the Github issue page) and it requires that you manually create issues for each post and specify YAML info to link an issue to a particular post. There’s a new tool called utteranc.es that looks pretty slick; it automates the issue linking and does fancy OAuth stuff to let users submit comments from the blog post itself.
One thing utteranc.es doesn’t do is allow you to moderate comments. Granted, there isn’t any mechanism to do this on the Github issues themselves (that wouldn’t make sense for their original purpose) but it’s easy to conceive of a way to, say, prevent certain comments from making it onto your blog post (even if they remain in the Github issue thread itself).
Github
reactions
are a nice feature for collaborative work on code bases, but they have
limited utility for a blog. I figured that I could commandeer a
particular reaction type to use as a way for moderating comments.
For this example, I decided to use a whitelist approach where
comments would only get posted if I (Github username mkoohafkan
)
gave the comment a +1
reaction.
The snippet below scans through the comments of a given issue
and pulls only those that got a +1
reaction from me. The reactions
API doesn’t specify the reaction of each user to each comment when
listing all comments on an issue,
so you actually need to individually query
reactions to each comment.
I made heavy use of
this medium post
to handle multiple asynchronous AJAX requests and prevent the page from
locking up while querying and loading comments. It might not be the
most efficient code, but it works. Test it out by pasting the
code chunk below into an HTML file and opening it in a browser.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id="comments">
</div>
<script type="text/javascript">
function loadComments(data) {
var cuser = data.user.login;
var cuserlink = data.user.html_url;
var clink = data.html_url;
var cbody = data.body_html;
var cavatarlink = data.user.avatar_url;
var cdate = new Date(data.created_at);
$("#comments").append(
"<div class='comment'>" +
"<div class='commentheader'>" +
"<div class='commentgravatar'>" +
'<img src="' + cavatarlink + '" alt="" width="30" height="30">' +
"</div>" +
"<a class='commentuser' href=\""+ cuserlink + "\">" +
cuser +
"</a>" +
"<a class='commentdate' href=\"" + clink + "\">" +
cdate.toLocaleDateString("en") +
"</a>" +
"</div>" +
"<div class='commentbody'>" +
cbody +
"</div>" +
"</div>"
);
}
function getComments(data) {
var results = [];
var deferred = [];
var deferreds = [];
for (var i=0; i<data.length; i++) {
deferred = $.ajax({
url: data[i].reactions.url,
type: "get",
data: {
content: "+1"
},
headers: {Accept: "application/vnd.github.squirrel-girl-preview"},
dataType: "json",
success: function(result) {
if(result.length < 1) {
results.push(false)
} else {
for(var j=0; j<result.length; j++) {
if (result[j].user.login == "mkoohafkan") {
results.push(true);
} else {
results.push(false);
}
}
}
}
});
deferreds.push(deferred);
}
$.when.apply($, deferreds).then(function() {
for(var k=0; k < results.length; k++) {
if (results[k]) {
loadComments(data[k]);
}
}
})
}
$.ajax({
// url should refer to blog post issue number
url: "https://api.github.com/repos/mkoohafkan/mkoohafkan.github.io/issues/29/comments",
type: "get",
headers: {Accept: "application/vnd.github.squirrel-girl-preview.html+json"},
dataType: "json",
success: function(msg){
getComments(msg);
}
});
</script>
</body>
</html>
You’ll see that the first comment I left on this post gets loaded
by the HTML file, but the second one does not; this is because I
only gave a +1
to the first comment. You could easily modify the
code to check for -1
and reverse the true/false values of the
results.push
statements to implement a comment blacklisting
approach. Neat, right?
The main limitation right now is that the reactions API is still in preview, and might change without warning; I don’t want to push this to my blog only to have my comment system suddenly break. But it’s a proof of concept, and should be straightforward to implement once the reactions API is finalized.
Comments
Want to leave a comment? Visit this post's issue page on GitHub (you'll need a GitHub account).