Last active
December 6, 2025 08:55
-
-
Save mary-ext/ef8d6bb0113f7acc933752e265a759a8 to your computer and use it in GitHub Desktop.
custom scriptlet for removing Bluesky's annoyances
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| bsky.app##+js(user-bsky-annoyances.js) | |
| main.bsky.dev##+js(user-bsky-annoyances.js) | |
| ||go.bsky.app/redirect$urlskip=?u |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const _fetch = globalThis.fetch; | |
| globalThis.fetch = async function (req, init) { | |
| if (req instanceof Request) { | |
| const url = new URL(req.url); | |
| switch (url.pathname) { | |
| // remove trending topics | |
| case '/xrpc/app.bsky.unspecced.getConfig': { | |
| const res = await _fetch.call(this, req); | |
| if (res.status !== 200) { | |
| return res; | |
| } | |
| const data = await res.json(); | |
| return Response.json({ ...data, topicsEnabled: false }); | |
| } | |
| case '/xrpc/app.bsky.unspecced.getTrendingTopics': { | |
| return Response.json({ suggested: [], topics: [] }); | |
| } | |
| case '/xrpc/app.bsky.unspecced.getTrends': { | |
| return Response.json({ trends: [] }); | |
| } | |
| // remove follow suggestions | |
| case '/xrpc/app.bsky.actor.getSuggestions': { | |
| return Response.json({ actors: [] }); | |
| } | |
| // remove suggestions from explore page | |
| case '/xrpc/app.bsky.unspecced.getSuggestedFeeds': { | |
| break; | |
| return Response.json({ feeds: [] }); | |
| } | |
| case '/xrpc/app.bsky.unspecced.getSuggestedUsers': { | |
| return Response.json({ actors: [] }); | |
| } | |
| case '/xrpc/app.bsky.unspecced.getSuggestedStarterPacks': { | |
| return Response.json({ starterPacks: [] }); | |
| } | |
| // remove feed interaction tracking | |
| case '/xrpc/app.bsky.feed.sendInteractions': { | |
| const data = await req.json(); | |
| data.interactions = data.interactions.filter((evt) => { | |
| switch (evt.event) { | |
| // requestLess and requestMore is a user-explicit action | |
| case 'app.bsky.feed.defs#requestLess': | |
| case 'app.bsky.feed.defs#requestMore': | |
| return true; | |
| } | |
| return false; | |
| }); | |
| // nothing to send, don't bother contacting | |
| if (data.interactions.length === 0) { | |
| return Response.json({}); | |
| } | |
| req = new Request(req, { body: JSON.stringify(data) }); | |
| return _fetch.call(this, req); | |
| } | |
| // mock age assurance (old) | |
| case '/xrpc/app.bsky.unspecced.getAgeAssuranceState': { | |
| return Response.json({ | |
| lastInitiatedAt: '2025-07-14T14:22:43.912Z', | |
| status: 'assured', | |
| }); | |
| } | |
| // mock age assurance (new) | |
| case '/xrpc/app.bsky.ageassurance.getConfig': { | |
| return Response.json({ | |
| regions: [], | |
| }); | |
| } | |
| case '/xrpc/app.bsky.ageassurance.getState': { | |
| return Response.json({ | |
| state: { | |
| lastInitiatedAt: '2025-07-14T14:22:43.912Z', | |
| status: 'assured', | |
| access: 'full', | |
| }, | |
| stateMetadata: { | |
| accountCreatedAt: '1970-01-01T00:00:00.000Z', | |
| }, | |
| }); | |
| } | |
| } | |
| } else if (typeof req === 'string') { | |
| if (req === 'https://ip.bsky.app/config') { | |
| // old | |
| return Response.json({ | |
| countryCode: 'US', | |
| regionCode: 'WA', | |
| ageBlockedGeos: [], | |
| ageRestrictedGeos: [], | |
| }); | |
| } else if (req === 'https://ip.bsky.app/geolocation') { | |
| // new | |
| return Response.json({ | |
| countryCode: 'US', | |
| regionCode: 'WA', | |
| }); | |
| } else if (req.startsWith('https://events.bsky.app/') || req.startsWith('https://statsigapi.net/')) { | |
| throw new TypeError(`Failed to fetch`); | |
| } | |
| } | |
| return _fetch.call(this, req, init); | |
| }; | |
| const _open = XMLHttpRequest.prototype.open; | |
| XMLHttpRequest.prototype.open = function (method, urlString, isAsync, user, password) { | |
| // remove video session tracking | |
| if (!urlString.endsWith('/playlist.m3u8')) { | |
| // `video.bsky.app` is a middleware that adds session tracking, | |
| // the actual files lives on `video.cdn.bsky.app` | |
| urlString = urlString.replace('://video.bsky.app/watch/', '://video.cdn.bsky.app/hls/'); | |
| } | |
| const url = new URL(urlString); | |
| // remove `session_id` everywhere | |
| url.searchParams.delete('session_id'); | |
| return _open.call(this, method, url.toString(), isAsync, user, password); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment