How to safeguard Disqus comment sections


This post demonstrates how to integrate Hexis API with the Disqus discussion system. You can automatically detect harmful messages, block them, and provide authors with an error message – all in a matter of microseconds.

Disqus is a widely used service for commenting on blogs that provides a good user experience and everything you would expect from a discussion system. But we don't want to rely on its built-in toxicity filter which has a hard time grasping hate speech and other strong forms of verbal abuse, so we will integrate with Hexis API and have it check on every new comment that is posted via Disqus.

Note: If you don't have an Hexis API key yet, head over to the main site and create one for free. Also, you will need to register for the Disqus API.

Our integration can be implemented using a callback as shown in the Disqus documentation. Given the standard embed code

var disqus_shortname = '<example>';  // Required - Replace example with your forum shortname

(function() {
  var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();

it is possible to add a function that's fired when a new comment is posted. All we need to do is wrap the Hexis API client code inside a onNewComment callback and add that to the standard embed code.

We can implement this on the client-side using only vanilla Javascript (no frameworks needed).

var disqus_config = function() {

  this.callbacks.onNewComment = [function(comment) {
    var HEXIS_URL = 'https://api.hexis.ai/off/en/v1';
    var HEXIS_KEY = 'Your Hexis API key';
    var THRESHOLD = 0.9;
    var DISQUS_URL = 'https://disqus.com/api/3.0/posts/remove.json';
    var DISQUS_KEY = 'Your Disqus API key';
    var STOP_MESSAGE = 'Please rephrase your comment. It looks like your comment is likely to be interpreted as rude or disrespectful.';
    var ERROR_MESSAGE = 'An error has occured. Please try again.';

    var data = JSON.stringify({'text': comment.text});
    var xhr = new XMLHttpRequest();
    xhr.open('POST', HEXIS_URL, true);
    xhr.setRequestHeader('Authorization', 'Bearer '+HEXIS_KEY);
    xhr.onload = function () {
      var res = JSON.parse(this.response);
      if (res.scores != null) {
        if (res.scores[0] > THRESHOLD) {
          alert(STOP_MESSAGE);

          var data2 = JSON.stringify({'api_key': DISQUS_KEY, 'post': comment.id});
          var xhr2 = new XMLHttpRequest();
          xhr2.open('POST', DISQUS_URL, true);
          xhr2.onload = function () {
            var res2 = JSON.parse(this.response);
            if (res2.code != 0) {
              alert(ERROR_MESSAGE);
        }
      } else {
        alert(ERROR_MESSAGE);
      }
    };
    xhr.send(data);
  }];

};

Enter your API keys at the beginning of this function as HEXIS_KEY and DISQUS_KEY.

The Hexis THRESHOLD value is set relatively high with 0.9. This is because in the given example we will not be reviewing but instantly rejecting any message above this value, so we probably don't want it to be overly sensitive. Of course this value can be tuned depending on your use case. For more information see the Hexis documentation.

Instead of discarding comments right away it is also possible to set DISQUS_URL to https://disqus.com/api/3.0/posts/report.json. This will flag comments and allow for their manual moderation.

Finally, our approach implies that API keys are public – which is not a problem in itself, but we need to limit API access to only this HTML file using the Client Restrictions in your account page.

Enter the full URL address of the file (including http://) in the field Allow Referrer URL and you're set.

Test your input form protection using any kind of foul language and the following error message will appear.

Well done, no more harmful messages coming through your Disqus comments!

More options

Complementary to the integration shown above, it is possible to split functionality between the client and server-side. This has the upside of being able to hide connection details such as the API key and not only rely on referrer-based access control. If you're not running a web application yourself, the easiest way to accomplish this is probably via a small PHP script as discussed in another post on how to safeguard any input form.