# antisocial Reads social posts back to you without the app. Links to X, Threads, Instagram, TikTok and Bluesky get shared constantly, and opening one means an app interstitial, a login wall, a feed you didn't ask for, and a pile of tracking. antisocial is the other half of a StopTheMadness rewrite rule: the link gets redirected here, and you get the post — the media and the words — plus a badge saying where it came from and a button to copy the original URL if you do want to go there. Single user, no authentication, tailnet only. It resolves posts by driving a real headless browser from a residential IP, logged out, exactly as if you'd opened the link yourself. Served at from Kallone. Deployment manifests live in the `infra` repo under `k8s/kallone/antisocial.unsupervised.studio/`. ## StopTheMadness rules One redirect rule per platform. The host is swapped for antisocial plus a short platform segment; the rest of the path is left alone, so the original is always recoverable and readable in your history. | Platform | Find | Replace | | --- | --- | --- | | X | `^https://(?:www\.\|mobile\.)?(?:x\|twitter)\.com/(.*)$` | `https://antisocial.unsupervised.studio/x/$1` | | Threads | `^https://(?:www\.)?threads\.(?:net\|com)/(.*)$` | `https://antisocial.unsupervised.studio/threads/$1` | | Instagram | `^https://(?:www\.)?instagram\.com/(.*)$` | `https://antisocial.unsupervised.studio/ig/$1` | | TikTok | `^https://(?:www\.\|vm\.\|vt\.)?tiktok\.com/(.*)$` | `https://antisocial.unsupervised.studio/tiktok/$1` | | Bluesky | `^https://bsky\.app/(.*)$` | `https://antisocial.unsupervised.studio/bsky/$1` | So `https://x.com/user/status/123` becomes `https://antisocial.unsupervised.studio/x/user/status/123`. Tracking parameters (`igsh`, `utm_*`, `s`, `t`, and friends) are stripped on arrival, so the URL the copy button gives back is the clean one. TikTok `vm.`/`vt.` share codes lose their subdomain in the rewrite; a single opaque path segment is recognised as a share code and rebuilt as `vm.tiktok.com//`. `/` serves this table with the live hostnames, if you'd rather read it there. ## How it works Every request drives a real Chromium page load. One code path, and it survives markup changes better than parsing HTML from the outside would. Each adapter layers its extraction, most structured first: 1. **The platform's own API response**, caught as it goes past during the page load. Reading the JSON a platform serves its own front end beats scraping what it renders. 2. **An inline payload** in the page — a JSON script tag, or an object buried in a bootstrap call (`src/platforms/scan.ts` pulls a balanced object out by key, including when it arrives escaped inside a JS string, which is what Instagram does). 3. **The rendered DOM** — whatever is actually on screen is real. 4. **Open Graph tags** — the floor, and enough to show something. | Platform | Loads | Reads | | --- | --- | --- | | Bluesky | the public AT Protocol API | `getPostThread`; falls back to the post page | | X | `platform.twitter.com` embed | the `cdn.syndication.twimg.com/tweet-result` response | | Instagram | `/embed/captioned/` | `shortcode_media`, then the rendered `