Every day, your potential customers are complaining about your competitors on Reddit.
Every day, people are asking for product recommendations in your niche.
Every day, you're not there to help them.
In this tutorial, we'll build a Reddit Monitoring Bot that:
- Watches any subreddit for new posts
- Filters for keywords that matter to you
- Sends you instant alerts (Slack, Discord, emailβwhatever)
The Problem with Reddit's API
Reddit's API has become... complicated.
- New rate limits after the API pricing drama
- OAuth flows that make you want to cry
- Terms that change every few months
We're going to sidestep all of that with SociaVault's /v1/scrape/reddit/* endpoints.
The Stack
- Node.js: Runtime
- SociaVault API: To fetch subreddit posts and comments
- node-cron: To run on a schedule
- Your preferred notification service: Slack/Discord webhook
Step 1: Setup
mkdir reddit-monitor
cd reddit-monitor
npm init -y
npm install axios dotenv node-cron
Create your .env:
SOCIAVAULT_API_KEY=your_sociavault_key
SLACK_WEBHOOK_URL=your_slack_webhook
Step 2: Fetch Subreddit Posts
Let's start by building a function to get the latest posts from any subreddit.
Create index.js:
require('dotenv').config();
const axios = require('axios');
const cron = require('node-cron');
const SOCIAVAULT_BASE = 'https://api.sociavault.com';
async function getSubredditPosts(subreddit, sort = 'new') {
console.log(`π₯ Fetching /r/${subreddit}...`);
try {
const response = await axios.get(`${SOCIAVAULT_BASE}/v1/scrape/reddit/subreddit`, {
params: {
subreddit,
sort // 'new', 'hot', 'top', 'rising'
},
headers: { 'Authorization': `Bearer ${process.env.SOCIAVAULT_API_KEY}` }
});
return response.data.data || [];
} catch (error) {
console.error(`Error fetching /r/${subreddit}:`, error.message);
return [];
}
}
Step 3: Get Comments on Specific Posts
When you find an interesting post, you might want to dive into the comments:
async function getPostComments(postUrl) {
console.log(`π₯ Fetching comments...`);
try {
const response = await axios.get(`${SOCIAVAULT_BASE}/v1/scrape/reddit/post/comments`, {
params: { url: postUrl },
headers: { 'Authorization': `Bearer ${process.env.SOCIAVAULT_API_KEY}` }
});
return response.data.data || [];
} catch (error) {
console.error('Error fetching comments:', error.message);
return [];
}
}
Step 4: Search Reddit for Keywords
This is where it gets powerful. Search across all of Reddit for specific keywords:
async function searchReddit(query, limit = 25) {
console.log(`π Searching Reddit for "${query}"...`);
try {
const response = await axios.get(`${SOCIAVAULT_BASE}/v1/scrape/reddit/search`, {
params: { query, limit },
headers: { 'Authorization': `Bearer ${process.env.SOCIAVAULT_API_KEY}` }
});
return response.data.data || [];
} catch (error) {
console.error('Error searching Reddit:', error.message);
return [];
}
}
Step 5: The Keyword Filter
Now let's build the core monitoring logic:
// Keywords that indicate buying intent or competitor mentions
const KEYWORDS = {
buying: ['looking for', 'recommend', 'alternative to', 'best', 'what do you use'],
complaints: ['hate', 'terrible', 'awful', 'broken', 'switched from', 'leaving'],
competitors: ['competitor1', 'competitor2'] // Add your competitor names
};
function containsKeywords(text, keywordList) {
const lowerText = text.toLowerCase();
return keywordList.some(keyword => lowerText.includes(keyword.toLowerCase()));
}
function categorizePost(post) {
const text = `${post.title || ''} ${post.selftext || ''}`;
const categories = [];
if (containsKeywords(text, KEYWORDS.buying)) categories.push('π° Buying Intent');
if (containsKeywords(text, KEYWORDS.complaints)) categories.push('π€ Complaint');
if (containsKeywords(text, KEYWORDS.competitors)) categories.push('π― Competitor Mention');
return categories;
}
Step 6: Send Notifications
Let's send alerts to Slack when we find something interesting:
async function sendSlackNotification(message) {
if (!process.env.SLACK_WEBHOOK_URL) {
console.log('π’ [Would send to Slack]:', message.substring(0, 100) + '...');
return;
}
try {
await axios.post(process.env.SLACK_WEBHOOK_URL, {
text: message,
unfurl_links: false
});
} catch (error) {
console.error('Error sending Slack notification:', error.message);
}
}
function formatAlert(post, categories) {
return `
π¨ *New Reddit Alert*
${categories.join(' ')}
*Subreddit:* /r/${post.subreddit}
*Title:* ${post.title}
*Score:* β¬οΈ ${post.score} | π¬ ${post.num_comments} comments
π ${post.url || `https://reddit.com${post.permalink}`}
`.trim();
}
Step 7: The Monitor Function
Bringing it all together:
// Track posts we've already alerted on
const alertedPosts = new Set();
async function monitorSubreddits(subreddits) {
console.log(`\nβ° ${new Date().toISOString()} - Running monitor cycle\n`);
for (const subreddit of subreddits) {
const posts = await getSubredditPosts(subreddit);
console.log(`π Found ${posts.length} posts in /r/${subreddit}`);
for (const post of posts) {
// Skip if we've already alerted on this post
if (alertedPosts.has(post.id)) continue;
const categories = categorizePost(post);
if (categories.length > 0) {
console.log(`\nπ― Match found: "${post.title.substring(0, 50)}..."`);
console.log(` Categories: ${categories.join(', ')}`);
const alert = formatAlert(post, categories);
await sendSlackNotification(alert);
alertedPosts.add(post.id);
}
}
// Small delay between subreddits
await new Promise(resolve => setTimeout(resolve, 1000));
}
console.log(`\nβ
Monitor cycle complete. Tracked ${alertedPosts.size} posts.`);
}
Step 8: Run on Schedule
// Subreddits to monitor (customize these!)
const SUBREDDITS = [
'SaaS',
'startups',
'Entrepreneur',
'webdev',
'javascript'
];
// Run immediately on start
monitorSubreddits(SUBREDDITS);
// Then run every 15 minutes
cron.schedule('*/15 * * * *', () => {
monitorSubreddits(SUBREDDITS);
});
console.log('π€ Reddit Monitor Bot is running...');
console.log(`π‘ Monitoring: ${SUBREDDITS.map(s => '/r/' + s).join(', ')}`);
console.log('β° Checking every 15 minutes');
Step 9: Search-Based Monitoring (Alternative)
If you want to monitor specific keywords instead of subreddits:
async function keywordMonitor() {
const SEARCH_QUERIES = [
'best social media API',
'alternative to apify',
'scraping instagram',
'twitter api expensive'
];
for (const query of SEARCH_QUERIES) {
const posts = await searchReddit(query);
console.log(`\nπ "${query}" - ${posts.length} results`);
for (const post of posts.slice(0, 5)) {
if (alertedPosts.has(post.id)) continue;
const alert = `
π *Keyword Match: "${query}"*
*Subreddit:* /r/${post.subreddit}
*Title:* ${post.title}
*Score:* β¬οΈ ${post.score}
π https://reddit.com${post.permalink}
`.trim();
await sendSlackNotification(alert);
alertedPosts.add(post.id);
}
}
}
// Add to cron schedule
cron.schedule('0 * * * *', keywordMonitor); // Every hour
Sample Output
β° 2024-01-15T14:00:00.000Z - Running monitor cycle
π₯ Fetching /r/SaaS...
π Found 25 posts in /r/SaaS
π― Match found: "Looking for alternatives to Brandwatch for social lis..."
Categories: π° Buying Intent
π₯ Fetching /r/startups...
π Found 25 posts in /r/startups
π― Match found: "What do you use for social media analytics? Current t..."
Categories: π° Buying Intent, π€ Complaint
β
Monitor cycle complete. Tracked 2 posts.
Extending This
1. Add AI to Score Leads
const OpenAI = require('openai');
const openai = new OpenAI();
async function scorePost(post) {
const prompt = `
Rate this Reddit post from 1-10 on how likely this person is to buy a social media data API.
Title: ${post.title}
Content: ${post.selftext}
Return JSON: { "score": number, "reason": string }
`;
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: prompt }],
response_format: { type: 'json_object' }
});
return JSON.parse(response.choices[0].message.content);
}
2. Auto-Draft Replies (Use Carefully!)
async function draftReply(post) {
const prompt = `
Write a helpful Reddit comment for this post.
Be genuinely helpful, NOT salesy.
If our product (SociaVault - social media data API) is relevant, mention it briefly.
Post: ${post.title}
${post.selftext}
`;
// Generate a draft, but ALWAYS review before posting
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: prompt }]
});
return response.choices[0].message.content;
}
3. Store in Database for Analysis
// Track mentions over time, analyze trends, etc.
const sqlite3 = require('sqlite3');
const db = new sqlite3.Database('./reddit_mentions.db');
db.run(`
CREATE TABLE IF NOT EXISTS mentions (
id TEXT PRIMARY KEY,
subreddit TEXT,
title TEXT,
category TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
The ROI
A proper social listening tool costs:
- Brandwatch: $800+/month
- Mention: $41+/month
- Sprout Social: $249+/month
This setup costs:
- SociaVault: ~$5-20/month (usage-based)
- A $5 VPS to run it: Optional
That's $1,000+/year in savings, plus you own the code and can customize it however you want.
Next Steps
- Get your SociaVault API Key
- Set up a Slack webhook (or Discord, or email)
- Customize the keywords for your industry
- Deploy on a cheap VPS or use a cron service
Stop missing those Reddit conversations. Start monitoring today.
Top comments (0)