Skip to content

Instantly share code, notes, and snippets.

@zachmargolis
Last active April 6, 2025 00:58
Show Gist options
  • Save zachmargolis/07b246ed0beb0878bf9e56dc76da5c9f to your computer and use it in GitHub Desktop.
Save zachmargolis/07b246ed0beb0878bf9e56dc76da5c9f to your computer and use it in GitHub Desktop.
Quick-n-dirty posts export as CSV from BlueSky repo.car files. Just exports text and timestamp
import { CarIndexedReader } from "@ipld/car";
import { decode } from "cbor2";
import { stringify as csvStringify } from 'csv-stringify/sync';
interface Subject {
cid: string;
uri: string;
}
interface EmbedImages {
$type: 'app.bsky.embed.images';
images: object[];
}
interface EmbedRecordWithMedia {
$type: 'app.bsky.embed.recordWithMedia';
}
type Embed = EmbedImages | EmbedRecordWithMedia;
interface Like {
$type:'app.bsky.feed.like';
subject: Subject;
createdAt: string;
}
interface Post {
$type: 'app.bsky.feed.post';
text: string;
reply?: {
root: Subject
parent: Subject
}
langs?: string[];
embed?: Embed;
facets?: object[];
createdAt: string;
}
interface Follow {
$type: 'app.bsky.feed.follow';
subject: string;
createdAt: string;
}
interface Unknown {}
type Block = Like | Post | Follow | Unknown;
const [_node, scriptFile, path] = process.argv;
if (!path) {
console.error(`Usage: ${scriptFile} [path-to-repo.car]`);
process.exit(1);
}
const repo = await CarIndexedReader.fromFile(path);
const blocks = await repo.blocks();
process.stdout.write(csvStringify([['type', 'text', 'createdAt']]))
while (true) {
const block = await blocks.next();
if (block.done) {
break;
}
const payload = decode(block.value.bytes) as Block;
if ('$type' in payload && payload.$type === 'app.bsky.feed.post') {
process.stdout.write(csvStringify([[payload.$type, payload.text, payload.createdAt]]))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment