dienst_echo_whatsappgroep/docs/superpowers/plans/2026-05-11-spam-protection.md

4 KiB

Spam Protection Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Limit each user to max 5 dienst requests per day, with automatic daily reset.

Architecture: In-memory rate limiter module that tracks request counts per user per day. Integrated into the message handler pipeline before dienst lookup. Sends a friendly warning when limit is exceeded.

Tech Stack: Node.js, no new dependencies needed


Task 1: Create rate limiter module

Files:

  • Create: src/rateLimiter.js

  • Step 1: Create src/rateLimiter.js

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 }
  • Step 2: Commit
git add src/rateLimiter.js
git commit -m "feat: add rate limiter module"

Task 2: Integrate rate limiter into message handler

Files:

  • Modify: src/messageHandler.js:1,25-36

  • Step 1: Add rate limiter import at top of src/messageHandler.js

Add after line 2:

const { checkLimit, increment, MAX_REQUESTS_PER_DAY } = require('./rateLimiter')
  • Step 2: Add rate limit check in handleWebhook after dienstnummer extraction

Insert between the dienstnummer null check (line 36) and the console.log (line 38), replacing lines 38-40 with:

  console.log(`Processing dienst ${dienstnummer} for ${message.author}`)

  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)
  • Step 3: Verify the file looks correct

Run: node -e "require('./src/messageHandler')" (should not throw)

  • Step 4: Commit
git add src/messageHandler.js
git commit -m "feat: integrate rate limiter into message handler"

Task 3: Add config to .env and restart

Files:

  • Modify: .env

  • Modify: .env.example

  • Step 1: Add MAX_REQUESTS_PER_DAY to .env

Append to .env:

# Rate limiting
MAX_REQUESTS_PER_DAY=5
  • Step 2: Add MAX_REQUESTS_PER_DAY to .env.example

Append to .env.example:

# Rate limiting
MAX_REQUESTS_PER_DAY=5
  • Step 3: Restart bot and verify
npx pm2 restart dienst-bot && npx pm2 save
npx pm2 logs dienst-bot --lines 5 --nostream

Expected: bot starts without errors, logs show listening on port 3002.

  • Step 4: Commit and push
git add .env.example
git commit -m "feat: add rate limiting config option"
git push

Task 4: Update README

Files:

  • Modify: README.md

  • Step 1: Add rate limiting section to README.md

Add after the "Foutafhandeling" section:

## 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).
  • Step 2: Commit and push
git add README.md
git commit -m "docs: add spam protection section to README"
git push