Signal-Bot mit lokaler KI
Was dieser Artikel behandelt
- Wie Du einen Signal-Bot mit signal-cli und Ollama baust.
- Registrierung einer Bot-Nummer und Geräte-Kopplung.
- Empfangen und Senden via JSON-RPC und Daemon-Modus.
- Erweiterungen: Gruppen, RAG, Anhänge, Reaktionen.
- Warum Signal die Privacy-stärkste Bot-Plattform ist.
Einleitung
Signal ist die einzige Mainstream-Plattform mit echter Ende-zu-Ende-Verschlüsselung für alles auch für Bot-Nachrichten. Wer einen KI-Bot für vertrauliche Kommunikation will (Journalisten, Anwälte, Firmeninterna), landet bei Signal.
Der Haken: Es gibt keine offizielle Bot-API. Der Standard-Weg ist signal-cli, ein Java-CLI, das das Signal-Protokoll implementiert und einen Daemon-Modus mit JSON-RPC anbietet. Dein Bot ist dann technisch ein „Signal-Client”, der wie ein normales Gerät funktioniert.
Typische Anwendungsszenarien
- Vertraulicher KI-Assistent: Chats bleiben E2E-verschlüsselt bis zu Deinem Server, ideal für sensible Fragen.
- Familien-/Team-Bot: Interne Kommunikation ohne Meta/Google/Cloud.
- Alarmierung: Monitoring-Alerts E2E-verschlüsselt ans Handy (besser als E-Mail).
- Dokumenten-Assistent: Vertrauliche Dokumente per Signal schicken, lokal verarbeiten lassen.
- Redaktioneller Kontakt: Quellen können anonym mit der KI sprechen.
Voraussetzungen
- Eine Telefonnummer für den Bot (Festnetz geht: Verifizierung per Anruf; oder zweite SIM/eSIM)
- Java 17+ (signal-cli ist Java) oder das Docker-Image
- Ollama mit einem Modell (
llama3.1:8bo. ä.) - Python für die Bot-Logik
Schritt 1: signal-cli installieren und registrieren
# Binary-Release (Linux)
wget https://github.com/AsamK/signal-cli/releases/download/v0.13.x/signal-cli-0.13.x-Linux.tar.gz
sudo tar xf signal-cli-*.tar.gz -C /opt
sudo ln -s /opt/signal-cli-*/bin/signal-cli /usr/local/bin/signal-cli
Nummer registrieren (Captcha nötig: Link aus https://signalcaptchas.org/ holen):
signal-cli -a +4917612345678 register
signal-cli -a +4917612345678 verify 123456
signal-cli -a +4917612345678 updateProfile --name "KI-Assistent"
Alternative: Als verknüpftes Gerät an Deinen bestehenden Account koppeln, der Bot sendet dann als Du (für persönliche Assistenten okay, für öffentliche Bots nicht):
signal-cli link -n "Bot-Server"
# gibt sgnl:// Link → auf dem Handy als QR-Code anzeigen lassen (z.B. mit qrencode) und scannen
Schritt 2: Daemon-Modus mit JSON-RPC
signal-cli kann als JSON-RPC-Daemon laufen: Dein Python-Code kommuniziert über TCP oder HTTP:
# TCP-Daemon
signal-cli -a +4917612345678 daemon --tcp 127.0.0.1:7583
# oder HTTP (REST-ish)
signal-cli -a +4917612345678 daemon --http 127.0.0.1:8080
JSON-RPC-Methoden (Auswahl): send, receive, listGroups, sendTyping, addReaction, updateProfile.
Schritt 3: Bot-Logik mit Ollama
Einfachster Weg: receive-Loop per CLI-Aufruf (gut für den Start):
#!/usr/bin/env python3
import json
import subprocess
import ollama
BOT_NUMBER = "+4917612345678"
MODEL = "llama3.1:8b"
ALLOWED = {"+491701234567"} # Wer darf den Bot nutzen
conversations = {}
client = ollama.Client(host="http://localhost:11434")
def send(recipient, text):
subprocess.run([
"signal-cli", "-a", BOT_NUMBER, "send",
"-m", text, recipient
], check=False)
def ask_ollama(user, text):
history = conversations.setdefault(user, [])
history.append({"role": "user", "content": text})
history = history[-10:]
resp = client.chat(
model=MODEL,
messages=[{"role": "system", "content":
"Du bist ein hilfsbereiter Assistent. Antworte kurz."}] + history,
)
answer = resp["message"]["content"]
history.append({"role": "assistant", "content": answer})
conversations[user] = history
return answer
def main():
proc = subprocess.Popen(
["signal-cli", "-a", BOT_NUMBER, "receive", "-t", "-1",
"--output", "json"],
stdout=subprocess.PIPE, text=True,
)
for line in proc.stdout:
line = line.strip()
if not line:
continue
try:
envelope = json.loads(line)
except json.JSONDecodeError:
continue
msg = envelope.get("envelope", {})
source = msg.get("sourceNumber") or msg.get("source")
data = msg.get("dataMessage")
if not data or source not in ALLOWED:
continue
text = data.get("message")
if not text:
continue
print(f"[{source}] {text}")
answer = ask_ollama(source, text)
# Signal-Limit ~64k, aber kurze Antworten sind besser
send(source, answer[:6000])
if __name__ == "__main__":
main()
Das funktioniert sofort: Polling-Modus, kein Webhook nötig.
Erweiterungen
Gruppen-Betrieb
signal-cli kann Gruppen verwalten. Der Bot reagiert in Gruppen nur auf Erwähnung oder Präfix:
data = msg.get("dataMessage")
group = data.get("groupInfo") # {"groupId": "...", "type": "..."}
text = data.get("message") or ""
if group:
if not text.startswith("!ki"):
continue
text = text[3:].strip()
# Antwort geht an die Gruppe:
subprocess.run(["signal-cli", "-a", BOT_NUMBER, "send",
"-g", group["groupId"], "-m", answer])
Gruppen erstellen/verwalten per CLI:
signal-cli -a +49... updateGroup -n "Team-KI" -m +491701234567 +491702345678
signal-cli -a +49... listGroups
Reaktionen und Typing-Indikator
# Tippen anzeigen
signal-cli -a +49... sendTyping +491701234567
# Reaktion senden
signal-cli -a +49... sendReaction -e "👍" -a +491701234567 -t 1695123456789 +491701234567
Anhänge: Bilder an Vision-Modell
dataMessage.attachments enthält Dateipfade: Bilder an minicpm-v oder llava, Audio an Whisper:
for att in data.get("attachments", []):
if att.get("contentType", "").startswith("image/"):
resp = client.chat(model="minicpm-v", messages=[{
"role": "user",
"content": "Was ist auf diesem Bild?",
"images": [att["file"]],
}])
send(source, resp["message"]["content"])
RAG wie bei Telegram
Identisches Muster: Embedding der Nachricht → Qdrant → Kontext in den System-Prompt. Siehe Telegram-Bot RAG und Lokales RAG.
Deployment
Docker: signal-cli als Daemon
services:
signal-cli:
image: registry.gitlab.com/morph027/signal-cli-daemon:latest
volumes:
- signal_data:/home/.local/share/signal-cli
environment:
- MODE=json-rpc
- SIGNAL_NUMBER=+4917612345678
ports:
- "127.0.0.1:7583:7583"
restart: always
signal-bot:
build: ./bot
restart: always
depends_on: [signal-cli, ollama]
ollama:
image: ollama/ollama:latest
volumes: [ollama_data:/root/.ollama]
volumes:
signal_data:
ollama_data:
systemd ohne Docker
[Unit]
Description=Signal-KI-Bot
After=network-online.target
[Service]
Type=simple
User=signalbot
WorkingDirectory=/opt/signal-bot
ExecStart=/usr/bin/python3 bot.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Datenschutz, der eigentliche Grund für Signal
- E2EE komplett: Nachrichten sind zwischen Sender und Bot-Server verschlüsselt. Signal-Server sehen nur Metadaten (und minimiert die sogar).
- Keine Werbung, kein Tracking: Signal ist ein gemeinnütziger Verein.
- Open Source: Client, Server und signal-cli sind Open Source.
- Grenze: Der Bot selbst entschlüsselt auf Deinem Server, dort gelten Deine Regeln. Und Metadaten (wer wann schreibt) sieht Signal trotzdem.
Typische Stolpersteine
- Registration-Captcha: Signal verlangt Captchas bei Registrierung: Workaround: Account zuerst auf einem Handy registrieren, dann als Linked Device koppeln.
- Nummer gesperrt: Wenn Signal die Nummer sperrt (selten):
signal-cli ... registererneut. - Daemon crasht: signal-cli ist Java, bei OOM
JAVA_OPTS="-Xmx512m"setzen. - Empfang verschluckt sich: Im
receive-Loop langsame Antworten blockieren den Loop: Ollama-Calls in Thread/Async auslagern. - Sealed Sender: Nachrichten von unbekannten Kontakten brauchen Trust:
signal-cli trust -a <nummer>für Kontakte.
Weiterführende Links
- IRC-Coding.de: Vertiefende Programmier-Tutorials: JSON-RPC, Subprocess-Handling, Bot-Architekturen.
- Matrix-Bots: Alternative mit offizieller Bot-API und E2EE.
- Telegram-Bots: Einfachste Bot-Plattform.
- Plattformen-Vergleich: Welche Plattform wofür.
- Datenschutz: Rechtliche Grundlagen.
- Ollama: Modellserver.
Key Takeaways:
- Signal-Bots laufen über signal-cli (Daemon + JSON-RPC), nicht über eine offizielle Bot-API.
- Einzige Plattform mit kompletter E2EE, ideal für vertrauliche Bots.
- Setup: Nummer registrieren oder als Linked Device koppeln, dann receive-Loop.
- Erweiterungen wie überall: Gruppen, RAG, Vision, Whisper.
- Für öffentliche Bots umständlich: Telegram ist einfacher, Signal ist privater.
FAQ
Gibt es eine offizielle Signal-Bot-API?
Brauche ich eine eigene Nummer?
Sind Bot-Nachrichten wirklich verschlüsselt?
Die Registrierung scheitert am Captcha, was tun?
Funktioniert der Bot in Gruppen?
Ist signal-cli schnell genug?
Signal oder Matrix für private Bots?
Quellen und weiterführende Literatur
- signal-cli: CLI + Daemon-Dokumentation.
- signal-cli JSON-RPC: API-Referenz.
- Signal: Offizielle Website.
- IRC-Coding.de: Programmier-Tutorials.


