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) |
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 |
client_id | the client id for Google OAuth2 apps |
client_secret | the client secret for Google OAuth2 apps |
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
andapp_website
in theoauth.mastodon
section of yourconfig.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).
- Create a new OAuth App on apps.twitter.com
- Name: the name of your blog
- Description: the description of your blog
- Website: the URL of your schnack instance (e.g. https://schnack.example.com)
- Callback URL: the URL of your schnack instance followed by
/auth/twitter/callback
(e.g. https://schnack.example.com/auth/twitter/callback) - Check the checkbox "Allow this application to be used to Sign in with Twitter"
- Copy the Consumer Key and the Consumer Secret from "Keys and Access Tokens" to
oauth.twitter.consumer_key
andoauth.twitter.consumer_secret
inconfig.json
GitHub
- Create a new GitHub OAuth App
- Application name: the name of your blog
- Homepage URL: the URL of your schnack instance (e.g. https://schnack.example.com)
- Application description: the description of your blog
- Authorization callack URL: the URL of your schnack instance followed by
/auth/github/callback
(e.g. https://schnack.example.com/auth/github/callback)
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!