import shuffle from "knuth-shuffle-seeded"; import {readFileSync} from "node:fs"; import {createServer} from "node:http"; var feed = readFileSync("posts.txt", "utf8"); feed = feed.trim().split("\n"); feed = feed.filter(x=>x); // idk how blank lines are getting in it feed = shuffle(feed); console.log(`${feed.length.toLocaleString()} posts`); var timeout; var server = createServer(function(req, res){ if (req.url == "/.well-known/did.json") { res.writeHead(200, { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }); res.end(`{"@context":["https://www.w3.org/ns/did/v1"],"id":"did:web:${req.headers.host}","service":[{"id":"#bsky_fg","type":"BskyFeedGenerator","serviceEndpoint":"https://${req.headers.host}"}]}`); return; } if (req.method != "GET" || !req.url.startsWith("/xrpc/app.bsky.feed.getFeedSkeleton")) { res.writeHead(404); res.end(); return; } if (!timeout) { timeout = setTimeout(() => { feed = shuffle(feed); timeout = undefined; }, 1000*60*60); } var i = req.url.indexOf("?"); if (i > -1) { var params = new URLSearchParams(req.url.substring(i+1)); var cursor = params.get("cursor"); var limit = params.get("limit"); if (limit) { limit = Number(limit); if (limit < 1) limit = 1; //else if (limit > 100) limit = 100; } } var index = cursor ? Number(cursor) : 0; var subfeed = feed.slice(index, index + (limit || 50)); var response = { feed: subfeed.map(url => ({post: url})), cursor: String(index + subfeed.length) }; response = JSON.stringify(response); res.writeHead(200, { "Content-Type":"application/json", "Content-Length": response.length }); res.end(response); }); server.listen(2381);