A toolkit to mirror a set of users in a Slack Workspace into a Matrix Homeserver
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
concorde Fixed vulnerabilities in dependencies Sep 18, 2018
scripts fixed inconsistent arg definition Apr 12, 2018
.gitignore zappa settings don't belong in version control Apr 6, 2018
LICENSE Create LICENSE Apr 18, 2018
README.md Update README.md Sep 25, 2018


Concorde: Slack Workspace -> Riot.im Account Migration Manager

So you want to migrate from Slack to Riot.im?

Great choice!

This repo brings together some tools and self-hostable infrastructure to help guide your users from Slack to their new home on Riot.im.

What does it do?

The tools in this repo will help you to:

  • mirror the set of Slack users onto a Matrix.org homeserver
  • advertise Riot.im and the migration process to users on Slack (via a Slack bot)
  • securely allow Slack users to claim their corresponding Matrix IDs via a simple web interface

The end result is that you can guarantee that @alice from your Slack workspace is the same person as @alice:yourdomain.com in Matrix, providing confidence and continuity of identity and ensuring a streamlined migration.

What does it not do?

These tools do not copy or sync rooms, room membership or room history.

What if continuity of identity isn't important to me?

In that case you can use a subset of the tools to manage a simpler migration - you might still want to use scripts/list_slack_users.py to fetch a list of Slack user email addresses and then use the standard Matrix 'invite by email' feature to guide your users onto Riot.im.

Step by step instructions

We are going to (not necessarily in this order):

  • puppet a Slack bot to pull the necessary details out of Slack to pre-register accounts for users on a Matrix homeserver
  • build and deploy a web interface that lets Slack users securely claim their accounts on a Matrix homeserver
  • puppet the same Slack bot to advertise a unique link to each of the migrating Slack users

The migration management web interface comprises a static Mithril.js web form and a stateless python Flask API.

These instructions assume you're using AWS to host the static .js page, and the Flask API has been optimised for deployment to AWS lambda using Zappa, but other hosting options are available and it shouldn't be too hard to adapt.

Before you start

Make sure you have:

  1. Capacity on your Slack instance for another integration (Slack limits free accounts to 10 integrations)
  2. An AWS account
  3. The address of your Matrix homeserver, such as https://matrix.example.com
  4. The registration_shared_secret from the target homeserver homeserver.yaml
  5. passgen_secret - a shared secret to transform Matrix IDs into passwords (can be generated using $ pwgen 80 1)
  6. migration_secret - a shared secret to validate that a user's account claim token was generated by us (can be generated using $ pwgen 80 1)
  7. Installed on your local machine:
  8. Finally: consider posting a public statement on an official channel. Your users will greet a direct message from an unfamiliar Slack bot with skepticism, so make sure you give them enough information that they know it can be trusted 😄


1. Check out this repo

  1. git clone https://github.com/lampholder/concorde.git
  2. cd concorde

2. Build the python library

  1. ~/concorde$ mkdir venv-concorde
  2. ~/concorde$ virtualenv venv-concorde
  3. ~/concorde$ source venv-concorde/bin/activate
  4. ~/concorde$ cd concorde
  5. ~/concorde/concorde$ pip install -r requirements.txt
  6. ~/concorde/concorde$ python setup.py install
  7. ~/concorde/concorde$ cd ..

3.Build the API

  1. ~/concorde$ cd website/api
  2. ~/concorde/website/api$ cp config.example.yaml config.yaml
  3. Update config.yaml to include the address of your target homserver and the generated passgen_secret and migration_secret
  4. ~/concorde/website/api$ zappa init
  5. Accept Zappa's suggestions for all of the values except for:
    • What do you want to call this environment (default 'dev'): - specify production
    • Where is your app's function?: - specify api.app
  6. ~/concorde/website/api$ zappa deploy production and ** note the generated AWS API gateway URL**
  7. ~/concorde/website/api$ cd ../..

4. Build the static site

  1. Create the S3 bucket: ~/concorde$ aws s3 mb s3://your-bucket-name
  2. ~/concorde$ cd website/ui
  3. ~/concorde/website/ui$ npm run-script build -- --env.registrationApiUrl <API gateway URL> --env.homeserver <url of homeserver> --env.slackTeam <Slack team name>
  4. ~/concorde/website/ui$ aws s3 sync ./dist s3://your-bucket-name/production
  5. Log into the AWS console and make /production publicly accessible
  6. Note the public URL of /production/index.html
  7. ~/concorde/website/ui$ cd ../..

5. Register a bot on your Slack workspace

N.B This section might quickly become out of date as Slack changes their UI - please submit a PR if you find any differences as you try to follow these instructions.

  1. Go to https://api.slack.com/apps
  2. Register an app
  3. Click 'Add features and functionality'
  4. Click 'Bots'
  5. Click 'Add a bot user'
  6. Choose a name and avatar that won't startle your users
  7. Click 'Add bot user'
  8. Go to 'OAuth and Permissions'
  9. Install the app to your workspace
  10. Get the bot user oauth token

6. Mirror your Slack users onto the Matrix homeserver and send out the invites

  1. ~/concorde$ cd scripts
  2. ~/concorde/scripts$ ./list_slack_users.py --bot-oauth-token <bot-oauth-token> --fields id username real_name display_name > slack_users.csv
  3. Register the Slack usernames as Matrix accounts:
~/concorde/scripts$ while read line; do
    ./register_matrix_user.py --homeserver <homeserver_url> --homeserver-secret <registration_shared_secret> --passgen-secret <passgen_secret> $user[1]
done < slack_users.csv
  1. Send the invites over Slack DM:
~/concorde/scripts$ while read line; do
    link=(./generate_link.py --migration-secret <migration_secret> <S3 public url for index.html> $user[1] --display-name $user[3])
    ./send_slack_dm.py --bot-oauth-token <bot-oauth-token> $user[0] "Hello $user[3], as you've probably heard we're migrating from Slack to Riot.im - here is your unique link to claim your Riot.im account: $link"
done < slack_users.csv
  1. ~/concorde/scripts$ cd ..

7. Watch the registrations in real time:

  1. ~/concorde$ cd website/api
  2. ~/concorde/website/api$ zappa tail | grep CONCORDE