Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7176f09387 | ||
|
|
100b2af449 | ||
|
|
3d933c96a6 | ||
|
|
52c51fbf3f |
4 changed files with 50 additions and 0 deletions
|
|
@ -11,5 +11,8 @@ BOT_NAME=EdGpt
|
|||
DIENSTEN_JSON=./diensten/dienst-tijden.json
|
||||
DIENSTEN_PNG=./diensten/png
|
||||
|
||||
# Rate limiting
|
||||
MAX_REQUESTS_PER_DAY=5
|
||||
|
||||
# Admin notifications
|
||||
ADMIN_NUMBER=31612345678@c.us
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ npx pm2 logs dienst-bot
|
|||
src/
|
||||
index.js # Express webhook server
|
||||
messageHandler.js # Berichtverwerking en filtering
|
||||
rateLimiter.js # Spam protectie (max 5 per dag)
|
||||
dienstService.js # JSON lookup en PNG bestandspaden
|
||||
whatsappApi.js # WhatsApp API client (bericht + afbeelding)
|
||||
```
|
||||
|
|
@ -124,6 +125,10 @@ src/
|
|||
- **Fout bij verzenden PNG**: de admin krijgt een WhatsApp melding
|
||||
- **Webhook fout**: wordt gelogd in PM2 logs
|
||||
|
||||
## Spam protectie
|
||||
|
||||
Elke gebruiker kan maximaal `MAX_REQUESTS_PER_DAY` (standaard 5) diensten per dag opvragen. Bij overschrijding krijgt de gebruiker een melding. De teller wordt dagelijks automatisch gereset (bij de eerste request na middernacht).
|
||||
|
||||
## Licentie
|
||||
|
||||
Privé project — niet voor distributie.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
const { findDienst, getPngFilePaths } = require('./dienstService')
|
||||
const { sendTextMessage, sendImageMessage, notifyAdmin } = require('./whatsappApi')
|
||||
const { checkLimit, increment, MAX_REQUESTS_PER_DAY } = require('./rateLimiter')
|
||||
|
||||
const BOT_NAME = (process.env.BOT_NAME || 'EdGpt').toLowerCase()
|
||||
const ALLOWED_GROUP = process.env.ALLOWED_GROUP
|
||||
|
|
@ -40,6 +41,15 @@ async function handleWebhook(payload) {
|
|||
const author = message.author
|
||||
if (!author) return
|
||||
|
||||
const limit = checkLimit(author)
|
||||
if (!limit.allowed) {
|
||||
await sendTextMessage(author, `Je hebt vandaag het maximum van ${limit.max} diensten bereikt. Probeer het morgen opnieuw.`)
|
||||
console.log(`Rate limit reached for ${author} (${limit.count}/${limit.max})`)
|
||||
return
|
||||
}
|
||||
|
||||
increment(author)
|
||||
|
||||
const dienst = findDienst(dienstnummer)
|
||||
if (!dienst) {
|
||||
await sendTextMessage(author, `Dienstnummer ${dienstnummer} niet gevonden.`)
|
||||
|
|
|
|||
32
src/rateLimiter.js
Normal file
32
src/rateLimiter.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
const MAX_REQUESTS_PER_DAY = parseInt(process.env.MAX_REQUESTS_PER_DAY, 10) || 5
|
||||
|
||||
const userCounts = new Map()
|
||||
let currentDate = new Date().toDateString()
|
||||
|
||||
function resetIfNeeded() {
|
||||
const today = new Date().toDateString()
|
||||
if (today !== currentDate) {
|
||||
userCounts.clear()
|
||||
currentDate = today
|
||||
console.log('Rate limiter: daily counters reset')
|
||||
}
|
||||
}
|
||||
|
||||
function checkLimit(userId) {
|
||||
resetIfNeeded()
|
||||
const count = userCounts.get(userId) || 0
|
||||
return {
|
||||
allowed: count < MAX_REQUESTS_PER_DAY,
|
||||
count,
|
||||
max: MAX_REQUESTS_PER_DAY
|
||||
}
|
||||
}
|
||||
|
||||
function increment(userId) {
|
||||
resetIfNeeded()
|
||||
const count = (userCounts.get(userId) || 0) + 1
|
||||
userCounts.set(userId, count)
|
||||
return count
|
||||
}
|
||||
|
||||
module.exports = { checkLimit, increment, MAX_REQUESTS_PER_DAY }
|
||||
Loading…
Reference in a new issue