Skip to content

24c02/fieldmouse

Repository files navigation

fieldmouse

keeping custom profile fields in the upgrade to an enterprise grid org!

slack won't do it so we gotta....

what is this

when you upgrade to Slack Enterprise Grid, they just... don't bring your custom profile fields. or the data in them. which is silly but here we are.

this tool dumps all your custom profile field definitions and user profile data from your old workspace, stores it in sqlite, and then recreates everything in your new enterprise grid org.

N.B.: this uses undocumented API endpoints! it was written to work exactly once! it may be broken by the time you see it, if so send patches?

setup

you need ruby 3.4+ and bundler. then:

bundle install

make a .env file with some slack tokens:

FROM_XOXC_TOKEN=xoxc-...
FROM_XOXD_TOKEN=xoxd-...
FROM_TOKEN=xoxb-...
FROM_URL=https://hackclub.slack.com
TO_XOXC_TOKEN=xoxc-...
TO_XOXD_TOKEN=xoxd-...
TO_TOKEN=xoxb-...
TO_URL=https://wackclub.enterprise.slack.com

if you don't know what an xoxd is and where it comes from, you may not be the target audience.

set up the database:

thor db:migrate

typical workflow:

before you even think about starting your migration:

step 1: dump profile fields

thor profile_fields:dump

grabs all your custom profile field definitions and saves them to the local db.

step 2: dump user profiles

one at a time, to test:

thor users:dump_single USER_ID

then do all of them:

thor users:dump_all

the dump_all command has a bunch of options because slack's rate limits are brutal:

thor users:dump_all \
  --threads=10 \
  --profile-rate-limit=90 \
  --include-restricted=false \
  --force
  • --threads - how many parallel workers (default: 10)
  • --profile-rate-limit - max profile.get calls per minute (default: 90, tier 4 limit is 100)
  • --list-rate-limit - max users.list calls per minute (default: 18, tier 2 limit is 20)
  • --include-restricted - include multi-channel guests (default: false)
  • --include-ultra-restricted - include single-channel guests (default: false)
  • --skip-deleted - skip deactivated users (default: false)
  • --force - re-dump users even if they're already in the db
  • --start-cursor <cursor> - resume pagination if it dies mid-run

once this works, save db.db! stash it away for once you have your shiny new grid org...

step 3: migrate to enterprise grid

easy, right?

after the lift-'n-shift:

step 4: recreate fields on target org

thor profile_fields:push

this creates the fields, but with all the custom ones permissioned to be set by API.

then, create a mapping from old-workspace internal IDs to new-org internal IDs:

thor profile_fields:pull_mappings

this matches by label, and is important to make sure profile info ends up in the right columns.

step 5: put that data back where it belongs

try it on one user to see if it works:

thor users:restore_single FROM_USER_ID TO_USER_ID

(from and to are the same in a real migration, but could be different in testing?)

if that's all good....

pull the trigger.

thor users:restore_all

this will take an eternity because users.profile.set is heavily ratelimited.

once that's done...

step 6: restore field permissions

we set all the fields to be API-editable in step 4, but that means users can't edit them.

luckily:

thor profile_fields:push_permissions

will set things right.

step 7: cry, take a vacation, and bask in the glory of people having their GitHub links in their profile again.

troubleshooting

contributing

why?

license

it doesn't feel right to license this code because it's 99% LLM slop...

...

you can use it if it suits your needs.

signed, your pal nora

About

migrator? i hardly know her!

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages