A .NET 9.0 cross-platform service that monitors multiple social media platforms for specific keywords and automatically publishes matches to configured destinations.
- Generic Source Interface: Monitor Reddit, Discord, Twitter, and more through a unified interface
- Generic Destination Interface: Publish to Discord, Email, Slack, webhooks, and more
- Keyword Matching: Filter content with configurable keywords (exact, contains, or regex)
- Exclusion Keywords: Filter out unwanted content
- Cross-Platform: Runs on Windows, Linux, and macOS
- Background Service: Runs continuously as a system service
- Extensible: Easy to add new sources and destinations
Sources (ISocialMediaSource) → Message Processor → Destinations (IPublishDestination)
├── RedditSource (Keyword Filtering) ├── DiscordPublisher
├── DiscordSource ├── EmailPublisher (future)
└── [Future sources...] └── [Future destinations...]
- .NET 9.0 SDK
- For Reddit: Reddit API credentials
- For Discord: Discord bot token(s)
cd /path/to/SocialSifter
dotnet buildCopy the example configuration:
cp appsettings.example.json appsettings.jsonEdit appsettings.json to set your keywords:
{
"SocialSifter": {
"Keywords": [
"your-keyword",
"another keyword"
],
"ExcludeKeywords": [
"spam"
],
"KeywordMatchMode": "Contains",
"CaseSensitive": false
}
}Note: appsettings.json is gitignored and will not be committed.
Initialize user secrets:
dotnet user-secrets initAdd credentials for sources and destinations:
# Reddit source
dotnet user-secrets set "Sources:Reddit:ClientId" "your-client-id"
dotnet user-secrets set "Sources:Reddit:ClientSecret" "your-client-secret"
dotnet user-secrets set "Sources:Reddit:Username" "your-username"
dotnet user-secrets set "Sources:Reddit:Password" "your-password"
# Discord source (monitoring)
dotnet user-secrets set "Sources:Discord:BotToken" "your-source-bot-token"
# Discord destination (publishing)
dotnet user-secrets set "Destinations:Discord:BotToken" "your-destination-bot-token"
dotnet user-secrets set "Destinations:Discord:ServerId" "your-server-id"
dotnet user-secrets set "Destinations:Discord:ChannelId" "your-channel-id"dotnet rundotnet publish -c Release -r win-x64
sc create SocialSifter binPath="C:\path\to\SocialSifter.exe"
sc start SocialSifterdotnet publish -c Release -r linux-x64
# Create service file
sudo nano /etc/systemd/system/socialsifter.service
# Enable and start
sudo systemctl enable socialsifter
sudo systemctl start socialsifterSocialSifter/
├── Interfaces/
│ ├── ISocialMediaSource.cs # Source interface
│ └── IPublishDestination.cs # Destination interface
├── Models/
│ └── SocialMessage.cs # Message model
├── Sources/
│ ├── RedditSource.cs # Reddit implementation
│ └── DiscordSource.cs # Discord implementation
├── Destinations/
│ └── DiscordPublisher.cs # Discord publisher
├── Services/
│ └── MessageProcessor.cs # Keyword filtering
├── Worker.cs # Main service loop
├── Program.cs # DI configuration
└── DESIGN.md # Detailed design doc
- Implement
ISocialMediaSourceinterface - Add to DI in
Program.cs - Configure credentials in user secrets
- Implement
IPublishDestinationinterface - Add to DI in
Program.cs - Configure credentials in user secrets
The application uses Serilog for structured logging with:
- Console output: Logs to console with colorized output
- File output: Daily rolling log files in
logs/directory - Retention: Keeps last 7 days of logs
Logs include:
- Source initialization and message retrieval
- Keyword matches with details
- Publish operations to destinations
- Errors and exceptions with full context
Implemented:
- ✅ Core architecture and interfaces
- ✅ Message processor with keyword matching
- ✅ Configuration system with user secrets
- ✅ Stub implementations for Reddit and Discord sources
- ✅ Stub implementation for Discord publisher
- ✅ Serilog structured logging with console and file sinks
TODO:
- ⏳ Complete Reddit source implementation (integrate Reddit API client)
- ⏳ Complete Discord source implementation (integrate Discord.Net)
- ⏳ Complete Discord publisher implementation
- ⏳ Add state persistence for deduplication
- ⏳ Add per-source polling intervals
- ⏳ Add configuration for enabling/disabling sources
MIT License - See LICENSE file for details