Saved in this browser. Move them to another device or host on the Sync tab.
Optional. One raw Worker URL per line — Tweee adds ?id= automatically. The same Worker also unblocks media downloads.
Create a bot with @BotFather, then press the Telegram button in the toolbar. If api.telegram.org is blocked in your region, set a Telegram-only proxy Worker above.
Carry your proxies & preferences to another browser/device, or share them.
On a static host (GitHub Pages/Netlify) you can also drop a config.json next to the app to preload these for every visitor — see the README.
Browsers can't read Twitter's syndication endpoint directly (no CORS headers). A tiny Cloudflare Worker fetches it server-side and adds them. The free plan covers 100,000 requests/day.
tweee-proxy) and click Deploy.*.workers.dev URL and paste the raw URL into the Proxy field — Tweee appends ?id= for you.Must be a Module Worker (export default) — the default for new Workers. Links: workers.cloudflare.com.
If api.telegram.org is blocked in your region, this tiny Cloudflare Worker forwards Bot API calls (like sending your exported HTML) through Cloudflare instead. It only relays to Telegram — nothing else.
tweee-tg) and Deploy.*.workers.dev URL into the Telegram API proxy field. Tweee will call YOUR-WORKER/bot<token>/sendDocument instead of api.telegram.org.Your bot token passes through this Worker — only deploy it to your own Cloudflare account.
export default {
async fetch(request) {
const CORS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,OPTIONS",
"Access-Control-Allow-Headers": "*",
"Access-Control-Expose-Headers": "*",
"Access-Control-Max-Age": "86400",
};
if (request.method === "OPTIONS") return new Response(null, { headers: CORS });
const json = (obj, status = 200) =>
new Response(JSON.stringify(obj), {
status,
headers: { ...CORS, "Content-Type": "application/json; charset=utf-8" },
});
try {
const params = new URL(request.url).searchParams;
// Media passthrough: ?url= — unblocks downloads + progress bar.
const media = params.get("url") || "";
if (media) {
let host;
try { host = new URL(media).hostname; } catch { return json({ error: "bad url" }, 400); }
if (!/(^|\.)twimg\.com$/i.test(host)) return json({ error: "host not allowed" }, 403);
const m = await fetch(media, { headers: { "User-Agent": "Mozilla/5.0", "Referer": "https://twitter.com/" } });
const h = new Headers(m.headers);
for (const [k, v] of Object.entries(CORS)) h.set(k, v);
const dl = (params.get("dl") || "").replace(/[^\w.\-]/g, "_");
if (dl) h.set("Content-Disposition", 'attachment; filename="' + dl + '"'); // force a real download (mobile/iOS)
return new Response(m.body, { status: m.status, headers: h });
}
// Tweet/article passthrough: ?id=
const id = params.get("id") || "";
if (!/^\d+$/.test(id)) return json({ error: "missing or invalid id/url" }, 400);
const token = ((Number(id) / 1e15) * Math.PI).toString(36).replace(/(0+|\.)/g, "");
const upstream = `https://cdn.syndication.twimg.com/tweet-result?id=${id}&token=${token}&lang=en`;
const r = await fetch(upstream, {
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "application/json",
"Referer": "https://platform.twitter.com/",
},
});
const body = await r.text();
return new Response(body, {
status: r.status,
headers: { ...CORS, "Content-Type": "application/json; charset=utf-8", "Cache-Control": "public, max-age=300" },
});
} catch (err) {
return json({ error: "proxy_failed", detail: String((err && err.message) || err) }, 502);
}
},
};
export default {
async fetch(request) {
const url = new URL(request.url);
// Forward /bot<token>/<method> straight to Telegram, preserving method, body and query.
const upstream = "https://api.telegram.org" + url.pathname + url.search;
const init = { method: request.method, headers: request.headers };
if (request.method !== "GET" && request.method !== "HEAD") init.body = request.body;
const r = await fetch(upstream, init);
const h = new Headers(r.headers);
h.set("Access-Control-Allow-Origin", "*");
h.set("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
h.set("Access-Control-Allow-Headers", "*");
return new Response(r.body, { status: r.status, headers: h });
},
};