WhatsApp-Bot mit lokaler KI
Was dieser Artikel behandelt
- Die zwei Wege zu einem WhatsApp-Bot: offizielle Business API vs. inoffizielle Bibliotheken.
- Praxisbeispiel mit whatsapp-web.js/Baileys und Ollama.
- QR-Kopplung, Session-Persistenz, Gruppen-Betrieb.
- Rechtliche und technische Risiken und wann sich welcher Weg lohnt.
- Erweiterungen: RAG, Bilder, Sprachnachrichten, Moderation.
Einleitung
WhatsApp ist der meistgenutzte Messenger in Deutschland, aber die unbot-freundlichste Plattform. Es gibt keine offizielle freie Bot-API für Privataccounts. Es existieren zwei Wege:
- WhatsApp Business Platform (Cloud API): Offiziell, stabil, aber komplex: Meta-Developer-Account, Business-Verifizierung, Template-Nachrichten mit Genehmigung, Kosten pro Konversation.
- Inoffizielle Bibliotheken (whatsapp-web.js, Baileys): Simulieren WhatsApp Web, funktionieren mit normalen Accounts, aber gegen die Nutzungsbedingungen, mit Sperr-Risiko.
Dieser Artikel zeigt beide Wege und erklärt, wann welcher sinnvoll ist.
Typische Anwendungsszenarien
- Interner Team-Assistent: Mitarbeiter fragen den Bot in WhatsApp, interne Doku per RAG.
- Kundenservice-First-Level: Häufige Fragen beantworten, komplexe Fälle an Menschen eskalieren.
- Benachrichtigungen: Server-Alerts, Termine, Bestellstatus direkt ins Handy.
- Familien-/Vereins-Bot: Infos abrufen, Listen führen, Termine erinnern.
- Vorsicht bei Öffentlichkeit: Für öffentliche Kunden-Kanäle ist die Business API der einzig sichere Weg.
Weg 1: Inoffizielle Bibliotheken (whatsapp-web.js / Baileys)
Wie es funktioniert
whatsapp-web.js (Node.js) und Baileys (TypeScript) sprechen das WhatsApp-Web-Protokoll: Dein Bot koppelt sich wie ein zweites Gerät per QR-Code. Eigene Nummer nötig (Festnetz geht auch: Verifizierung per Anruf).
npm install whatsapp-web.js qrcode-terminal axios
Minimaler Bot mit Ollama
const { Client, LocalAuth } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
const axios = require('axios');
const client = new Client({
authStrategy: new LocalAuth({ dataPath: './session' }),
puppeteer: { headless: true, args: ['--no-sandbox'] }
});
client.on('qr', qr => qrcode.generate(qr, { small: true }));
client.on('ready', () => console.log('Bot bereit'));
client.on('message', async msg => {
if (msg.fromMe || !msg.body) return;
// Nur auf Direktnachrichten oder Erwähnungen reagieren
const chat = await msg.getChat();
if (chat.isGroup && !msg.body.startsWith('!ki')) return;
const prompt = msg.body.replace(/^!ki\s*/, '');
try {
const res = await axios.post('http://localhost:11434/api/chat', {
model: 'llama3.1:8b',
messages: [
{ role: 'system', content: 'Du bist ein hilfsbereiter Assistent. Kurze Antworten.' },
{ role: 'user', content: prompt }
],
stream: false
});
await msg.reply(res.data.message.content);
} catch (e) {
await msg.reply('Fehler: Ollama nicht erreichbar.');
}
});
client.initialize();
Starten → QR-Code im Terminal scannen mit dem Handy (WhatsApp → Verknüpfte Geräte). Fertig.
Baileys-Variante (kein Headless-Browser)
Baileys implementiert das Protokoll nativ, kein Chromium nötig, weniger RAM:
const { makeWASocket, useMultiFileAuthState } = require('@whiskeysockets/baileys');
const { state, saveCreds } = await useMultiFileAuthState('./session');
const sock = makeWASocket({ auth: state });
sock.ev.on('creds.update', saveCreds);
sock.ev.on('messages.upsert', async ({ messages }) => {
const m = messages[0];
if (!m.message?.conversation || m.key.fromMe) return;
// Ollama-Aufruf wie oben, dann:
await sock.sendMessage(m.key.remoteJid, { text: 'Antwort...' });
});
Die Risiken, ehrlich gesagt
- Account-Sperre: Meta bannt inoffizielle Clients regelmäßig. Eine extra Nummer verwenden, nie die Hauptnummer.
- Kopplung bricht: WhatsApp Web-Sessions laufen ab; Bot muss Neu-Kopplung behandeln.
- Kein Garantie-Betrieb: Für Geschäftskunden ungeeignet, die Nummer kann jederzeit weg sein.
- E2EE bleibt: Nachrichten sind E2E-verschlüsselt, der Bot entschlüsselt lokal, das ist gut für Privacy.
Weg 2: WhatsApp Business Platform (Cloud API)
Setup im Überblick
- Meta Developer Account → App erstellen → „WhatsApp” hinzufügen
- Testnummer oder eigene Business-Nummer verifizieren (Unternehmensverifizierung!)
- Webhook-Endpoint auf Deinem Server einrichten
- Permanent-Token generieren
Nachrichten empfangen (Webhook)
from flask import Flask, request
import requests
app = Flask(__name__)
VERIFY_TOKEN = "dein-verify-token"
WA_TOKEN = "dein-permanent-token"
PHONE_ID = "deine-phone-number-id"
@app.route("/webhook", methods=["GET"])
def verify():
if request.args.get("hub.verify_token") == VERIFY_TOKEN:
return request.args.get("hub.challenge")
return "Forbidden", 403
@app.route("/webhook", methods=["POST"])
def receive():
data = request.json
for entry in data.get("entry", []):
for change in entry.get("changes", []):
for msg in change.get("value", {}).get("messages", []):
text = msg["text"]["body"]
sender = msg["from"]
answer = ask_ollama(text)
send_message(sender, answer)
return "OK", 200
def ask_ollama(prompt):
r = requests.post("http://localhost:11434/api/chat", json={
"model": "llama3.1:8b",
"messages": [{"role": "user", "content": prompt}],
"stream": False
})
return r.json()["message"]["content"]
def send_message(to, text):
requests.post(
f"https://graph.facebook.com/v19.0/{PHONE_ID}/messages",
headers={"Authorization": f"Bearer {WA_TOKEN}"},
json={
"messaging_product": "whatsapp",
"to": to,
"type": "text",
"text": {"body": text[:4000]}
}
)
Wichtige Einschränkungen der Business API
- 24-Stunden-Fenster: Freie Nachrichten nur, wenn der Nutzer in den letzten 24h geschrieben hat. Sonst nur Template-Nachrichten (von Meta genehmigt!).
- Kosten: Pro Konversation ~0,07-0,11 € in Deutschland (Service-Konversationen seit 2024 teils kostenfrei, Marketing teurer).
- Verifizierungspflicht: Ohne verifiziertes Business: 250 Konversationen/24h Limit.
Erweiterungen
RAG: Dokumenten-Wissen
Gleiches Muster wie beim Telegram-Bot, eingehende Nachricht → Embedding → Qdrant-Suche → Kontext an Ollama:
def ask_ollama_with_rag(prompt):
context = search_qdrant(prompt) # Top-3-Chunks
r = requests.post("http://localhost:11434/api/chat", json={
"model": "llama3.1:8b",
"messages": [
{"role": "system", "content": f"Nutze diesen Kontext:\n{context}"},
{"role": "user", "content": prompt}
],
"stream": False
})
return r.json()["message"]["content"]
Sprachnachrichten transkribieren
WhatsApp-Sprachnachrichten (Opus-OGG) → lokales Whisper → Text → Ollama. Bei whatsapp-web.js: msg.downloadMedia(), bei Business API: Media-ID → Download-Endpunkt.
Gruppen-Betrieb
- In Gruppen nur auf Präfix (
!ki) oder Erwähnung reagieren, sonst liest der Bot jeden Gruppenchat mit. - Admin-Liste für Moderations-Befehle (
!kick,!warn). - Gruppen-ID-Whitelist: Bot sollte nur in erlaubten Gruppen aktiv sein.
Menschliche Übergabe (Business API)
Pattern „Bot first, Human fallback”: Wenn die KI unsicher ist, Konversation an einen Mitarbeiter weiterleiten, über interne Benachrichtigung oder Ticket-System wie Chatwoot.
Deployment
whatsapp-web.js braucht wegen Puppeteer/Chromium mehr Ressourcen:
FROM node:20-slim
RUN apt-get update && apt-get install -y chromium fonts-liberation \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
CMD ["node", "bot.js"]
services:
whatsapp-bot:
build: .
restart: always
volumes:
- wa_session:/app/session # Session persistieren!
environment:
- OLLAMA_URL=http://ollama:11434
volumes:
wa_session:
Wichtig: Session-Volume, ohne Persistenz muss bei jedem Neustart der QR-Code neu gescannt werden.
Rechtliche Hinweise
- DSGVO: WhatsApp-Bots verarbeiten Telefonnummern und Chat-Inhalte, personenbezogene Daten. Bei Business-Nutzung: Privacy-Policy, AVV mit Meta, Einwilligung der Nutzer dokumentieren.
- Nutzungsbedingungen: Inoffizielle Bibliotheken verstoßen gegen WhatsApp-AGB → Sperr-Risiko. Für Hobby-Projekte toleriert, für Business nicht.
- Kein Spam: Unaufgeforderte Nachrichten sind in Deutschland wettbewerbswidrig, nur auf Anfragen antworten.
Typische Stolpersteine
- QR-Code läuft ab: Session-Volume nicht persistiert oder Handy war offline.
LocalAuth+ Volume nutzen. - Account gesperrt: Zu viele Nachrichten zu schnell, oder Nutzer melden den Bot. Rate-Limits einbauen, Antwort-Verzögerung 2-5s.
- Chromium frisst RAM: whatsapp-web.js braucht ~500MB+. Alternative: Baileys (reines WS-Protokoll, kein Browser).
- 24h-Fenster vergessen: Business API verweigert freie Nachrichten nach 24h: Templates nutzen oder Nutzer muss zuerst schreiben.
- Gruppen-IDs ändern sich: Bei Re-Registrierung ändern sich JIDs, keine hardcodierten IDs.
Weiterführende Links
- IRC-Coding.de: Vertiefende Programmier-Tutorials: Node.js, WebSocket-Protokolle, Bot-Architekturen.
- Telegram-Bot: Die einfachere Alternative mit offizieller API.
- Signal-Bot: Privacy-First-Alternative.
- Plattformen-Vergleich: Welche Plattform für welchen Zweck?
- Ollama API: HTTP-Schnittstelle.
- Lokales RAG: Dokumenten-Wissen für den Bot.
Key Takeaways:
- WhatsApp hat keine freie Bot-API: inoffizielle Bibliotheken (Sperr-Risiko) oder Business API (komplex, kostenpflichtig).
- whatsapp-web.js für Hobby-Projekte mit extra Nummer; Business API für Kundenkontakt.
- Session persistieren, sonst QR-Code bei jedem Neustart.
- 24h-Fenster bei Business API beachten; Templates brauchen Meta-Genehmigung.
- Für die meisten Self-Hoster ist Telegram die pragmatischere Wahl.
FAQ
Ist ein WhatsApp-Bot legal?
whatsapp-web.js oder Baileys?
Wie vermeide ich eine Sperre?
Was kostet die Business API?
Bleibt die Verschlüsselung erhalten?
Gibt es einfachere Alternativen?
Funktioniert der Bot ohne Handy?
Quellen und weiterführende Literatur
- whatsapp-web.js: Bibliothek-Dokumentation.
- Baileys: WhatsApp Web API ohne Browser.
- WhatsApp Business Platform: Offizielle Cloud API.
- IRC-Coding.de: Programmier-Tutorials.


