- JavaScript 100%
| docs/superpowers | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
Dienst Bot
Dit project is gemaakt door middel van vibecoding met OpenCode 1.14.40.
WhatsApp bot die dienstschema's (PNG) privé verstuurt op basis van een 4-cijferig dienstnummer, gepost in een speciale WhatsApp groep.
Hoe het werkt
- Iemand stuurt een 4-cijferig dienstnummer in de groep (bijv.
4002) - De bot zoekt het dienstschema op in
dienst-tijden.json - De bijbehorende PNG-bestanden worden privé naar de afzender gestuurd
- Via een vastgezet welkomstbericht in de groep staat uitleg over het gebruik
De bot gebruikt een speciale groep (Dienst opvragen EdGPT-EBS) waarin elk bericht dat uit exact 4 cijfers bestaat wordt verwerkt. Geen @mention nodig.
Vereisten
- Node.js 18+
- wwebjs-api Docker container op nextcloud (poort 3001)
- WhatsApp sessie "EdGpt" actief in wwebjs-api
Installatie
git clone <repo-url>
cd dienst_echo_whatsappgroep
npm install
Configuratie
Kopieer .env.example naar .env en vul de waarden in:
# WhatsApp API
WHATSAPP_API_ENDPOINT=http://192.168.5.252:3001
WHATSAPP_SESSION=EdGpt
# Webhook
WEBHOOK_PORT=3002
ALLOWED_GROUP=120363407613652082@g.us
# Bestanden
DIENSTEN_JSON=./diensten/dienst-tijden.json
DIENSTEN_PNG=./diensten/png
# Admin
ADMIN_NUMBER=31620248011@c.us
wwebjs-api webhook config
In de .env van wwebjs-api:
BASE_WEBHOOK_URL=http://192.168.5.252:3002/webhook
ENABLE_LOCAL_CALLBACK_EXAMPLE=FALSE
ENABLE_WEBHOOK=TRUE
Belangrijk: gebruik docker compose up -d (niet docker restart) om .env wijzigingen door te voeren.
Data
De map diensten/ bevat:
dienst-tijden.json— array met dienstmetadata:[ { "dienstnummer": "4002", "startTime": "09:30", "endTime": "10:30", "paginas": [ { "bestandsnaam": "4002-001.png" }, { "bestandsnaam": "4002-002.png" } ] } ]png/— PNG bestanden met dienstschema's (bijv.4002-001.png)
Beide zijn uitgesloten van git via .gitignore.
Gebruik
Starten (nextcloud — huidig)
De bot draait op nextcloud via systemd (gemigreerd van Mac Mini LaunchDaemon → PM2, nu systemd).
# Status
ssh aiaiaiaiagent@nextcloud "sudo -A systemctl status dienst-bot"
# Herstarten
ssh aiaiaiaiagent@nextcloud "sudo -A systemctl restart dienst-bot"
# Logs volgen
ssh aiaiaiaiagent@nextcloud "sudo -A journalctl -u dienst-bot -n 50 -f"
Oude Mac Mini (niet meer actief)
Plist: /Library/LaunchDaemons/nl.eddydevink.dienst-bot.plist → .disabled
Wrapper: run-dienst-bot.sh (codesign fix voor Homebrew Node)
Projectstructuur
src/
index.js # Express webhook server + cron job
messageHandler.js # Berichtverwerking en filtering
rateLimiter.js # Spam protectie (max 5 per dag)
dailyStats.js # Dagelijkse aanvraag-teller
dienstService.js # JSON lookup en PNG bestandspaden
whatsappApi.js # WhatsApp API client (bericht + afbeelding)
pinnedMessageService.js # Vastgezet welkomstbericht beheer
Welkomstbericht
De groep heeft een vastgezet welkomstbericht dat automatisch door EdGpt wordt herplaatst als het is verlopen (30 dagen). De tekst luidt:
Welkom in Dienst opvragen EdGpt-EBS. Stuur hier je 4 cijferige dienstnummer en EdGpt zal het prive naar je toe sturen, alleen 4 cijfers meer niet.
Bij elke interactie met de groep controleert de bot of het pinned bericht nog bestaat en plaatst het opnieuw indien nodig.
Foutafhandeling
- Ongeldig dienstnummer: de bot stuurt een melding terug naar de afzender
- Fout bij verzenden tekst/PNG: maximaal 3 pogingen met exponential backoff (1s, 2s, 4s) voor 5xx HTTP-fouten en connectieproblemen (ECONNRESET, ECONNREFUSED, ETIMEDOUT). Bij definitieve fout krijgt de admin een WhatsApp-melding.
- EADDRINUSE (poort 3002 in gebruik): de server wacht 5 seconden en herhaalt de bind-poging, met
SO_REUSEADDRom TIME_WAIT te omzeilen - Graceful shutdown: de server handelt SIGTERM en SIGINT af door actieve connecties netjes te sluiten (10s timeout)
- Restart-loop preventie: de LaunchDaemon heeft
ThrottleInterval=10— maximaal 1 herstart per 10 seconden - Webhook fout: wordt gelogd in de 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).
Dagelijkse samenvatting
Elke dag om 10:00 stuurt de bot een WhatsApp-bericht naar ADMIN_NUMBER met het totaal aantal alle 4-cijferige berichten van de vorige dag (00:00 t/m 23:59).
📊 Aantal dienstaanvragen gisteren: N
De teller wordt bijgehouden in memory door dailyStats.js en gereset na verzending van de samenvatting. De scheduling gebruikt node-cron (0 10 * * *).
Licentie
Public Domain