A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/feed-generator 65 lines 1.7 kB view raw
1import type { Agent } from "@atproto/api"; 2import chalk from "chalk"; 3import { ctx } from "context"; 4import { createAgent } from "lib/agent"; 5import * as FeedGenerator from "lexicon/types/app/rocksky/feed/generator"; 6import tables from "schema"; 7import type { InsertFeed } from "schema/feeds"; 8import { eq } from "drizzle-orm"; 9 10const args = process.argv.slice(2); 11 12if (args.length === 0) { 13 console.error("Please provide user author identifier (handle or DID)."); 14 console.log(`Usage: ${chalk.cyan("npm run seed:feed -- <handle|did>")}`); 15 process.exit(1); 16} 17 18async function getFeeds(agent: Agent, limit: number = 100) { 19 const res = await agent.com.atproto.repo.listRecords({ 20 repo: agent.assertDid, 21 collection: "app.rocksky.feed.generator", 22 limit, 23 }); 24 return res.data.records.map((record) => ({ 25 ...record, 26 value: FeedGenerator.isRecord(record.value) ? record.value : null, 27 })); 28} 29 30let userDid = args[0]; 31 32if (!userDid.startsWith("did:plc:")) { 33 userDid = await ctx.baseIdResolver.handle.resolve(userDid); 34} 35 36const agent = await createAgent(ctx.oauthClient, userDid); 37 38const [user] = await ctx.db 39 .select() 40 .from(tables.users) 41 .where(eq(tables.users.did, agent.assertDid)) 42 .execute(); 43 44const feeds = await getFeeds(agent); 45 46for (const feed of feeds) { 47 if (!feed.value) continue; 48 49 await ctx.db 50 .insert(tables.feeds) 51 .values({ 52 displayName: feed.value.displayName, 53 description: feed.value.description, 54 did: feed.value.did, 55 userId: user.id, 56 uri: feed.uri, 57 } satisfies InsertFeed) 58 .onConflictDoNothing() 59 .execute(); 60 console.log( 61 `Feed ${chalk.cyanBright(feed.value.displayName)} seeded successfully.`, 62 ); 63} 64 65process.exit(0);