DEV Community

Deva
Deva

Posted on

Building profile sync: 19 platforms, 6 API shapes, 3 with no API at all

Three platforms in my live run had no profile API at all. dev.to, mataroa, and pika.page all require you to open a browser and click through a settings page. You can automate almost everything across 19 platforms and still end up with a checklist item that only a human can close.

That observation motivated the whole profile sync subcommand. I had been updating my bio, avatar, and banner manually every time I tweaked the copy, which was stupid for the same reason any repeated manual task is stupid: it drifts. The bio on Bluesky would be a month behind the one on Mastodon. The avatar on Telegraph would be a PNG from a year back that predated the actual brand kit.

The fix: a single identity.json with a bio rich in keywords, a four link graph, and topic hashtags I wanted everywhere, plus a brand/ directory holding the canonical 400x400 avatar and 1500x500 banner pulled from @DevaBuilds. One source of truth.

The implementation splits into six adapter shapes:

  • Nine Mastodon instances: display_name, note, fields, avatar, header via the credentials update endpoint
  • Bluesky: actor.profile update plus blob upload for assets (the blob step is easy to miss if you only read the profile PUT docs)
  • Nostr: one kind 0 metadata event, shared key deduped so you do not blast the same event to every relay
  • Matrix: display name and avatar URL
  • prose.sh: overwrite _readme.md via the SSH publishing interface
  • Telegraph: editAccountInfo

The , only flag lets you target a subset: profile sync, only bluesky,mastodon when you just need to push a bio change without touching image assets.

23 hermetic tests cover the pure builder logic and dispatch routing. No live network in CI: the adapters get fakes that assert on the exact API calls made.

Live run results: 13 out of 15 API profiles updated and spot verified. Bluesky and Mastodon read back with the correct avatar and banner. Two failures:

Glasgow Social had login disabled at the instance level, so the Mastodon adapter could not authenticate. Nothing in the API response tells you this is a permanent policy versus a transient auth error. You get a 401 and have to go look at the instance manually.

Buttondown's newsletter PATCH is gated on a paid plan. The free tier gives you a newsletter but not the API endpoint to update your profile metadata. That one is surfaced as a known limitation; the adapter errors fast with a clear message.

What I would do differently: model the "no API, web UI only" case more explicitly in the platform registry. Right now dev.to, mataroa, and pika.page are documented in a comment. A better design has them as a first class platform type that surfaces directly when you run profile sync: "3 platforms require manual update, open these URLs." The current approach treats them as outside the tool, which means they stay invisible until you wonder why your dev.to bio looks stale.

The other thing: instance failures on Mastodon should be flagged separately from credential failures. Both are 401s but one is recoverable (rotate the token) and one is not (the instance is gone or login disabled). Worth adding a probe step that distinguishes them before the full sync run. Right now you only find out mid run.

Top comments (0)