Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active August 6, 2023 08:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save intrnl/518c7f1a04e4ef6293ff3662b1b0112b to your computer and use it in GitHub Desktop.
Save intrnl/518c7f1a04e4ef6293ff3662b1b0112b to your computer and use it in GitHub Desktop.
script to delete all posts from a Bluesky account
import { Agent } from '@intrnl/bluesky-client/agent';
import type { UnionOf } from '@intrnl/bluesky-client/atp-schema';
import { pRateLimit } from 'p-ratelimit';
const agent = new Agent({ serviceUri: 'https://bsky.social' });
const limit = pRateLimit({ concurrency: 3, interval: 1000, rate: 5 });
const getRecordId = (uri: string) => {
const idx = uri.lastIndexOf('/');
return uri.slice(idx + 1);
};
const chunked = <T>(str: T[], size: number): T[][] => {
const chunks: T[][] = [];
for (let idx = 0, len = str.length; idx < len; idx += size) {
chunks.push(str.slice(idx, idx + size));
}
return chunks;
};
await agent.login({
identifier: 'invalid.handle',
password: '7aen-mxlf-rc56-o4yl',
});
console.log(`Logged in as ${agent.session!.handle} (${agent.session!.did})`);
let deletes: UnionOf<'com.atproto.repo.applyWrites#delete'>[] = [];
let cursor: string | undefined;
do {
const response = await limit(() =>
agent.rpc.get('com.atproto.repo.listRecords', {
params: {
repo: agent.session!.did,
collection: 'app.bsky.feed.post',
limit: 100,
cursor: cursor,
reverse: true,
},
}),
);
const data = response.data;
cursor = data.cursor;
deletes = deletes.concat(
data.records.map((record) => ({
$type: 'com.atproto.repo.applyWrites#delete',
collection: 'app.bsky.feed.post',
rkey: getRecordId(record.uri),
})),
);
} while (cursor != undefined);
const chunkedDeletes = chunked(deletes, 200);
console.log(`Retrieved ${deletes.length} posts to delete`);
console.log(`Deletion can be done in ${chunkedDeletes.length} batched operations`);
for (let idx = 0, len = chunkedDeletes.length; idx < len; idx++) {
const chunk = chunkedDeletes[idx];
await limit(() =>
agent.rpc.call('com.atproto.repo.applyWrites', {
data: {
repo: agent.session!.did,
writes: chunk,
},
}),
);
console.log(`Batch operation #${idx + 1} completed`);
}
console.log(`Done`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment