import path from "node:path"; import dotenv from "dotenv"; import { AtpAgent, BlobRef, AppBskyFeedDefs } from "@atproto/api"; import fs from "fs/promises"; import { ids } from "@my/lexicon/server/lexicons"; const myFeeds = [ { recordName: "heb-ppl", displayName: "דוברי עברית", description: 'פוסטים שנכתבו ע"י דוברי עברית', avatar: path.join(__dirname, "avatars", "hep-ppl.png"), }, { recordName: "heb-ppl-all", displayName: "דוברי עברית + תגובות", description: 'פוסטים ותגובות שנכתבו ע"י דוברי עברית', avatar: path.join(__dirname, "avatars", "hep-ppl-all.png"), }, ]; const descSuffix = [ "", "הקוד של הפיד נמצא ב", "https://tangled.sh/@drornir.dev/atprotocol-apps", ].join("\n"); const run = async () => { dotenv.config(); const conf = { handle: "@drornir.dev", password: process.env.BLUESKY_PASSWORD, service: "https://bsky.social", }; if (!conf.password) { throw new Error("Please provide a password in BLUESKY_PASSWORD"); } if (!process.env.FEEDGEN_SERVICE_DID && !process.env.FEEDGEN_HOSTNAME) { throw new Error("Please provide a hostname FEEDGEN_HOSTNAME"); } const feedGenDid = process.env.FEEDGEN_SERVICE_DID ?? `did:web:${process.env.FEEDGEN_HOSTNAME}`; // only update this if in a test environment const agent = new AtpAgent({ service: conf.service, }); await agent.login({ identifier: conf.handle, password: conf.password }); for (const feed of myFeeds) { let avatarRef: BlobRef | undefined; if (feed.avatar) { let encoding: string; if (feed.avatar.endsWith("png")) { encoding = "image/png"; } else if (feed.avatar.endsWith("jpg") || feed.avatar.endsWith("jpeg")) { encoding = "image/jpeg"; } else { throw new Error("expected png or jpeg"); } const img = await fs.readFile(feed.avatar); const blobRes = await agent.com.atproto.repo.uploadBlob(img, { encoding, }); avatarRef = blobRes.data.blob; } console.log(`Publishing feed ${feed.recordName}...`); await agent.com.atproto.repo.putRecord({ repo: agent.session?.did ?? "", collection: ids.AppBskyFeedGenerator, rkey: feed.recordName, validate: true, record: { did: feedGenDid, displayName: feed.displayName, description: feed.description + descSuffix, avatar: avatarRef, createdAt: new Date().toISOString(), contentMode: AppBskyFeedDefs.CONTENTMODEUNSPECIFIED, }, }); } console.log("All done 🎉"); }; run();