Lazy search for Mastodon accounts
Webfinger + Cloudflare Workers + Firefox custom search enginesAnyone who has been using Mastodon (or other ActivityPub servers) for a bit might have noticed how its a little annoying to look up someone’s “home profile” from their account handle. My personal flow goes something like:
- Open my own mastodon instance
- Search the other user’s handle
- Find the account in the results
- Use the
Open original page
button to jump to their full profile
Luckily, with a little bit of server-side tinkering, this process can be cut down to a single step:
- Search the user’s handle in my browser searchbar
A bit of background
Most (notable) decentralized social media services are built on a web standard called ActivityPub. ActivityPub handles all aspects of cross-instance communication, including the process of looking up users on another instance.
This cross-instance user lookup system utilizes RFC7033: WebFinger, a modern replacement / reimplementation of the old RFC742: Name/Finger protocol.
For example, if you wanted some information about my personal @[email protected]
account, you can send an HTTP GET request to the following URL:
https://ewpratten.com/.well-known/webfinger?resource=acct:[email protected]
..and you’ll get back a response that looks something like this:
{
"subject": "acct:[email protected]",
"aliases": [
"https://social.ewpratten.com/@evan",
"https://social.ewpratten.com/users/evan"
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://social.ewpratten.com/@evan"
},
{
"rel": "self",
"type": "application/activity+json",
"href": "https://social.ewpratten.com/users/evan"
},
{
"rel": "http://ostatus.org/schema/1.0/subscribe",
"template": "https://social.ewpratten.com/authorize_interaction?uri={uri}"
}
]
}
Notice the links[0].href
field above? This is exactly the URL for my profile page, on my home instance!
Plan of action
Now that we know how to get a profile’s “home” URL via WebFinger, we can write a little script to convert an account handle query into a 302 redirect to that account’s URL.
The plan is to make a query like:
GET https://mastodon-redirect.example.com/profile/@[email protected]
and get a repsonse of:
HTTP/1.1 302 Found
Location: https://social.ewpratten.com/@evan
Implementing the redirect script
I chose to do this with a Cloudflare Worker, since my domains are already managed by them, and I have free credits to use.
The script to get this working is pretty simple:
export default {
async fetch(request, env) {
try {
const { pathname } = new URL(request.url);
// If the root is hit, return a basic info page
if (pathname == "/" || pathname == "") {
return new Response("This is a webfinger redirect service.");
}
// Put together common info other functions may need
let profile = pathname.split("/profile").reverse()[0].replaceAll("%40", "@").replace("/@", "").replace("/", "");
let domain = profile.split("@").reverse()[0];
let webfinger_url = `https://${domain}/.well-known/webfinger?resource=acct:${profile}`;
// Handle profile redirects
if (pathname.startsWith("/profile")) {
// Make a request to the webfinger url for JSON data
let response = await fetch(webfinger_url);
// If the response fails, return in
if (!response.ok){
return response;
}
let response_json = await response.json();
// Parse the profile url out of the response
let profile_url = null;
for (let i = 0; i < response_json.links.length; i++){
if (response_json.links[i]["rel"] == "http://webfinger.net/rel/profile-page"){
profile_url = response_json.links[i]["href"];
break
}
}
// Handle the response
if (profile_url) {
return new Response("", {
status: 302,
headers: {
"Location": profile_url
}
})
} else {
return new Response("Could not find a profile-page link for this profile", {status: 404});
}
}
} catch(e) {
return new Response(e.stack, { status: 500 })
}
}
}
For the rest of this post, I’ll assume you have this hosted at mastodon-redirect.example.com
.
Tying everything together with a Firefox search prefix
Note: This probably also works in Chromium-based browsers. I just don’t remember the details of how
Firefox lets users set a prefix on their bookmarks. With a prefix set, you can search things with @yourprefix This is a thing
, and the browser will string-substitute This is a thing
into the bookmark url. Its a handy way to trigger a search inside a specific website without first opening that site.
To set up a search prefix for the redirect service, we need to do the following:
- Create a new bookmark
- Set the url to
https://mastodon-redirect.example.com/profile/%s
- Set the prefix to
@mastodon
(or whatever else you want)
Finally, you can search @mastodon @[email protected]
in your searchbar, and you’ll end up on my profile page!