Twitter Communities are the most underrated feature on the platform.
500,000+ people in the "Indie Hackers" community. 200,000+ in "Tech Twitter." Thousands of niche communities with your exact target audienceβall in one place.
But there's no good way to monitor them.
Until now.
In this tutorial, we'll build a Twitter Community Tracker that:
- Scrapes posts from any Twitter Community
- Identifies trending topics and influential members
- Helps you find the perfect time to engage
Why Communities Matter
Twitter's algorithm is brutal. Unless you have 50K+ followers, your tweets disappear into the void.
But Community posts? They get shown to every member of that community.
Post in the right community at the right time = guaranteed eyeballs from your target audience.
The Stack
- Node.js: Runtime
- SociaVault API: To scrape community data
- OpenAI API: For trend analysis (optional)
Step 1: Setup
mkdir twitter-community-tracker
cd twitter-community-tracker
npm init -y
npm install axios dotenv openai node-cron
Create .env:
SOCIAVAULT_API_KEY=your_sociavault_key
OPENAI_API_KEY=your_openai_key
Step 2: Fetch Community Info
First, let's get the basic info about a community.
Create index.js:
require('dotenv').config();
const axios = require('axios');
const OpenAI = require('openai');
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const SOCIAVAULT_BASE = 'https://api.sociavault.com';
async function getCommunityInfo(communityUrl) {
console.log('π₯ Fetching community info...');
try {
const response = await axios.get(`${SOCIAVAULT_BASE}/v1/scrape/twitter/community`, {
params: { url: communityUrl },
headers: { 'Authorization': `Bearer ${process.env.SOCIAVAULT_API_KEY}` }
});
return response.data.data;
} catch (error) {
console.error('Error fetching community:', error.message);
return null;
}
}
Step 3: Get Community Posts
Now the good stuffβlet's fetch recent posts from the community:
async function getCommunityTweets(communityUrl) {
console.log('π₯ Fetching community tweets...');
try {
const response = await axios.get(`${SOCIAVAULT_BASE}/v1/scrape/twitter/community/tweets`, {
params: { url: communityUrl },
headers: { 'Authorization': `Bearer ${process.env.SOCIAVAULT_API_KEY}` }
});
const tweets = response.data.data || [];
return tweets.map(t => ({
id: t.id || t.rest_id,
author: t.user?.screen_name || t.author_handle,
authorName: t.user?.name || t.author_name,
text: t.full_text || t.text,
likes: t.favorite_count || t.likes || 0,
retweets: t.retweet_count || t.retweets || 0,
replies: t.reply_count || t.replies || 0,
date: t.created_at
}));
} catch (error) {
console.error('Error fetching community tweets:', error.message);
return [];
}
}
Step 4: Analyze Community Patterns
Let's build functions to understand the community dynamics:
function analyzeEngagement(tweets) {
if (tweets.length === 0) return null;
// Sort by engagement
const byEngagement = [...tweets].sort((a, b) =>
(b.likes + b.retweets + b.replies) - (a.likes + a.retweets + a.replies)
);
// Calculate averages
const totalEngagement = tweets.reduce((sum, t) =>
sum + t.likes + t.retweets + t.replies, 0
);
const avgEngagement = totalEngagement / tweets.length;
// Find top posters
const posterCounts = {};
tweets.forEach(t => {
posterCounts[t.author] = (posterCounts[t.author] || 0) + 1;
});
const topPosters = Object.entries(posterCounts)
.sort((a, b) => b[1] - a[1])
.slice(0, 10)
.map(([author, count]) => ({ author, posts: count }));
// Find top engaged posts
const topPosts = byEngagement.slice(0, 5).map(t => ({
author: t.author,
text: t.text.substring(0, 100) + '...',
engagement: t.likes + t.retweets + t.replies
}));
return {
totalPosts: tweets.length,
avgEngagement: avgEngagement.toFixed(1),
topPosters,
topPosts
};
}
Step 5: Identify Content Themes
Use AI to understand what performs well in the community:
async function analyzeContentThemes(tweets) {
console.log('π€ Analyzing content themes...');
// Get top performing tweets for analysis
const topTweets = [...tweets]
.sort((a, b) => (b.likes + b.retweets) - (a.likes + a.retweets))
.slice(0, 30);
const prompt = `
Analyze these top-performing tweets from a Twitter Community.
Return JSON with:
{
"themes": [top 5 content themes that get engagement],
"formats": [top 3 post formats that work (threads, questions, hot takes, etc.)],
"bestPractices": [5 specific tips for posting in this community],
"contentIdeas": [5 specific post ideas that would likely perform well],
"avoid": [3 things to avoid based on what doesn't get engagement]
}
Tweets:
${JSON.stringify(topTweets.map(t => ({ text: t.text, engagement: t.likes + t.retweets })))}
`;
const completion = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: prompt }],
response_format: { type: 'json_object' }
});
return JSON.parse(completion.choices[0].message.content);
}
Step 6: Find Your People
Identify community members who engage with content like yours:
async function findRelevantMembers(tweets, yourKeywords) {
console.log('π Finding relevant community members...');
const relevantTweets = tweets.filter(t => {
const text = t.text.toLowerCase();
return yourKeywords.some(kw => text.includes(kw.toLowerCase()));
});
// Extract unique authors who post about your topics
const relevantAuthors = {};
relevantTweets.forEach(t => {
if (!relevantAuthors[t.author]) {
relevantAuthors[t.author] = {
author: t.author,
authorName: t.authorName,
relevantPosts: 0,
totalEngagement: 0
};
}
relevantAuthors[t.author].relevantPosts++;
relevantAuthors[t.author].totalEngagement += t.likes + t.retweets;
});
return Object.values(relevantAuthors)
.sort((a, b) => b.totalEngagement - a.totalEngagement)
.slice(0, 20);
}
Step 7: The Full Analysis
async function trackCommunity(communityUrl, keywords = []) {
console.log('\nπ¦ Twitter Community Tracker\n');
console.log('βββββββββββββββββββββββββββββββββββββββ\n');
// 1. Get community info
const community = await getCommunityInfo(communityUrl);
if (community) {
console.log(`π ${community.name}`);
console.log(`π₯ ${Number(community.member_count || 0).toLocaleString()} members`);
console.log(`π ${community.description?.substring(0, 100) || 'No description'}...\n`);
}
// 2. Get recent tweets
const tweets = await getCommunityTweets(communityUrl);
if (tweets.length === 0) {
console.log('No tweets found.');
return;
}
console.log(`β
Fetched ${tweets.length} recent posts\n`);
// 3. Analyze engagement patterns
const engagement = analyzeEngagement(tweets);
console.log('βββββββββββββββββββββββββββββββββββββββ');
console.log('π ENGAGEMENT ANALYSIS');
console.log('βββββββββββββββββββββββββββββββββββββββ\n');
console.log(`π Avg engagement per post: ${engagement.avgEngagement}`);
console.log('\nπ Most Active Posters:');
engagement.topPosters.slice(0, 5).forEach((p, i) => {
console.log(` ${i + 1}. @${p.author} (${p.posts} posts)`);
});
console.log('\nπ₯ Top Performing Posts:');
engagement.topPosts.forEach((p, i) => {
console.log(` ${i + 1}. @${p.author} - ${p.engagement} engagements`);
console.log(` "${p.text}"`);
});
// 4. AI Content Analysis
const themes = await analyzeContentThemes(tweets);
console.log('\nβββββββββββββββββββββββββββββββββββββββ');
console.log('π― CONTENT STRATEGY');
console.log('βββββββββββββββββββββββββββββββββββββββ\n');
console.log('π Top Themes:');
themes.themes.forEach((t, i) => console.log(` ${i + 1}. ${t}`));
console.log('\n⨠Winning Formats:');
themes.formats.forEach((f, i) => console.log(` ${i + 1}. ${f}`));
console.log('\nπ‘ Content Ideas for You:');
themes.contentIdeas.forEach((idea, i) => console.log(` ${i + 1}. ${idea}`));
console.log('\nβ οΈ What to Avoid:');
themes.avoid.forEach((a, i) => console.log(` ${i + 1}. ${a}`));
// 5. Find relevant members (if keywords provided)
if (keywords.length > 0) {
const members = await findRelevantMembers(tweets, keywords);
console.log('\nβββββββββββββββββββββββββββββββββββββββ');
console.log(`π― MEMBERS TALKING ABOUT: ${keywords.join(', ')}`);
console.log('βββββββββββββββββββββββββββββββββββββββ\n');
members.forEach((m, i) => {
console.log(` ${i + 1}. @${m.author}`);
console.log(` ${m.relevantPosts} relevant posts, ${m.totalEngagement} total engagement`);
});
}
return { community, tweets, engagement, themes };
}
Step 8: Run It
async function main() {
// Replace with your target community
const communityUrl = 'https://twitter.com/i/communities/1234567890';
// Keywords related to your product/niche
const myKeywords = ['API', 'scraping', 'data', 'automation'];
await trackCommunity(communityUrl, myKeywords);
}
main();
Sample Output
π¦ Twitter Community Tracker
βββββββββββββββββββββββββββββββββββββββ
π Indie Hackers
π₯ 523,847 members
π A community for indie hackers building profitable online businesses...
β
Fetched 48 recent posts
βββββββββββββββββββββββββββββββββββββββ
π ENGAGEMENT ANALYSIS
βββββββββββββββββββββββββββββββββββββββ
π Avg engagement per post: 47.3
π Most Active Posters:
1. @levelsio (12 posts)
2. @marc_louvion (8 posts)
3. @tdinh_me (6 posts)
4. @dannypostmaa (5 posts)
5. @arlogilbert (4 posts)
π₯ Top Performing Posts:
1. @levelsio - 847 engagements
"Just crossed $100K MRR with a single product. No employees. No fund..."
2. @marc_louvion - 523 engagements
"The best marketing strategy in 2024: Build in public. Here's why..."
βββββββββββββββββββββββββββββββββββββββ
π― CONTENT STRATEGY
βββββββββββββββββββββββββββββββββββββββ
π Top Themes:
1. Revenue milestones and financial transparency
2. Product launch announcements
3. Build-in-public updates
4. Lessons learned from failures
5. Tech stack discussions
β¨ Winning Formats:
1. Personal stories with specific numbers
2. Thread breakdowns of strategies
3. Hot takes that challenge conventional wisdom
π‘ Content Ideas for You:
1. "I built X in Y days - here's my exact tech stack"
2. "The real cost breakdown of running my SaaS"
3. "Why I stopped doing [popular thing] and what I do instead"
4. "Unpopular opinion: [controversial take about building products]"
5. "My first $X from [product] - lessons learned"
β οΈ What to Avoid:
1. Promotional posts without value
2. Generic advice without personal experience
3. Asking for help without showing what you've tried
Multi-Community Monitoring
Track multiple communities at once:
const cron = require('node-cron');
const COMMUNITIES = [
{ url: 'https://twitter.com/i/communities/123', name: 'Indie Hackers' },
{ url: 'https://twitter.com/i/communities/456', name: 'Tech Twitter' },
{ url: 'https://twitter.com/i/communities/789', name: 'SaaS Builders' }
];
// Check hourly for new opportunities
cron.schedule('0 * * * *', async () => {
for (const community of COMMUNITIES) {
console.log(`\nChecking ${community.name}...`);
const tweets = await getCommunityTweets(community.url);
// Find posts you should reply to
const relevantPosts = tweets.filter(t => {
const text = t.text.toLowerCase();
return (
text.includes('api') ||
text.includes('scraping') ||
text.includes('recommend')
);
});
if (relevantPosts.length > 0) {
console.log(`Found ${relevantPosts.length} relevant posts to engage with!`);
// Send notification, add to queue, etc.
}
}
});
Why This Matters
Twitter Communities are:
- Curated audiences (everyone opted-in to the topic)
- Higher engagement (posts shown to all members)
- Less noise (no algorithm dilution)
Most people don't even know they exist. The ones who do are too lazy to monitor them properly.
Now you have an unfair advantage.
Get Started
- Get your SociaVault API Key
- Find communities in your niche
- Start tracking what works
- Post when you have something valuable to add
Stop shouting into the void. Start engaging where your audience already is.
Top comments (0)