schnack!

An easy to use and open source commenting system

What the schnack?

Schnack is an open source commenting system written in JavaScript.

  • Tiny! It takes only ~8 KB!!! to embed Schnack.
  • Open source and self-hosted.
  • Ad-free and Tracking-free. Schnack will not disturb your users.
  • It's simple to moderate, with a minimal and slick UI to allow/reject comments or trust/block users.
  • webpush protocol to notify the site owner about new comments awaiting for moderation.
  • Third party providers for authentication like Github, Twitter, Google and Facebook. Users are not required to register a new account on your system and you don't need to manage a user management system.

Quickstart

This is the fastest way to setup schnack.

Requirements:

  • Node.js (>= v6)
  • npm (>= v5)

Clone or download schnack:

git clone https://github.com/schn4ck/schnack

Go to the schnack directory:

cd schnack

Install dependencies:

npm install

Copy and edit the config file according to configuration section:

cp config.tpl.json config.json
vim config.json                 # or open with any editor of your choice

Run the server:

npm start

Embed in your HTML page:

<div class="comments-go-here"></div>
<script src="https://comments.yoursite.com/embed.js"
    data-schnack-slug="post-slug"
    data-schnack-target=".comments-go-here">
</script>

Configuration

schnack will try to read the configuration from the config.json file. The minimal configuration requires the following fields: schnack_host, admins, oauth.secret and at least one oauth provider (id and secret key) and one notification provider. The fields schnack_host and page_url should be hosted on the same domain. If your blog is running at https://blog.example.com, then your schnack instance should be reachable at any subdomain of example.com.

option description
schnack_host the hostname where the schnack server runs (e.g. https://schnack.example.com)
page_url the page where schnack is going to be embeded. The %SLUG% placeholder should be replaceable with you tags (e.g. https://blog.example.com/posts/%SLUG%)
database
  comments the filename of the embeded SQLite database where the user comments are going to be stored (e.g. comments.db)
  sessions the filename of the embeded SQLite database where OAuth session data is going to be stored (e.g. sessions.db)
port the port where the schnack server is going to run (e.g. 3000)
admins an array of userIDs which can login as admin (e.g. [1, 245])
oauth
  secret the secret passed to express-session
  mastodon
    app_name Schnack is going to create the OAuth apps automatically via Mastodon API. While doing so it has to give the Mastodon instance a name and a website url of the external application (you can just use your website title).
    app_website the website url used to create the OAuth apps at Mastodon instances (see app_name)
  twitter
    consumer_key the consumer key for Twitter OAuth apps
    consumer_secret the consumer secret for Twitter OAuth apps
  github
    client_id the client id for GitHub OAuth apps
    client_secret the client secret for GitHub OAuth apps
  google
    client_id the client id for Google OAuth2 apps
    client_secret the client secret for Google OAuth2 apps
  facebook
    client_id the client id for Facebook OAuth apps
    client_secret the client secret for Facebook OAuth apps
notify
  pushover
    app_token the Pushover app token
    user_key the Pushover user key
  webpush
    vapid_public_key the webpush public key
    vapid_private_key the webpush private key
  slack
    webhook_url the Slack webhook URL
date_format how to display dates (e.g. MMMM DD, YYYY - h:mm a)
trust a list of trusted users (see Trust your friends)

Authentication

schnack uses OAuth to authenticate the users of your comment platform, in order to prevent spam without having to implement and manage an own user management system. Users have to be registered for one of the configured providers. You should configure at least one of the OAuth providers in order to allow users to login and write comments. When an user login through an OAuth provider, the session informations are stored into a cookie. In order to allow this action, your schnack instance and the page where you are embedding schnack should reside on subdomains of the same domain.

The secret provided in config.json will be used by express-session to sign the session ID cookie.

Mastodon

  • All you have to do is to define app_name and app_website in the oauth.mastodon section of your config.json. Schnack will then create OAuth applications at Mastodon instances whenever a user tries to sign in (the users are asked to enter a Mastodon domain before signing in).

Twitter

  • Create a new OAuth App on apps.twitter.com
  • Copy the Consumer Key and the Consumer Secret from "Keys and Access Tokens" to oauth.twitter.consumer_key and oauth.twitter.consumer_secret in config.json

GitHub

Google

Facebook

Notifications

When new comments are awaiting for approval, schnack will notify the administrators using one of the following services:

web-push

Web-push is a protocol designed to send push notifications to browsers on mobile and desktop devices. Using a Service Worker it is possible to register a component which is always listening for push notifications, even when the tab or the browser are closed. This allows to send end-to-end notifications from the schnack server to the admins.

In order to configure web-pushes, you should follow these steps:

  • Generate a VAPID key pairs using the web-push package:
node_modules/.bin/web-push generate-vapid-keys
  • Copy the VAPID keys in config.json
  • Add your user ID to the admin array in config.json
  • Copy the sw.js into your website's root path, so that this will be accessible at https://comments.example.com/sw.js
  • Login to your schnack instance and you will be asked to grant the permission for push notifications.

When a new comment is posted, you will be notified with a notification. In order to avoid flooding, schnack will send only a notification every 5 minutes, highlighting the number of comments awaiting for approval.

We strongly reccommend to subscribe to push notifications using Chrome on your mobile device.

slack

schnack can also send a message to a slack channel when a new comment is awaiting for approval. In order to configure this service just create a slack webhook and paste its URL to notify.slack.webhook_url in config.json.

PushOver

PushOver is a service to send notifications to your devices. You can use it to receive schnack notifications. In order to configure it you should first register for an account and download a client. Then you can create an app and copy the token and the key to notify.pushover.app_token and notify.pushover.user_key in config.json.

RSS

If none of the notification services fits your needs, you can still use the RSS feed provided at /feed to stay updated about the latest comments posted. You can also use this endpoint in combination with services like IFTTT.

Localization

The language used in the Schnack form and comments ("Send comment", "Reply", etc.) can now be customized! Just pass any wording you want to change as data-schnack-partials- attribute to the script tag:

<script src="https://comments.yoursite.com/embed.js"
    data-schnack-slug="post-slug"
    data-schnack-target=".comments-go-here"
    data-schnack-partials-reply="Reply to this comment"
    data-schnack-partials-sign-in-via="To post a comment sign in via">
</script>

Here's a list of all the supported attributes (make sure to add data-schnack-partial- in to the keys:

key default value
sign-in-via To post a comment you need to sign in via
login-status signed in as @%USER% (<a class='schnack-signout' href='#'>sign out</a>)
or or
edit Edit
preview Preview
cancel Cancel
reply Reply
send-comment Send comment
post-comment Write your comment here (feel free to use markdown). Please be nice :)
mute mute notifications
unmute unmute
admin-approval This comment is still waiting for your approval
waiting-for-approval Your comment is still waiting for approval by the site owner

Administration

Administrators are managed adding or removing their schnack user ID to the admins array in config.js. When a user logs in as administrator, the moderation UI will appear in the certain comment section. By default it's set to [1]. So the first user will be an admin.

Moderation

It is possible to approve or reject single comments, but it is also possible to trust or block a certain user. An approved comment will be displayed to all users visiting your site, while a rejected comment will be deleted. Comments posted by a trusted users are approved automatically, while comments posted by blocked users will be automatically deleted.

schnack also prevents users from posting the same comment twice.

Trust your friends

You can provide a list of user IDs of people you trust for each authentication provider. For instance, you could use the Twitter API to get a list of all the people you follow and drop that into the trust.twitter in config.js.

"trust": {
    "twitter": [
        "916586732845400064",
        "902094599329591296"
    ],
    "github": [
        1639, 2931, 2946, 3602, 4933
    ]
}

Backups

The most effective way to keep a backup of your data is to take a copy of your comments.db file, which is actually including all necessary data. If you cannot find this file then you probably set another name to database.comments in config.json.

Import comments

It is possible to import disqus XML export and Wordpress XML export. In order to be able to import your comments, a database should already exist and schnack shouldn't be running. The importer requires Node.js >= v9.

Wordpress

You can export your data from Wordpress following this guide. Then you can run the following to import the comments into schnack's database:

npm run import -- wordpress.xml

Disqus

You can export your disqus comments and import them into schnack running:

npm run import -- disqus.xml

Docker

You can build a Docker image for the schnack server running:

docker build -t schn4ck/schnack .

The image will contain everything in the project folder and can be started with:

docker run -p 3000:3000 -d schn4ck/schnack

In order to be able to edit your config file and your SQL database files, you may want to share the project folder with the docker container:

docker run -p 3000:3000 -v $(pwd):/usr/src/app -d schn4ck/schnack

Try schnack

Here you can leave us some comments. Let us know what you think about schnack!