- Rate Limiting
- Method Filtering - POST for webhooks, GET for info, DELETE returns 418 (teapot)
- Retry Logic
- Timeout
- Health Check Endpoint
- Content Length Limits
# Clone the repository
git clone https://github.com/M1noa/discord-webhook-proxy.git
cd discord-webhook-proxy
# Install dependencies
npm installCopy the example environment file and configure it:
cp .env.example .envEdit .env with your settings:
# Discord Webhook Configuration (REQUIRED)
WEBHOOK_ID=your_webhook_id_here
WEBHOOK_TOKEN=your_webhook_token_here
# Security Configuration (OPTIONAL)
# Leave empty or remove for no authentication (drop-in Discord webhook replacement)
# Set to enable enhanced security features and higher rate limits
API_KEY=your_secure_api_key_here
# Proxy Configuration (set to true if behind Cloudflare/Vercel)
BEHIND_PROXY=false
# Optional: Customize limits
RATE_LIMIT_MAX=5
MAX_CONTENT_LENGTH=2000- Go to your Discord server settings
- Navigate to Integrations → Webhooks
- Create a new webhook or edit an existing one
- Copy the webhook URL:
https://discord.com/api/webhooks/WEBHOOK_ID/WEBHOOK_TOKEN - Extract the
WEBHOOK_IDandWEBHOOK_TOKENfrom the URL
# Generate a secure API key (OPTIONAL)
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"# Development
npm run dev
# Production
npm startReplace your Discord webhook URL with the proxy URL for instant spam protection:
# Instead of: https://discord.com/api/webhooks/ID/TOKEN
# Use: http://localhost:3000/
curl -X POST http://localhost:3000/ \
-H "Content-Type: application/json" \
-d '{
"content": "Give us a star :D",
"username": "ProxyBot"
}'Add an API key for higher rate limits and enhanced features:
curl -X POST http://localhost:3000/ \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"content": "PLEASEE I NEED THE STARS!",
"username": "SecureBot"
}'curl -X POST http://localhost:3000/ \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"embeds": [{
"title": "Secure Notification",
"description": "IM BEGGING I NEED STARS SO BADLY",
"color": 65280,
"url": "https://example.com"
}]
}'const axios = require('axios');
const sendWebhook = async () => {
try {
const response = await axios.post('http://localhost:3000/', {
content: 'IM BEGGING YOU!',
username: 'JSBot',
avatar_url: 'https://cdn.discordapp.com/avatars/123/avatar.png'
}, {
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your_api_key_here'
}
});
console.log('✅ Webhook sent:', response.data);
} catch (error) {
console.error('❌ Error:', error.response?.data || error.message);
}
};
sendWebhook();curl -X POST http://localhost:3000/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key_here" \
-d '{"content": "Hello World!"}'Retrieve mock Discord webhook information (obfuscated for security):
curl -X GET http://localhost:3000/Response:
{
"application_id": null,
"avatar": null,
"channel_id": "9876543210123456789",
"guild_id": "1234567890987654321",
"id": "5647382910384756291",
"name": "Secure Webhook Proxy",
"type": 1,
"token": "AbC123XyZ789MnOpQrStUvWxYz456DeF789GhIjKlMnOpQrStUvWxYzAbC123XyZ",
"url": "https://discord.com/api/webhooks/5647382910384756291/AbC123XyZ789MnOpQrStUvWxYz456DeF789GhIjKlMnOpQrStUvWxYzAbC123XyZ"
}DELETE requests are blocked with a humorous 418 "I'm a teapot" response:
curl -X DELETE http://localhost:3000/Response:
{
"error": "I'm a teapot",
"message": "Cannot brew coffee, I'm a webhook proxy teapot",
"code": 418
}- Rate Limit: 3 requests per minute
- Use Case: Drop-in replacement for Discord webhooks
- Setup: Just replace your Discord webhook URL
- Response: Includes hint about API key benefits
- Rate Limit: 9 requests per minute (3x higher)
- Use Case: Custom applications requiring higher throughput
- Setup: Add
X-API-Keyheader orAuthorization: Bearertoken - Response: Enhanced features and priority processing
npm testThe test suite validates:
- ✅ API key authentication
- ✅ Rate limiting functionality
- ✅ Input validation
- ✅ Method filtering
- ✅ Content length limits
- ✅ Embed validation
- ✅ URL validation
- ✅ Error handling
- Set environment variables in Vercel dashboard
- Set
BEHIND_PROXY=true - Deploy using the included
vercel.json
- Set
BEHIND_PROXY=true - Configure environment variables
- Deploy using Wrangler
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
WEBHOOK_ID |
Required | Discord webhook ID |
WEBHOOK_TOKEN |
Required | Discord webhook token |
API_KEY |
Optional | API authentication key (enables enhanced features) |
BEHIND_PROXY |
false |
Enable proxy IP detection |
RATE_LIMIT_WINDOW |
60000 |
Rate limit window (ms) |
RATE_LIMIT_MAX |
5 |
Max requests per window |
MAX_CONTENT_LENGTH |
2000 |
Max content characters |
MAX_EMBEDS |
10 |
Max embeds per request |
- IP-based rate limiting with configurable windows
- Hashed IP addresses for privacy
- Separate limits for different endpoints
- Automatic retry-after headers
- Strict type checking for all fields
- Content length limits
- Username character validation
- URL validation with domain whitelisting
- Embed structure validation
- API key required for all webhook requests
- Support for
X-API-Keyheader orAuthorization: Bearer - Cryptographically secure key generation
- Automatic IP detection behind proxies
- Support for Cloudflare, Vercel, and other CDNs
- Proper handling of forwarded headers
curl http://localhost:3000/healthResponse:
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00.000Z",
"version": "2.0.0-secure"
}The proxy logs all requests with:
- Timestamp
- Method and path
- Truncated IP address
- User agent
- Processing time
- Error details (if any)
| Status | Error | Description |
|---|---|---|
400 |
Validation failed | Invalid request payload |
401 |
Unauthorized | Missing or invalid API key |
405 |
Method not allowed | Non-POST request to webhook endpoint |
429 |
Rate limit exceeded | Too many requests |
500 |
Internal server error | Server or Discord API error |
- Use HTTPS - Always deploy with SSL/TLS
- Rotate API Keys - Regularly update your API keys
- Monitor Logs - Watch for suspicious activity
- Set Strict Limits - Configure appropriate rate limits
- Use Environment Variables - Never hardcode secrets
- Keep Updated - Regularly update dependencies
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test - Submit a pull request
MIT License - see LICENSE file for details.
Created by Minoa - A secure, production-ready Discord webhook proxy.
⚡ Ready to proxy webhooks securely!