A lightweight Node.js service built with TypeScript that listens for Amazon SNS notifications and RKHunter log reports, forwarding structured alerts to a specified Discord webhook.
Perfect for monitoring email deliverability and server security right from your Discord server.
This service provides real-time monitoring for two critical areas:
- π§ Email Deliverability Monitoring: Tracks SES (Simple Email Service) events including bounces, complaints, and successful deliveries
- π Server Security Monitoring: Processes RKHunter security scan logs and forwards security alerts with detailed system information
All notifications are automatically formatted into rich Discord embeds with color-coding, timestamps, and relevant metadata.
- β Express API with SNS + file upload support
- β AWS SNS signature verification
- β Bounce, Complaint, and Delivery handling (SES)
- β RKHunter scan parser with Discord alerts
- β Discord embeds with color-coded metadata and attachments
- β Rate limiting to protect against abuse
- β Health check UI with real-time status
- β Custom RKHunter setup script with cron
- β Unit-tested with Jest
- β Linted & formatted with ESLint + Prettier
sns-discord-forwarder/
βββ src/
β βββ index.ts # Main application entry point & setup
β βββ routes/
β β βββ sns.ts # AWS SNS webhook handler (email events)
β β βββ report.ts # RKHunter log processing endpoint
β β βββ health/
β β βββ index.ts # Health check endpoint
β βββ utils/
β β βββ index.ts # Utility functions (parsing, formatting)
β β βββ discordNotifier.ts # Discord webhook client
β β βββ logger.ts # Logging utility
β β βββ verifySignature.ts # SNS signature verification
β βββ types/
β β βββ aws.ts # AWS/SNS TypeScript definitions
β β βββ sns.ts # SES notification type definitions
β βββ public/
β βββ health.html # Health check UI template
βββ tests/
β βββ utils/ # Unit tests for utility functions
βββ package.json
βββ README.md
| Component | Purpose | Key Features |
|---|---|---|
src/index.ts |
Application bootstrap | Express setup, middleware, route registration |
src/routes/sns.ts |
Email event processing | SNS signature verification, SES event routing |
src/routes/report.ts |
Security log processing | File upload, RKHunter parsing, Discord formatting |
src/utils/discordNotifier.ts |
Discord integration | Webhook sending, embed formatting, file attachments |
src/utils/index.ts |
Data processing | Log parsing, timestamp extraction, uptime formatting |
git clone https://github.com/Shironex/sns-discord-forwarder.git
cd sns-discord-forwarder
pnpm installCreate a .env file in the project root:
# Server Configuration
PORT=3000 # Port for the HTTP server (default: 3000)
NODE_ENV=production # Environment: 'development' or 'production'
# Discord Integration
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/your-webhook-id/your-token
# Optional: Custom Server Settings
# RATE_LIMIT_WINDOW_MS=3600000 # SNS rate limit window (default: 1 hour)
# RATE_LIMIT_MAX_REQUESTS=10 # Max SNS requests per window (default: 10)
# MAX_FILE_SIZE=10485760 # Max upload size in bytes (default: 10MB)| Variable | Required | Default | Description |
|---|---|---|---|
PORT |
No | 3000 |
HTTP server port |
NODE_ENV |
No | development |
Affects static file paths and logging |
DISCORD_WEBHOOK_URL |
Yes | - | Discord webhook URL for notifications |
RATE_LIMIT_WINDOW_MS |
No | 3600000 |
SNS rate limit window in milliseconds |
RATE_LIMIT_MAX_REQUESTS |
No | 10 |
Maximum SNS requests per window |
MAX_FILE_SIZE |
No | 10485760 |
Maximum file upload size in bytes |
- Go to your Discord server settings
- Navigate to Integrations β Webhooks
- Create a new webhook or copy an existing one
- Copy the webhook URL to your
.envfile
pnpm devRuns the dev server using ts-node.
pnpm build
pnpm startCompiles to dist/ and runs with Node.
# Create SNS topic for email notifications
aws sns create-topic --name email-monitoring
# Subscribe your service endpoint to the SNS topic
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:123456789012:email-monitoring \
--protocol https \
--endpoint https://your-domain.com/sns# Enable bounce notifications for your domain/identity
aws ses set-identity-notification-topic \
--identity your-domain.com \
--notification-type Bounce \
--sns-topic arn:aws:sns:us-east-1:123456789012:email-monitoring
# Enable complaint notifications
aws ses set-identity-notification-topic \
--identity your-domain.com \
--notification-type Complaint \
--sns-topic arn:aws:sns:us-east-1:123456789012:email-monitoring
# Enable delivery notifications (optional)
aws ses set-identity-notification-topic \
--identity your-domain.com \
--notification-type Delivery \
--sns-topic arn:aws:sns:us-east-1:123456789012:email-monitoringA full Bash automation script is included to:
- Install and configure RKHunter
- Patch common false positives
- Schedule daily cron scans at 03:00
- Forward logs to your webhook + email
- Include HTML-style Discord embeds with warnings, suspicious files, and system info
# After running RKHunter scan
curl -X POST \
-F "logfile=@/var/log/rkhunter.log" \
-H "x-server: production-server-01" \
https://your-domain.com/report# Add to /etc/crontab for daily scans
0 3 * * * root rkhunter --check --cronjob --report-warnings-only && curl -X POST -F "logfile=@/var/log/rkhunter.log" -H "x-server: $(hostname)" https://your-domain.com/reportThe service sends different types of notifications:
- π Bounces: Invalid email, full mailbox, blocked sender
- π΄ Complaints: Recipients marked email as spam
- π’ Deliveries: Successful email delivery (if enabled)
- π’ Clean scans: No warnings or errors
- π Warnings: Potential issues detected
- π΄ Critical errors: Serious security findings
Each notification includes:
- Timestamp and server identification
- Color-coded severity levels
- Detailed field information
- Full log file attachments (for security scans)
pnpm testUses Jest. Add tests under src/__tests__.
Method: POST | Content-Type: application/json or text/plain
Handles incoming AWS SNS notifications, primarily SES (Simple Email Service) events.
Supported SNS Message Types:
SubscriptionConfirmation- AWS subscription verificationNotification- Email delivery events (Bounce, Complaint, Delivery)
Security:
- SNS signature verification to prevent spoofing
- Rate limiting (10 requests per hour)
- Request body size limit (10MB)
Example SES Bounce Notification:
{
"Type": "Notification",
"MessageId": "12345678-1234-1234-1234-123456789012",
"Message": "{\"notificationType\":\"Bounce\", \"bounce\": {\"bouncedRecipients\": [{\"emailAddress\":\"user@example.com\"}]}}"
}Method: POST | Content-Type: multipart/form-data
Processes RKHunter security scan logs and forwards structured reports to Discord.
Parameters:
logfile(file) - RKHunter log file (max 10MB)x-server(header, optional) - Server identifier for multi-server setups
Response:
{
"message": "Report sent to Discord"
}Features:
- Automatic log parsing and field extraction
- Color-coded Discord embeds based on severity
- File attachment support for full log access
- Server identification via headers
Method: GET | Accepts: application/json or text/html
Service health monitoring endpoint with uptime and version information.
JSON Response:
{
"status": "running",
"uptime": "2 days, 3 hours, 45 min",
"version": "1.0.0",
"timestamp": "2023-01-01T12:00:00.000Z",
"uptimePercentage": 100.0
}HTML Response: Returns a formatted health status page with real-time information.
- Express
- TypeScript
- AWS SNS + SES
- Discord Webhooks
- Multer (file upload)
- Jest (unit testing)
- Chalk
- Prettier + ESLint
| Script | Description |
|---|---|
pnpm dev |
Run in dev mode (ts-node) |
pnpm build |
Compile TypeScript |
pnpm start |
Run compiled code |
pnpm lint |
Lint with ESLint |
pnpm format |
Format code with Prettier |
pnpm test |
Run unit tests with Jest |
- β Get notified when SES mail bounces, fails, or is marked spam
- β Parse and forward RKHunter logs from VPS
- β Detect suspicious activity or potential compromise
- β Centralize logs in Discord with full visibility
Error: [SNS] Signature verification failed
Solution: Ensure your SNS endpoint is publicly accessible with HTTPS. AWS SNS requires valid SSL certificates.
Error: Failed to send Discord embed message
Solutions:
- Verify
DISCORD_WEBHOOK_URLis correct - Check webhook permissions in Discord
- Ensure the webhook hasn't been deleted
Error: No log file uploaded
Solution: Ensure you're sending the file with the correct form field name logfile and using multipart/form-data content type.
Error: Too many requests, please try again later
Solution: The SNS endpoint is rate-limited to 10 requests per hour. This is normal AWS behavior.
Enable detailed logging by setting NODE_ENV=development:
NODE_ENV=development pnpm startThis provides more verbose logging for troubleshooting.
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes and add tests
- Run the test suite:
pnpm test - Submit a pull request
- Code Style: Follow ESLint and Prettier configurations
- Testing: Add unit tests for new features
- Documentation: Update README for API changes
- Types: Use TypeScript interfaces for new data structures
- INFO: Normal operations and important events
- WARN: Non-critical issues and warnings
- ERROR: Failures that need attention
- DEBUG: Detailed information (development mode only)
Integrate the /health endpoint with monitoring services like:
- UptimeRobot
- Pingdom
- AWS CloudWatch
- Prometheus
Example health check configuration:
curl -f https://your-domain.com/health || exit 1MIT β free to use, modify, and share.