IRC notifications with TikTokBot (on Debian 8)

I was asked about my setup to get notifications for incoming Webmentions in IRC, so here is some documentation for it. I use aaronpk’s TikTokBot project, which provides an HTTP API to IRC and Slack.


You need a (private) IRC channel somewhere. I personally run my own IRC server using Oragono. It’s on the same server as my IRC bouncer, so I do not have to expose it to the Internet (side-note: if someone has documentation about how to set up a secured, private IRC server with strict user authentication against some backend, I’d love to hear about it). You could also use a private channel on a public network though.

You also need a server to run TikTokBot itself, which requires ruby (here, the same VPS running Debian 8 that runs all my stuff).

primer on running Ruby programs

(I’m not a Ruby dev, corrections welcome)
Ruby dependencies are organized in "Gems". A project’s Gemfile lists all dependencies of the project. A Gemfile.lock is generated to freeze exact versions of the dependencies. Bundler is a tool to create an isolated environment for a project, and then to run applications in this environment (instead of installing dependencies globally, they end up in a .vendor subdirectory)

install TikTokBot

First, install ruby and bundler:

$ apt install ruby bundler

Create a directory for TikTokBot, and download it there. I cloned the git repo, but of course you can also download the zip file from Github and upload it’s contents.

# git clone

check your ruby version

# ruby -v

if it is below 2.2.2, the dependency version snapshot in the current Gemfile.lock doesn’t work. As a workaround, I just deleted it, and let the installation pick it’s own versions, and it works out OK for now.

install dependencies:

# bundle install

configure TikTokBot

TikTokBot has 3 configuration files.
In config.yml a server needs to be defined, and to bot is instructed to join a channel (e.g. #webmentions) – look at the example file for reference. Similarly, in token.yml at least a global token has to be created – all other lines can be deleted. We don’t need any hooks (=webhooks sent when specific things are said in IRC), so hooks.yml is filled with

hooks: []

start TikTokBot

as described in the README, run

# bundle exec ruby tiktok.rb localirc

(replace localirc with the name of your server definition)
Now the bot should connect to IRC and appear in the channel.

test sending

Now we’ll send the bot a command to send a message to the channel. This is done by sending a form-encoded POST request to the /messag endpoint of it’s API, e.g. using curl:

# curl -H "Authorization: Bearer TOKEN" -X POST -F 'channel=#webmentions' -F 'content=HELLO WORLD!' http://localhost:9000/message

(obviously, fill in your actual token, the channel and the API location)

persistent start using systemd

I’ve written a systemd unit file for TikTokBot, which runs it as it’s own user and group (which have to be created before):

Description=Tiktokbot for local IRC

ExecStart=/usr/local/bin/bundle exec ruby tiktok.rb localirc


Place it in /etc/systemd/system/ as e.g. tiktok_local.service and systemctl enable and systemctl start it.

integrate with the rest of your site

Now, you can start sending form-encoded POST requests just as above to TikTokBot and it’ll report events in IRC.

note on restarts

During testing it has occasionally happened to me that the API portion of TikTokBot didn’t shut down cleanly, which meant that starting TikTokBot again failed with an error like

* Listening on tcp://
== Someone is already performing on port 9030!

In this case, you have to manually kill the left-over puma processes. If you find a solution to this problem, please contribute it at this GitHub issue

Notes for HomebrewWebsiteClub 2017-04-05

We started this HWC by discussing future plans for our meetup, especially how to promote it and how to find a better location. (Afterwards, Florian created a group at I've also been building a web site for HWC – mostly for learning CSS Flexbox and Grid layouts, but maybe we’ll turn it into an actual page.

Florian had brought a bunch of interesting links:

This led back to a discussion from 2 weeks before, where we had talked about about tracking and respecting user requests like the Do-Not-Track-header. Joel mentioned the CommonTerms project, which proposes icons for typical clauses in Terms and Conditions.

He showed how on one of his web pages, he does not just disable tracking for users that have the Do Not Track header set, it also clearly indicates this to users:

“Active tracking using Piwik on this page has been disabled based on your browser's Do Not Track (DNT) setting.”

Another example are the cookie banners made by TRUSTe, which allow a visitor to choose between different types of cookies used, if they find the right link to click:

Differential privacy was mentioned, but nobody knew enough to really talk about it. Here is a slide deck about the topic a friend made a few years ago.

Another privacy aspect covered was how federated/distributed systems by design create many additional copies of data, with less centralized control over them. This is of course a desired property, but it also means that these copies might be hard to delete and are presented in different aggregations users might not be aware of. While a deleted silo post is expected to be gone from outside of dedicated archives, a deleted post on a GNU Social/Mastodon instance likely is still visible on other federated instances. If one instance blocks search engines using robots.txt, content from it still might be indexed on other sites. In an IndieWeb context, a site that backfeeds from Twitter likely still shows deleted interactions (and in general shows them in an unexpected context). Many IndieWeb tools also have public logs or APIs retaining data, which might be surprising to users. (e.g.,

Other random links that were mentioned:

Talking about our private sites, only I had progress to present: I improved my Micropub endpoint, and I have now explicit headers for replies, bookmarks, …: example post

Today I wondered why #Firefox suddenly had become slow and laggy again. Turns out it tries to detect the use of accessibility tools and then disables Electrolysis (seperate rendering processes) for a week and goes back to it's old, laggy single-process model. I assume this was triggered by taking a screenshot with the Windows Snipping Tool in my case. Luckily, there is a preference to turn this detection off.

notes for HWC Berlin 2017-03-08

At yesterday's HWC we talked a bit about the recently released W3C Annotation standards and annotations in general. The W3C standards have many ways of addressing content (“selectors”), many of which likely only work against a specific version of a document and site design. But there is a way to specify timestamps and link archived copies.

Examples of annotation UIs (not using the W3C standards (yet)): related Indieweb components:

Some discussion about (over-)sharing in social media, your own website, and a trend to move social media content to private channels.

Joel found the Indieweb wiki because he found while searching for a new OpenID provider, and joined us.

References from last time: Things randomly mentioned:
  • JSON Web Tokens as a standard way to create signed tokens with payloads, useful for e.g. authentication endpoints.

Some notes for HWC Berlin 2017-02-22

Just some quick notes and links for things we talked about at last night’s HWC Berlin.
  • We talked about various messaging-related topics:
    1. as a relatively new and open messaging protocol.
    2. The private webmention specification created from IWC Brighton.
    3. Sebastian would like a chat interface on his contact page so visitors can quickly talk to him if he is available. There are bunch of services targeted at e-commerce sites, but from a quick review not much suitable for individual pages. This was also discussed on IRC. (I’ll probably follow up on this in another post, once I ordered my ideas a bit)
  • IndieAuth-the-protocol – several attendees weren't aware that they can use their own systems (e.g. existing website login) for IndieAuth and want to implement this now. Documentation for the necessary authorization endpoint is here.
  • Security: Caddy server has a new fingerprinting feature to detect TLS interception proxies. One could show a warning to users along the lines of “Your HTTPS looks wonky. ”. I tried to think of additional ways to detect this, but the only one I could come up with, detecting missing HPKP headers using Javascript, wouldn't work because Firefox and Chrome ignore HPKP on local trust roots, so there is no need for a proxy to strip those.
Morning trip to #IndieWebCamp #Düsseldorf. Taking a Thalys high-speed train today instead of the Regio, which is faster, more comfortable, has wifi… and is cheaper?!