Mastodon is a federated micro-blogging service. “Federated” means that there are many servers, each with their own rules, unlike Facebook, Google+ or Twitter. “Micro-blogging” means that you can post status updates up to 500 characters long.

I wrote mastodon-backup so that people can download their own toots, favorites and media attachments.

I also wrote bitlbee-mastodon. This plugin allows Bitblee to communicate with Mastodon instances. Bitlbee is an IRC server connecting to various other text messaging services. You run Bitlbee and connect to it using an IRC client, then configure Bitblee to connect to other services, such as a Mastodon instance where you already have an account. The benefit is that you can now use any IRC client you want to connect to Mastodon.

If you’re new, I recommend this post: How to Mastodon.

2018-10-25 Using a Mastodon Bot

Perhaps if I had a dedicated bot acting on behalf of the blog, like a newsbot. It toots what I post on the blog, and it posts any replies it gets as comments to the blog. Hm. 🤔

I’ll have to think about that. 🧠

I had half of a Blog/Mastodon bridge going for a while until I decided that people on Mastodon weren’t expecting their toots to show up as comments on the blog (including caching and all that), specially as I myself am trying to expire all my old toots. But a dedicated bot would (perhaps?) solve that problem.


Comments on 2018-10-25 Using a Mastodon Bot

That should be relatively easy. I have a few Twitter bots that crawl RSS feeds and post them to Twitter, it’d just be a matter of changing the output API to Mastodon.

Neither costs me anything at the moment.

Wes Baker 2018-10-25 17:08 UTC

Very cool, thanks for the links!

– Alex Schroeder 2018-10-25 20:13 UTC

Add Comment

2018-10-21 RPG Mastodon

I need to keep track of Mastodon and Pleroma instances related to role-playing games...


Add Comment

2018-10-17 Trunk Quality Program

I fear that a lot of the people that volunteered for Trunk have either fallen silent (a common problem), or they don’t actually toot a lot on the topics they signed up for. Perhaps they’re interested in following more people tooting about the topic and were confused about the purpose of the lists, or they do write about the topics but they also write about a gazillion other things, drowning out the signal people might be looking for, or it turns out that they mostly boost other people instead of writing their own toots (in which case we might be interested in adding the people they’re boosting to our lists instead).

It’s difficult! I’m considering going through all the lists (ugh!) and clicking on all the linked people. Removing people from Trunk feels like acting as the content police. It’s awful. I need to get into the mindset of “curating.” Perhaps I wouldn’t feel so bad if I were a curator at a gallery, picking and choosing the people that get exposure. But who am I kidding. I’d still feel bad.

But I want better quality for Trunk! So I need to get into the groove. I need to repeat this, like a mantra:

  • If people are no longer active, I’m going to remove them.
  • If people are mostly boosting others, I’m going to remove them.
  • If people are mostly writing about other stuff, I’m going to remove them.

Should I notify them? I wonder. Are they going to change? I hope not! But perhaps it would still be fair to tell them. Hm. 🤔

Like this, perhaps:

Hi! I’m slowly going through the lists on Trunk to see whether people actually write about the topics they volunteered for. I followed a link to your profile and didn’t see a lot of posts on the topics you were listed under so I’m going to remove you from the lists. I hope you understand. 🙇 If you’re simply interested in reading about a topic, you don’t need to be on the list, you can simply follow people on the list. 🐘


Comments on 2018-10-17 Trunk Quality Program

Yeah, I think that the slight reminder makes a lot of sense. I don’t remember what I supposed to do after joining some lists to be honest.

Jacky 2018-10-17 07:15 UTC

“The road to hell is paved with good intentions.”

People probably intend to post on their chosen topics, but never get around to it. I’m sure people will accept that failing, if it is pointed out to them. It probably doesn’t require individual communication, blanket statement somewhere would be fine.

Fitheach 2018-10-17 08:34 UTC

I liked the comment by @ckeen: “Trunk’s biggest plus is somewhat showing the broadness of possible stuff people talk about. With the usual introductions you will find yourself sitting in a very small bubble. […] So I think trunk is useful as such, I am wondering how much active curating is necessary to achieve good connections.”

Indeed. How much active curating is necessary? I’ll have to think about this some more.

– Alex Schroeder 2018-10-18 20:09 UTC

Add Comment

2018-09-12 OAuth and Mastodon

This page is mostly about trying to debug OAuth for Mastodon. Here’s the thing: I have a web application called Trunk. When you use it, you can mass-follow a number of accounts.

Sadly, I see OAuth issues piling up. I get the impression that my app mostly works, but every day I see reports by users getting “Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method”. The 3 instances I looked at reported their version to be 2.5.0 according to /api/v1/instances. What do you think I should do? How to debug this?

This is why I started writing this page. I’m hoping that some Mastodon client developer can look at the flow of things and tell me where I’m doing it wrong. Or perhaps they are running into similar issues and found a way around it? Perhaps register the app every single time? Who knows. All I know is that I’m seeing multiple reports.

If you want to look at the source code while you read this, you can find it in my repository.

The basic overview of the OAuth flow is this:

  1. Create your app in the instance and make sure you use the same scopes and redirect URL later. This gives you the client credentials client_id and client_secret.
  2. Redirect your user to the instance using the same scopes, redirect URL, and client credentials.
  3. If all went well, you’ll your redirection URL gets visited with a code parameter. Transform it into an access token ASAP (using the same parameters as before).
  4. Use the token as bearer token for each call to the mastodon API.

Here’s what this looks like in my app.

You start out with /follow_confirm. The web site says:

Please confirm
We’re going to use to follow all the accounts in Test.
Let’s do this
If you’d like to help us find the authorisation problems we’ve been having, please use the following link instead:
Let’s log this

When you click the link, you’re sent to the /auth route. There, we’re going to get ourselves a client. We check if the client is already registered. We do this by checking our file with all the client credentials and look for the credentials. If we don’t find them, we’re going to register the client. in this case this is not necessary.

The /auth route now has a client. We’re going to authorise it. This means storing a bunch of cookies in the browser and then redirecting to the oauth URL of If the browser has the cookie set, then no action is required. Otherwise, I need to click the big Authorize button. then redirects back to our application, i.e. the / route, with an authorisation code.

I think this is where people are getting the error: “Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method”. They get the error from the instance, not from my web application, after all.

Screenshot of the error message

Anyway, assuming everything worked as intended... We’re back at / and we need to figure out what to do. If we are being called without a code, then we’re just going to show our main page. But in this case, we did get a code. So now we look at our cookies in order to discover what it was I was trying to accomplish. Ah! I was trying to follow the Test list, right. So we’re going to redirect to /do/follow.

The /do/follow route looks at the cookie and the parameters, again. Yep, got an account, got a list name, got a code... So now we’re going to get ourselves a client! You know how it is. The HTTP protocol is stateless. So we have to redo it all: get the client credentials from the file. This time we have a code, which is cool, so authorise the client again. Now we get the real deal: the authorisation token. Well, in my case the Mastodon::Client library handles all the painful details. But here we are, now. We have a client with the token. We’re good to go!

Now the application starts remote-following the accounts in the list. We end our journey on the /do/follow route. The URL actually contains the code but not the token. I still replaced the client_id and the authorisation code in the log with XXX.

Here’s what the log says:

[Wed Sep 12 22:58:24 2018] [debug] GET "/follow_confirm" (4fa2b1fd)
[Wed Sep 12 22:58:24 2018] [debug] Routing to a callback
[Wed Sep 12 22:58:24 2018] [debug] Rendering cached template "follow_confirm.html.ep" from DATA section
[Wed Sep 12 22:58:24 2018] [debug] Rendering cached template "layouts/default.html.ep" from DATA section
[Wed Sep 12 22:58:24 2018] [debug] 200 OK (0.003705s, 269.906/s)
[Wed Sep 12 22:58:32 2018] [debug] GET "/auth" (9f1d8f22)
[Wed Sep 12 22:58:32 2018] [debug] Routing to a callback
[Wed Sep 12 22:58:32 2018] [debug] wants to authorize the 'follow' action for the Test list
[Wed Sep 12 22:58:32 2018] [debug] found client credentials for id yes, secret yes
[Wed Sep 12 22:58:32 2018] [debug] has a client: yes
[Wed Sep 12 22:58:32 2018] [debug] is being redirected to
[Wed Sep 12 22:58:32 2018] [debug] 302 Found (0.024886s, 40.183/s)
[Wed Sep 12 22:58:32 2018] [debug] GET "/" (8a14f8db)
[Wed Sep 12 22:58:32 2018] [debug] Routing to a callback
[Wed Sep 12 22:58:32 2018] [debug] is authorized for the 'follow' action using the Test list, redirecting to /do/follow?code=XXX&
[Wed Sep 12 22:58:32 2018] [debug] 302 Found (0.000799s, 1251.564/s)
[Wed Sep 12 22:58:32 2018] [debug] GET "/do/follow" (b79fbbdb)
[Wed Sep 12 22:58:32 2018] [debug] Routing to a callback
[Wed Sep 12 22:58:32 2018] [debug] found client credentials for id yes, secret yes
[Wed Sep 12 22:58:32 2018] [debug] has a client: yes
[Wed Sep 12 22:58:32 2018] [debug] authorizing using a code: yes
[Wed Sep 12 22:58:33 2018] [debug] begins to follow 2 accounts from list Test
[Wed Sep 12 22:58:33 2018] [debug] followed 2 accounts from list Test
[Wed Sep 12 22:58:33 2018] [debug] Rendering template "follow_done.html.ep" from DATA section
[Wed Sep 12 22:58:33 2018] [debug] Rendering cached template "layouts/default.html.ep" from DATA section
[Wed Sep 12 22:58:33 2018] [debug] 200 OK (0.762821s, 1.311/s)


Comments on 2018-09-12 OAuth and Mastodon

Did you try with scope written with %20 instead of +?


Other than that this call fail:

If it’s not the scope, your client_id is no longer known by the instance. Did you try to register the app each time to see if the problem comes from your way of storing app clients?

– tom79 2018-09-13 05:41 UTC

It also fails with a fresh client id due to a server side error on this callback for code:


Location: /trunk/do/follow?code=XXXXXXXXXXXXXXXXXXXXXXX&

– tom79 2018-09-13 05:54 UTC

Hm, I need better logging at that point: I see in my logs that you got a 500 error:

[Thu Sep 13 07:51:40 2018] [info] GET 500 0.1443s

But that’s it. As far as I can tell from here, the flow looks correct: you did get authorised or the instance would not have sent you back to the redirect URL with a code. But it did, so that worked. So now the code is about to do this:

  1. get the authorisation token using the code it just got
  2. use the token to create the list, follow people and add these people to the list

– Alex Schroeder 2018-09-13 07:03 UTC

OK, I found a problem! I currently have 159 client credentials but when I look for duplicates, there’s a problem: 4 23 2 3 2

This is obviously a problem because only one of them is going to be the correct client_secret.

Well, at least here’s a clue!

– Alex Schroeder 2018-09-13 07:16 UTC

OK, here’s something else: I while ago I tried to follow the Test list using and got the error “Authorisation failed. Did you try to reload the page? This will not work since we’re not saving the access token.” And just now I tried again and it worked. Clearly not the same error (since the authorisation seems to work) but disconcerting none the less.

– Alex Schroeder 2018-09-13 07:50 UTC

Improved logging, tried following the Test list using my account on

“Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method”

The log:

[Thu Sep 13 10:12:49 2018] [info] GET 200 0.0223s
[Thu Sep 13 10:12:54 2018] [debug] GET "/trunk/auth" (8d6b9c08)
[Thu Sep 13 10:12:54 2018] [debug] Routing to a callback
[Thu Sep 13 10:12:54 2018] [debug] wants to authorize the 'follow' action for the Test list
[Thu Sep 13 10:12:54 2018] [debug] found client credentials for id yes, secret yes
[Thu Sep 13 10:12:54 2018] [debug] has a client: yes
[Thu Sep 13 10:12:54 2018] [debug] is being redirected to
[Thu Sep 13 10:12:54 2018] [info] GET 302 0.0516s

And that’s the end of it! OK, let’s compare this with the flow I described: We have a client and we want to authorize it. We’re going to redirect the user to their instance. If they have the instance’s cookie set, they’re authorized immediately and should get back to our redirect URL (the / route).

But this is not what happens. We’re not being sent back to the redirect URL and the error is shown instead.

– Alex Schroeder 2018-09-13 08:27 UTC

I’m looking at some info @NicolasConstant kindly sent me and the URLs he uses are:

create new app:

    form data: 


redirect sign-in url:        

access_token retrieval 

API access : 
    In the headers:
    'Authorization': 'Bearer [access_token]'

In this case, we’re not yet at the access_token retrieval stage. We’re at the “redirect sign-in URL” stage: matches https://[instance]/oauth/authorize?scope=[scopes]&response_type=code&redirect_uri=[redirect_uri]&client_id=[client_id].

So why is the server rejecting it?

Let’s try the following:

Just do it again. A temporary fluke? → fail

[Thu Sep 13 11:06:46 2018] [debug] Routing to a callback
[Thu Sep 13 11:06:46 2018] [debug] wants to authorize the 'follow' action for the Test list
[Thu Sep 13 11:06:46 2018] [debug] found client credentials for id yes, secret yes
[Thu Sep 13 11:06:46 2018] [debug] has a client: yes
[Thu Sep 13 11:06:46 2018] [debug] is being redirected to
[Thu Sep 13 11:06:46 2018] [debug] 302 Found (0.04456s, 22.442/s)
[Thu Sep 13 11:06:46 2018] [info] GET 302 0.0488s

Delete the client credentials and do it again. Perhaps the client_id is no longer valid? → fail

[Thu Sep 13 11:07:21 2018] [debug] wants to authorize the 'follow' action for the Test list
[Thu Sep 13 11:07:21 2018] [debug] found no client credentials for YYY
[Thu Sep 13 11:07:22 2018] [debug] registered client and got new credentials for YYY: id yes, secret yes
[Thu Sep 13 11:07:22 2018] [debug] has a client: yes
[Thu Sep 13 11:07:22 2018] [debug] is being redirected to
[Thu Sep 13 11:07:22 2018] [debug] 302 Found (0.182976s, 5.465/s)

Oops! What’s YYY doing here? I wonder. My log writing got confused. Will rewrite this section and try again.

– Alex Schroeder 2018-09-13 09:13 UTC

Still borked:

[Thu Sep 13 11:28:07 2018] [debug] GET "/trunk/auth" (a8dae4dc)
[Thu Sep 13 11:28:07 2018] [debug] Routing to a callback
[Thu Sep 13 11:28:07 2018] [debug] wants to authorize the 'follow' action for the Test list
[Thu Sep 13 11:28:07 2018] [debug] found client credentials for id yes, secret yes
[Thu Sep 13 11:28:07 2018] [debug] has a client: yes
[Thu Sep 13 11:28:07 2018] [debug] is being redirected to
[Thu Sep 13 11:28:07 2018] [debug] 302 Found (0.043568s, 22.953/s)
[Thu Sep 13 11:28:07 2018] [info] GET 302 0.0520s

And after removing the credentials – it worked‽

[Thu Sep 13 11:29:38 2018] [debug] GET "/trunk/auth" (353e6e43)
[Thu Sep 13 11:29:38 2018] [debug] Routing to a callback
[Thu Sep 13 11:29:38 2018] [debug] wants to authorize the 'follow' action for the Test list
[Thu Sep 13 11:29:38 2018] [debug] found no client credentials for
[Thu Sep 13 11:29:38 2018] [debug] registered client and got new credentials for id yes, secret yes
[Thu Sep 13 11:29:38 2018] [debug] has a client: yes
[Thu Sep 13 11:29:38 2018] [debug] is being redirected to
[Thu Sep 13 11:29:38 2018] [debug] 302 Found (0.591784s, 1.690/s)
[Thu Sep 13 11:29:38 2018] [info] GET 302 0.6006s
[Thu Sep 13 11:29:42 2018] [debug] GET "/trunk" (2ca628ab)
[Thu Sep 13 11:29:42 2018] [debug] Routing to a callback
[Thu Sep 13 11:29:42 2018] [debug] is authorized for the 'follow' action using the Test list, redirecting to /trunk/do/follow?code=XXX&account=kensanata%40humanities.
[Thu Sep 13 11:29:42 2018] [debug] 302 Found (0.001252s, 798.722/s)
[Thu Sep 13 11:29:42 2018] [info] GET 302 0.0078s
[Thu Sep 13 11:29:42 2018] [debug] GET "/trunk/do/follow" (1d4bad6a)
[Thu Sep 13 11:29:42 2018] [debug] Routing to a callback
[Thu Sep 13 11:29:42 2018] [debug] found client credentials for id yes, secret yes
[Thu Sep 13 11:29:42 2018] [debug] has a client: yes
[Thu Sep 13 11:29:42 2018] [debug] authorizing using a code: yes
[Thu Sep 13 11:29:42 2018] [debug] begins to follow 4 accounts from list Test
[Thu Sep 13 11:29:45 2018] [debug] followed 4 accounts from list Test
[Thu Sep 13 11:29:45 2018] [debug] Rendering template "follow_done.html.ep" from DATA section
[Thu Sep 13 11:29:45 2018] [debug] Rendering cached template "layouts/default.html.ep" from DATA section
[Thu Sep 13 11:29:45 2018] [debug] 200 OK (3.888279s, 0.257/s)
[Thu Sep 13 11:29:45 2018] [info] GET 200 3.8928s

Hm. I am convinced that my rewriting just changed the way things are being logged. Just to be sure, though, I will delete all the client credentials (except for the one I just saved) and we’ll see whether the situation improves.

– Alex Schroeder 2018-09-13 09:38 UTC

I tested and it now works as expected.

– tom79 2018-09-13 11:15 UTC

Amazing. 🤷‍♂️

– Alex Schroeder 2018-09-13 13:51 UTC

Add Comment

2018-09-10 Trunk Explosion

Trunk A while ago, I wrote a little web app called Trunk. It was supposed to help beginners get started. Beginners see a bunch of people in lists and if they’re interested in the topic, they can follow all of these people. And if it failed, or if you wanted to pick and choose, no problem: you could always just click through and pick and choose yourself.

I’ve always asked for people to volunteer for being on the lists because I felt that adding people to lists without them knowing or agreeing to it is rude. It’s a surprise to be suddenly exposed like that! So people had to volunteer: message me and ask to be added to this list or that list. This was also to serve as some sort of minimum quality control: if your timeline is full of spam, I’d be able to deny that request.

Soon, a bunch of friendly people volunteered to help out. This is great. The task doesn’t require any programming, it’s all about getting messages, adding people to lists, and talking with the other admins about this list or that list. Recently one or two accounts with more reach mentioned Trunk and we were flooded with new requests.

If you’re interested in helping out, please contact me and volunteer for the admin team!

I just posted the following call for help:

We’re looking to add volunteers to help out with #Trunk administration. Mostly that means getting messages by people requesting to be added to a bunch of lists. There’s a simple admin interface where you then get to do that. There’s also a decent amount of discussion trying to figure out whether we need to add lists, what to call them, how to describe them, that sort of thing. It sometimes feel like a strange mix of philosophy and the Muppet show.

Some of the things we talk about:

  • What is the best name for a list? I had never heard of Wrenching before, for example.
  • How granular do we want this to be: do we need to have Knitting and Sewing and Crocheting or do we just need Fibre Arts? Do we list Dada or will we end up adding every art movement in history? Early on I was pointed at lumpers and splitters on Wikipedia. This discussion never ends and we might have to go back on them as the fediverse changes. We create lists for programming languages and sports now, but we don’t want to have lists for all the various diet trends: low carb, keto, paleo, etc. Perhaps that will have to change.
  • Do we add NGOs, and if we do, do we add them to a list of NGOs or do we add them to the topics they toot about? We decided to add them to a separate list of Organisations, NGOs & Associations because we want this Trunk instance to be about people connecting to other people.
  • What if the NGO wants to create a list for the NGO itself: FSF, FSFE, EFF, ACLU, Greenpeace, and what about other organisations: political parties, companies? We decided that in this case we’d like these organisations to run their own Trunk instances.
  • What about news bots? Given that we want this instance to be about newbies finding other people, we don’t want add bots.
  • What about people just boosting a lot of other people? Same argument: we’d prefer the people being boosted to volunteer for some of the lists. That would foster the people finding people aspect of it all.

That’s not to say that having lists of boosters and bots could not be useful, too. But it’s not what we want to do. The same is true for foreign languages.

I think that non-English speakers should start separate Trunk instances. Let me know if you’re interested and I’ll help you get it installed and everything. Right now I’m thinking that it doesn’t really make sense to add people that mostly toot in a foreign language. I just wonder about the numbers. It’s easy to say now that we don’t mind a French account tooting about Gamedev even if we don’t speak French, for example. But what will we do when 70% of the people in the Gamedev list are Japanese? So I suspect we’d need to have a “Gamedev 日本語” and “Gamedev Français” and so on. Maybe we’d need to translate “Gamedev” as well: “Spieleentwicklung auf Deutsch”. Soon we’re talking about lists we don’t understand to people we don’t understand... This will not scale.

I’ll try to make Trunk as easy to translate into other languages as I can. Please volunteer if you’re interested in this! 😅


Comments on 2018-09-10 Trunk Explosion

The newer edition of Trunk now comes with a queue and a bot.

I installed the bot as @trunk and every ten minutes it connects to see if anybody mentioned it using the formula “Please add me to a comma separated list of names.” If so, it adds the request to a queue stored in the Trunk app. There, admins have an easy way to accept the request.

What this lacks is feedback! I’ll have to think of something. Right now, the bot will accept direct messages which the admins might not even see. Ideally, the admin’s action would then prompt the bot to reply, I guess.

– Alex Schroeder 2018-09-11 13:06 UTC

Add Comment

2018-09-04 Bitlbee Mastodon Plugin 1.4.0

I tagged a new release of the Bitlbee Mastodon plugin!

New features for 1.4.0:

  • new filter command
  • new list command
  • new settings to hide notifications by type

Incompatible change in 1.4.0:

If you have subscribed to a hashtag, you need to change your channel settings and prepend the hash. Without the hash, the plugin gets confused and things the channel is for a list of the same name. Do this from the control channel (&bitlbee). Let’s assume you have a channel called #hashtag. It’s room setting should be #hashtag. If it’s lacking the initial hash:

channel #hashtag set room
room = ’hashtag’
channel #hashtag set room #hashtag
room = ’#hashtag’


Add Comment

2018-09-03 Unfollowing Lurkers

A direct message reminded me of another way you might want to trim the list of people you are following. Following too many people is a burden. When I see that it is taking too long for me to read all the new toots, it’s time to trim the list. I prefer to follow less people instead of not reading all the toots.

So I’ve added a following command to mastodon-archive. You can list the people you’re following who never mentioned you, and if you’re hardcore enough, you can unfollow them all.

This can probably use some fine-tuning:

  1. editing the list before submitting it?
  2. having exceptions for your favourite bots?

If you have strong opinions either way, let me know.


Comments on 2018-09-03 Unfollowing Lurkers

Released v1.1.0 of Mastodon Archive which includes this feature.

– Alex Schroeder 2018-10-04 21:53 UTC

Add Comment

2018-08-31 Mastodon Bitlbee

So... brainstorming about things I’d like to look at.

  1. Look at issues, of course
  2. Considering better filtering: I’m interested in expiration of filters; using phrases as regular expression; applying filters to usernames too (use them as temporary muting)
  3. I think I’d like to support a tiny bit of rich text: bold and italic, maybe underline. Don’t know about colors! But with Pleroma now doing rich text, we should at least support what IRC supports!


Add Comment

2018-08-30 Dogpiling Wil

Wil Wheaton left Mastodon and he wrote a long blog post about it.

What happened? Here’s what I understand:

Wheaton is famous and gets to see a lot of comments directed at him that he doesn’t care for. When he was on Twitter, he started using block lists. I can’t find the post right now but at one point I thought he used Good Game Auto Blocker by Randi Lee Harper; on his blog post regarding blocklists, trolls, twitter’s systemic inaction against abuse, and the responsibility of wielding great power he mentions Block Together and Twitter Block Chain.

Here’s an extract from Good Game Auto Blocker:


A major problem with social media is the lack of flexible filtering controls. Twitter has a block mechanism, but a user has to initiate contact in order to be blocked. For most forms of harassment, this is an effective way of moderating conversations. Unfortunately, as more social campaigns use Twitter as their basis for communications, this approach becomes less effective. While it’s suitable for use against a single harasser, it’s useless against a large number of accounts targeting a single user. These tweets needed to be stopped before they land in the user’s notifications.

how it works

Good Game Auto Blocker compares the follower lists for a given set of Twitter accounts. If anyone is found to be following more than one of these accounts, they are added to a list and blocked.

That means the blocker will automatically block people that are following people on the block list. It’s contagious, trying to block people before they have actually done anything worth blocking them for. The other side argues, as shown in the quote above, that preventive blocking is necessary when you’re faced with a relentless onslaught.

Apparently, this list contained a lot of trans women. People concluded that Wheaton was therefore a transphobe. He denies it, of course. I haven’t seen any other evidence except for this: he used this blocker, promoted it, and people feel it contained false positives. Wheaton says he removed people who contacted him, except when he felt that they were overreacting, at which point he decided he might want to keep blocking them.

This gets us into the entire topic of tone policing. Marginalized people feel righteous anger, but at the same time Wheaton feels entitled to not having to face it.

And then there’s another element to it all: Wheaton is friends with Chris Hardwick who allegedly abused Chloe Dykstra. If you search the web for these names, you’ll find articles like ‘Speak up, Wesley’: Wheaton Wheaton under fire after he asks for time to process sexual abuse allegations against his best friend, Chris Hardwick. I’m not sure what to think of this. Chloe Dykstra’s story is terrible and heart breaking. Rose-Colored Glasses: A Confession. I couldn’t read it all. I skimmed large part of its. This is very painful. And there’s Chris Hardwick responds to Chloe Dykstra's allegations of sexual and emotional abuse, too. The entire disaster here is beyond words and there never was a trial and there’s no confession, so nobody knows whether it’s true or not. Dykstra’s story sounds compelling and Hardwick’s story is simply a denial. And now what?

Do we always believe the victims, no more fair trials? As a society we’ve struggled for hundreds of years to improve our judicial systems and I’m not yet ready to dump these principles. I want to believe and support victims all I can. But this is a story about Wheaton, and by extension about Hardwick. My heart goes out to Dykstra and everybody in a similar situation. You are not alone. I hope that it does get better. But the rest of this post is about the men in this story – and I cannot in good conscience punish the accused without a fair trial. So, with misgivings, and wishing it was different, the affair remains inconclusive.

In this situation, one might wish Wheaton to clear it all up, make a strong statement, help us decide whether Dykstra is right, whether his friend Hardwick is a terrible person. But it isn’t going to work that way. Wheaton was apparently faced with a constant stream of questions regarding Hardwick, some insulting and some not, but from his point of view, it was simply dogpiling, harassment (Wikipedia: “Harassment, under the laws of the United States, is defined as any repeated or continuing un-consented contact that serves no useful purpose beyond creating alarm, annoyance, or emotional distress.”)

Mastodon was supposed to be better than Twitter because each instance has their own maintainers, their own rules. But Wheaton was being reported 60 times per day and the administrator of his instance decided to kick him. Clearly, this system doesn’t scale, these tools don’t scale.

I am disappointed in how it all turned out. Dykstra’s story is sad. I wish I knew Hardwick was a good man. I wish Wheaton could clear it all up. But as a society, I think the most important thing is that we must be able to live and coexist in a world where these things happen, where these issues cannot be resolved. My wife used to work for the judiciary and now she works for the police and there are thousands of similar situations. Something terrible happened and there is not enough evidence to convict anybody. We try to help the victims, and I think the state could do much better in this respect, but when we cannot convict the accused, we must presume innocence. Sure, we don’t have to be friends with these people, but we shouldn’t punish them, and thus we should not harass them. No “repeated or continuing un-consented contact that serves no useful purpose beyond [...] emotional distress.” We can block and mute them all we want. But don’t send them a constant stream of tweets and toots.

At the same time, there are toots like the following:

POC, LGBT, women, literally EVERY community EXCEPT white guys have been continual targets of dog-piling and harassment from since day one, but when a famous white guy gets a small taste of the abuse... – @Are0h [1]
All the white men crying how disappointed they are in mastodon didnt lift a finger when women were being harassed shut up white men forever – @Laurelai [2]
Most hated star trek actor runs to mommy after girl says a swear – @eweish1 [3]

Ouch! Am I feeling white fragility? (see my post about white emoji.) I need to remind myself: one wrong does not justify another. Well, perhaps they also oppose the dog piling, they just mock the dismay people like me feel at witnessing it as we apparently didn’t lift a finger before. I don’t know. My first impulse is definitely to not engage. And perhaps I’m therefore similar to Wheaton in this respect: I feel like life is too short to deal with unfriendly people. And they of course feel they have a right to unfriendliness, having suffered under the oppression of people “with some or all of the P7 traits (Pale Patriarchal Protestant Plutocratic Penis-People of Power),” as Charles Stross called them in his blog post Dread of Heinleinism. I have no answer to this conundrum. This doesn’t lead to a constructive solution. We will be better off living in separate bubbles.

I feel like this is the long shadow of Gamergate, which I see as an extension of the culture war.

@zlg said: “No matter where you go on this planet, people are still the same.” Is this wisdom or cynicism? I don’t want to turn into a cynic old man who has no hope, but it is increasingly difficult. It’s like 1984: not only do you get punished but you must agree to it in your heart of hearts. And in the end we will see the planet burn and pat each other on the back and laugh because we will all agree: we deserve it.

The best takes on the situation ignore the details of who is right and who is wrong and focus on how we will enable healing to happen, what to watch out for, what to avoid. Things that concern the future. Watch out, both linked posts are about child abuse.

@fraying recommended this: “That vicious little voice inside you that cheers when you lash into someone — that voice is not your friend. It will never help you reach people. It will never change hearts or minds. It cannot build bridges, it can only destroy. It will never let you be happy, and it will never let you heal, because it will never, ever let your abuser die, because it lives inside you and comes out through your voice, your hands.” – It’s up to you, by yesivebeenthere2

@buzz recommended this: “Which is of course why it is so dangerous to join a mob… any mob, no matter how “noble” the stated purpose may be. The mob is almost surely led by a malignant narcissist. And that narcissist is using you.” – Narcissists: Sexists, Racists, Child Abusers, Saboteurs, Internet Trolls, also by yesivebeenthere2


Comments on 2018-08-30 Dogpiling Wil

I enjoy Mastodon but, long term, it won't be better than Twitter, by @baldur.

Wil Wheaton Has a Listening Problem, by Amber Enderton.

Mastodon and the challenges of abuse in a federated system, by @nolan.

Social Media Mobs, by @brentsimmons. The article describes how it feels to be on the receiving end of a mob.

Proposals/Discussion on the 'wilw' Incident, by @SuperFloppies. This one comes with links to Mastodon issues related to defence.

– Alex Schroeder 2018-08-30 and beyond

I’ve been chatting with @mxfraud about @wilw. They had an interesting point: famous (or rich?) people shouldn’t rely on free services (like hosting and moderation). I hadn’t considered it before and I’m not sure I agree. I earn enough money, for example. Does that mean I should find a paid solution? Also, perhaps Wheaton would have donated to the instance’s admin. I wouldn’t know. But the idea itself is interesting. Who deserves free service? One thing I know about myself is that I often don’t feel like paying for Free Software or free hosting because I feel like I’m already giving back, writing Free Software and offering free hosting. I feel like I’m involved in a kind of “pay it forward” scheme already.

We also talked about the need to listen before joining a new platform. Get a feel for the culture, the vibe. At the same time, I know how hard it is. Just looking at the number of people complaining about other people butting into their conversations with unwanted advice. I’m assuming that’s how any sort of advice would have come across to Wheaton. That’s why I don’t fault him for not listening. I’ve also seen the kind of advice offered to him on a thread or two on and in sum it was bad. The good advice was hard to spot.

As for hurting trans women, I’m not sure what the accusation is, exactly. The one I do understand is that he used Randi Harper’s block list to block thousands, and later learned that Randi had blocked some trans people too, but the steps he took to counter this were weak, and by that time the block list had spread, cutting some of them off from their income. Is that it, or is there more to it? If that’s the only accusation, then I understand his position, though: compared to the thousands of trolls, and given the ludicrously bad defences we have on social media, a crude blocking mechanism is the only way to be online in any meaningful way. From his point of view, he used a crude hammer, and he’s sorry, but it isn’t obvious to me (and to him) how this makes him guilty regarding a specific subset of innocent people banned. How is he responsible for other people using the tool he is using if it does the job: making existing on social media bearable? How is he responsible for some people using Twitter as an essential tool for their livelihood? And taken together: if some innocent people are losing their income due to the crude defences deemed necessary on Twitter, isn’t that a problem of the platform? How does that make him guilty, in a moral sense? Surely a lot of other innocent people were banned, but one individual banning another is par for the course, that’s your right (except if you’re the president of the United States of America, apparently, according to Reuters).

Anyway, to focus on the more constructive aspects of it all. I interested in seeing how the moderation tools and defence mechanisms of the fediverse evolve to meet this challenge. And I keep thinking that we need to let go of a Manichaean world view where people have to be all good, all the time, in order to be accepted. That’s not how it works offline and I personally feel that’s also not how it should work online.

– Alex Schroeder 2018-09-03 06:14 UTC

I took the liberty of correcting the second yesivebeenthere2 link. You accidentally linked “It’s Up to You” twice.

zlg 2018-09-15 03:29 UTC

Thank you very much!

– Alex Schroeder 2018-09-17 06:25 UTC

On the topic of blocking, I’ve written a tool, Mastodon Blocker. And @codesections wrote Mastodon De-Mob.

– Alex Schroeder 2018-09-17 06:29 UTC

Add Comment

2018-08-27 Mastodon and rcirc

If you use rcirc (one of the two Emacs IRC clients) and the Bitlbee Mastodon plugin to communicate with a Mastodon instance via Bitlbee, and you want to “dim” the notifications of follows, boosts and favourites:

(eval-after-load 'rcirc
  '(add-to-list 'rcirc-markup-text-functions 'asc:rcirc-dim-keywords))

(defvar asc:rcirc-dim-keywords
  '("favourited your status: "
    "boosted your status: "
    " followed you")
  "Keywords which result in the entire message being dimmed.")

(defun asc:rcirc-dim-keywords (_senders _response)
  "Dim message if it contains particular phrases.
Phrases to take are from `asc:rcirc-dim-keywords'.
Each function takes two arguments, SENDER, and RESPONSE.  The
buffer is narrowed with the text to be printed and the point is
at the beginning of the ‘rcirc-text’ propertized text."
  (dolist (str asc:rcirc-dim-keywords)
    (goto-char (point-min))
    (when (search-forward str nil t)
      (rcirc-add-face (point-min) (point-max) 'rcirc-dim-nick))))

(Mastodon is a free, open-source, decentralized microblogging network. Bitlbee is an IRC server connecting to various other text messaging services. You run Bitlbee and connect to it using an IRC client, then configure Bitlbee to connect to other services, such as a Mastodon instance where you already have an account. The benefit is that you can now use any IRC client you want to connect to Mastodon.)


Add Comment



Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy Policy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.