my monorepo for atproto based applications
at main 90 lines 2.7 kB view raw
1import path from "node:path"; 2import dotenv from "dotenv"; 3import { AtpAgent, BlobRef, AppBskyFeedDefs } from "@atproto/api"; 4import fs from "fs/promises"; 5import { ids } from "@my/lexicon/server/lexicons"; 6 7const myFeeds = [ 8 { 9 recordName: "heb-ppl", 10 displayName: "דוברי עברית", 11 description: 'פוסטים שנכתבו ע"י דוברי עברית', 12 avatar: path.join(__dirname, "avatars", "hep-ppl.png"), 13 }, 14 { 15 recordName: "heb-ppl-all", 16 displayName: "דוברי עברית + תגובות", 17 description: 'פוסטים ותגובות שנכתבו ע"י דוברי עברית', 18 avatar: path.join(__dirname, "avatars", "hep-ppl-all.png"), 19 }, 20]; 21 22const descSuffix = [ 23 "", 24 "הקוד של הפיד נמצא ב", 25 "https://tangled.sh/@drornir.dev/atprotocol-apps", 26].join("\n"); 27 28const run = async () => { 29 dotenv.config(); 30 31 const conf = { 32 handle: "@drornir.dev", 33 password: process.env.BLUESKY_PASSWORD, 34 service: "https://bsky.social", 35 }; 36 if (!conf.password) { 37 throw new Error("Please provide a password in BLUESKY_PASSWORD"); 38 } 39 40 if (!process.env.FEEDGEN_SERVICE_DID && !process.env.FEEDGEN_HOSTNAME) { 41 throw new Error("Please provide a hostname FEEDGEN_HOSTNAME"); 42 } 43 44 const feedGenDid = process.env.FEEDGEN_SERVICE_DID ?? `did:web:${process.env.FEEDGEN_HOSTNAME}`; 45 46 // only update this if in a test environment 47 const agent = new AtpAgent({ 48 service: conf.service, 49 }); 50 await agent.login({ identifier: conf.handle, password: conf.password }); 51 52 for (const feed of myFeeds) { 53 let avatarRef: BlobRef | undefined; 54 if (feed.avatar) { 55 let encoding: string; 56 if (feed.avatar.endsWith("png")) { 57 encoding = "image/png"; 58 } else if (feed.avatar.endsWith("jpg") || feed.avatar.endsWith("jpeg")) { 59 encoding = "image/jpeg"; 60 } else { 61 throw new Error("expected png or jpeg"); 62 } 63 const img = await fs.readFile(feed.avatar); 64 const blobRes = await agent.com.atproto.repo.uploadBlob(img, { 65 encoding, 66 }); 67 avatarRef = blobRes.data.blob; 68 } 69 70 console.log(`Publishing feed ${feed.recordName}...`); 71 72 await agent.com.atproto.repo.putRecord({ 73 repo: agent.session?.did ?? "", 74 collection: ids.AppBskyFeedGenerator, 75 rkey: feed.recordName, 76 validate: true, 77 record: { 78 did: feedGenDid, 79 displayName: feed.displayName, 80 description: feed.description + descSuffix, 81 avatar: avatarRef, 82 createdAt: new Date().toISOString(), 83 contentMode: AppBskyFeedDefs.CONTENTMODEUNSPECIFIED, 84 }, 85 }); 86 } 87 console.log("All done 🎉"); 88}; 89 90run();