Skip to content

Instantly share code, notes, and snippets.

@ryancdotorg
Created May 10, 2023 23:49
Show Gist options
  • Save ryancdotorg/5114a172636148b3403d5509a1c79795 to your computer and use it in GitHub Desktop.
Save ryancdotorg/5114a172636148b3403d5509a1c79795 to your computer and use it in GitHub Desktop.
bluesky public api blocklist scanner
async function json_fetch(url) {
return (await fetch(url)).json();
}
async function bsky_resolve_handle(id) {
if (id.length && id.charAt(0) == '@') { id = id.substr(1); }
const url = `https://bsky.social/xrpc/com.atproto.identity.resolveHandle?handle=${id}`;
const j = await json_fetch(url);
return j.did;
}
handles = new Map();
async function bsky_resolve_did(id) {
if (handles.has(id)) { return handles.get(id); }
if (!id.startsWith('did:plc:')) { id = await bsky_resolve_handle(id); }
const url = `https://bsky.social/xrpc/com.atproto.repo.describeRepo?repo=${id}`;
const j = await json_fetch(url);
handles.set(id, j.handle);
return j.handle;
}
async function bsky_profile(id) {
if (!id.startsWith('did:plc:')) { id = await bsky_resolve_handle(id); }
const results = await bsky_records(id, 'app.bsky.actor.profile');
return results.length ? results[0] : {};
}
async function bsky_records(id, collection) {
if (!id.startsWith('did:plc:')) { id = await bsky_resolve_handle(id); }
const url = `https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=${id}&collection=${collection}`;
const results = [];
let j = {};
do {
j = await json_fetch(url + (j.cursor ? `&cursor=${j.cursor}` : ''));
for (let v of j.records) {
results.push(v.value);
}
} while (j.cursor && j.cursor != 'self');
return results;
}
blocks = {}, follows = new Set();
follow = await bsky_records('rya.nc', 'app.bsky.graph.follow');
for (let fid of follow) {
console.log('scanning blocks of', fid.subject, '@' + (await bsky_resolve_did(fid.subject)));
follows.add(fid.subject);
let block = await bsky_records(fid.subject, 'app.bsky.graph.block');
for (let bid of block) {
if (!(bid.subject in blocks)) {
blocks[bid.subject] = [];
}
blocks[bid.subject].push(fid.subject);
}
}
s = '';
for (let blocked of Object.keys(blocks)) {
let n = blocks[blocked].length;
if (n) {
let handle = (await bsky_resolve_did(blocked)) || 'unknown';
let name = (await bsky_profile(blocked)).displayName;
name = name ? JSON.stringify(name) : 'Unknown';
let line = `${n} ${blocked} @${handle} ${name} [`
for (let blocker of blocks[blocked]) {
line += ' @' + (await bsky_resolve_did(blocker));
}
s += line + ' ]\n';
console.log(line);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment