feat: X API Cost Crisis Alert Chrome extension MVP with cost calculator, 8 alternatives, and 12 passing tests

This commit is contained in:
Bun Bun
2026-06-20 06:23:33 +00:00
commit 7052227f69
25 changed files with 3050 additions and 0 deletions
+142
View File
@@ -0,0 +1,142 @@
export const xApiAlternatives = [
{
name: 'Nitter (community instances)',
website: 'https://nitter.net',
freeTier: 'Unlimited (self-hosted or public instances)',
paidTier: 'Self-hosting ~$5/mo VPS',
pricingUrl: 'https://github.com/zedeus/nitter',
description: 'Privacy-friendly Twitter/X front-end that scrapes public profiles and tweets without API keys.',
features: ['No API key required', 'RSS feeds for any user', 'Read-only', 'Self-hostable'],
bestFor: 'Read-only use cases, RSS feeds, monitoring public accounts',
xApiReplacement: 'GET statuses/user_timeline, GET search/tweets'
},
{
name: 'BirdsiteLive (Mastodon bridge)',
website: 'https://github.com/NicolasConstant/BirdsiteLive',
freeTier: 'Self-hosted',
paidTier: 'VPS ~$5-10/mo',
pricingUrl: 'https://github.com/NicolasConstant/BirdsiteLive',
description: 'Bridge that lets you follow Twitter/X accounts from Mastodon. No API billing.',
features: ['Follow X accounts from Mastodon', 'No X API key', 'ActivityPub federation', 'Self-hostable'],
bestFor: 'Social media monitoring via Mastodon ecosystem',
xApiReplacement: 'GET followers/ids, GET friends/ids'
},
{
name: 'RSSHub',
website: 'https://rsshub.app',
freeTier: 'Public instance free, self-hosted free',
paidTier: 'Self-host ~$5/mo or donate',
pricingUrl: 'https://docs.rsshub.app/',
description: 'Open-source RSS feed generator that supports Twitter/X timelines without API.',
features: ['RSS feeds for tweets', 'No API key needed', '300+ sites supported', 'Self-hostable'],
bestFor: 'RSS-based monitoring, newsletters, automation pipelines',
xApiReplacement: 'GET statuses/user_timeline'
},
{
name: 'Wayback Machine / Archive.org',
website: 'https://archive.org',
freeTier: 'Unlimited reads',
paidTier: 'Free',
pricingUrl: 'https://archive.org/donate/',
description: 'Archived snapshots of public Twitter/X pages. Good for historical data.',
features: ['Historical tweet access', 'No rate limits', 'Free forever', 'Bulk export via CDX API'],
bestFor: 'Historical research, compliance, deleted tweet recovery',
xApiReplacement: 'Historical tweet lookup'
},
{
name: 'TweetScraper (开源 Python)',
website: 'https://github.com/twintproject/twint',
freeTier: 'Unlimited (no API)',
paidTier: 'Free (just your machine)',
pricingUrl: 'https://github.com/twintproject/twint',
description: 'Python library that scrapes tweets using Twitter\'s internal guest endpoints.',
features: ['No API key', 'Unlimited scraping', 'No rate limits', 'JSON/CSV export'],
bestFor: 'Data science, research, bulk exports',
xApiReplacement: 'GET search/tweets, GET statuses/user_timeline'
},
{
name: 'Apify Twitter Scraper',
website: 'https://apify.com/quacker/twitter-scraper',
freeTier: '5$/mo platform credit',
paidTier: '~$49/mo for 100K tweets',
pricingUrl: 'https://apify.com/pricing',
description: 'Managed cloud scraping with proxy rotation. Pays per compute, not per API call.',
features: ['Proxy rotation', 'Structured JSON output', 'Scheduled runs', 'No API rate limits'],
bestFor: 'Production pipelines needing reliable extraction without X API billing',
xApiReplacement: 'Full read/write replacement via scraping'
},
{
name: 'ScrapingBee',
website: 'https://www.scrapingbee.com',
freeTier: '1,000 API credits',
paidTier: 'From $49/mo (150K credits)',
pricingUrl: 'https://www.scrapingbee.com/pricing/',
description: 'Web scraping API with proxy rotation. Extract Twitter/X public pages via URL.',
features: ['JavaScript rendering', 'Proxy rotation', 'No X API key', 'Generic web scraper'],
bestFor: 'Generic web scraping including Twitter/X public pages',
xApiReplacement: 'GET any public Twitter page'
},
{
name: 'Mastodon API (switch platform)',
website: 'https://docs.joinmastodon.org/api/',
freeTier: 'Unlimited on most instances',
paidTier: 'Free (most instances) or ~$5/mo hosting',
pricingUrl: 'https://joinmastodon.org/servers',
description: 'Federated Twitter alternative with fully open, free API. No pay-per-use.',
features: ['REST + Streaming API', 'No rate limits on most instances', 'OAuth 2.0', 'Free forever'],
bestFor: 'Building social tools without platform risk or billing surprises',
xApiReplacement: 'Full Twitter API replacement (different platform)'
}
];
export const xApiTiers = {
free: {
name: 'Free',
readLimit: 1500,
writeLimit: 0,
monthlyCost: 0
},
basic: {
name: 'Basic',
readLimit: 10000,
writeLimit: 50000,
monthlyCost: 100
},
pro: {
name: 'Pro',
readLimit: 1000000,
writeLimit: 300000,
monthlyCost: 5000
},
enterprise: {
name: 'Enterprise',
readLimit: 20000000,
writeLimit: 10000000,
monthlyCost: 42000
}
};
export function calculateXCost(reads, writes) {
const tiers = [
{ name: 'Free', maxReads: 1500, maxWrites: 0, cost: 0 },
{ name: 'Basic', maxReads: 10000, maxWrites: 50000, cost: 100 },
{ name: 'Pro', maxReads: 1000000, maxWrites: 300000, cost: 5000 },
{ name: 'Enterprise', maxReads: 20000000, maxWrites: 10000000, cost: 42000 },
];
for (const tier of tiers) {
if (reads <= tier.maxReads && writes <= tier.maxWrites) {
return { tier: tier.name, cost: tier.cost, overage: false };
}
}
return { tier: 'Enterprise+', cost: 42000 + Math.ceil((reads - 20000000) / 1000000) * 10000, overage: true };
}
export function getAlternativesForUseCase(useCase) {
const map = {
'rss': ['RSSHub', 'Nitter (community instances)'],
'scraping': ['TweetScraper (开源 Python)', 'Apify Twitter Scraper', 'ScrapingBee'],
'monitoring': ['Nitter (community instances)', 'RSSHub', 'BirdsiteLive (Mastodon bridge)'],
'historical': ['Wayback Machine / Archive.org'],
'social-bot': ['Mastodon API (switch platform)', 'BirdsiteLive (Mastodon bridge)'],
'default': ['Nitter (community instances)', 'RSSHub', 'TweetScraper (开源 Python)']
};
const names = map[useCase] || map['default'];
return xApiAlternatives.filter(a => names.includes(a.name));
}