Channels
Connect OpenSentinel to any messaging platform. Each channel runs independently — enable only what you need.
Overview
OpenSentinel supports 10+ input channels. Each channel is activated by setting the corresponding environment variable in your .env file. All channels run in parallel on a single instance and share the same brain, memory, and tool system.
| Channel | Env Variable | Protocol | Status |
|---|---|---|---|
| Telegram | TELEGRAM_BOT_TOKEN | Bot API (grammY) | Stable |
| Discord | DISCORD_BOT_TOKEN | Gateway (discord.js) | Stable |
| Slack | SLACK_BOT_TOKEN | Bolt / Socket Mode | Stable |
WHATSAPP_ENABLED | Baileys (Web) | Stable | |
| Signal | SIGNAL_ENABLED | signal-cli JSON-RPC | Stable |
| iMessage | IMESSAGE_ENABLED | BlueBubbles / AppleScript | macOS only |
| WebSocket | Always on | ws:// (Bun native) | Stable |
| Web Dashboard | Always on | HTTP + React | Stable |
| REST API | Always on | HTTP (Hono) | Stable |
| Voice | VOICE_ENABLED | Microphone + STT | Linux |
Telegram
Telegram is the primary and most feature-rich channel for OpenSentinel. It uses the grammY framework and supports text messages, voice notes with automatic transcription, inline keyboards, and full tool execution.
Setup
Open Telegram, search for @BotFather, and send /newbot. Follow the prompts to choose a name and username. BotFather will give you a bot token.
TELEGRAM_BOT_TOKEN=your-telegram-bot-token
TELEGRAM_CHAT_ID=your-chat-id # Your personal chat ID (restricts access)
The Telegram bot starts automatically when TELEGRAM_BOT_TOKEN is set. Find your bot in Telegram and send /start.
TELEGRAM_CHAT_ID to restrict the bot to your personal chat. Any message from a different chat ID is silently ignored. To find your chat ID, send a message to the bot and check the server logs.Features
- Text messages — Full conversational AI with Claude, including tool execution (shell, web search, file operations, etc.)
- Voice messages — Automatic STT transcription via OpenAI Whisper, processes the transcription as a text query, and optionally replies with TTS audio via ElevenLabs
- Markdown formatting — Responses are sent with Telegram Markdown, with automatic plaintext fallback on parse errors
- Long message splitting — Messages exceeding Telegram's 4096-character limit are automatically split at natural break points
- Session history — Last 20 messages per user are maintained for multi-turn conversations
- Tool usage display — Shows which tools were used (e.g., "Used: shell, web_search") above the response
Commands
| Command | Description |
|---|---|
/start | Welcome message with capabilities overview |
/help | Show all available commands and usage examples |
/clear | Clear conversation history for the current session |
/remind <time> <message> | Set a reminder (e.g., /remind 5m Check the oven). Supports s, m, h units |
/mode <name> | Switch personality mode (e.g., concise, creative, technical) |
/expert <domain> | Activate a domain expert persona (e.g., /expert python) |
How it works
import { Bot, session } from "grammy";
import { handleMessage, handleVoice } from "./handlers";
const bot = new Bot(env.TELEGRAM_BOT_TOKEN);
// Session middleware maintains per-user conversation history
bot.use(session({ initial: () => ({ messages: [] }) }));
// Restrict to your personal chat
bot.use(async (ctx, next) => {
if (ctx.chat?.id?.toString() !== env.TELEGRAM_CHAT_ID) return;
await next();
});
// Route text and voice messages to handlers
bot.on("message:text", handleMessage);
bot.on("message:voice", handleVoice);
Voice messages are downloaded, transcribed with Whisper, and processed as text. If the response is short enough (under 1000 characters), a voice reply is also generated via ElevenLabs TTS and sent back as an .ogg file.
Discord
The Discord channel uses discord.js and supports slash commands, direct messages, server mentions, and voice channel operations. Per-user sessions are maintained with the last 20 messages of context.
Setup
Go to discord.com/developers/applications, click New Application, then navigate to Bot and click Reset Token to get your bot token.
In the Bot settings, enable all three Privileged Gateway Intents:
- Presence Intent
- Server Members Intent
- Message Content Intent
DISCORD_BOT_TOKEN=your-discord-bot-token
DISCORD_CLIENT_ID=your-client-id
DISCORD_GUILD_ID=your-server-id # Your server ID
DISCORD_ALLOWED_USER_IDS=your-user-id # Comma-separated
Use the OAuth2 URL generator in the developer portal. Select bot and applications.commands scopes, then grant Send Messages, Read Message History, Use Slash Commands, and Connect (for voice) permissions.
Slash Commands
| Command | Description |
|---|---|
/ask <question> | Ask a single question with full tool execution |
/chat <message> | Continue a multi-turn conversation with context |
/clear | Clear your conversation history (ephemeral reply) |
/remind <time> <unit> <message> | Set a reminder with dropdown unit selection (seconds, minutes, hours) |
/status | Check bot status and your session message count |
/help | Show all available commands and tips |
/voice join | Join your current voice channel |
/voice leave | Leave the voice channel |
/voice speak <text> | Speak text aloud in the voice channel via TTS |
Features
- Slash commands — All commands are registered as Discord slash commands with proper descriptions and option types
- DM support — Message the bot directly for private conversations
- Deferred replies — Long-running tool executions use Discord's deferred reply system so the interaction never times out
- Message splitting — Responses exceeding Discord's 2000-character limit are automatically split into follow-up messages
- User restriction — Set
DISCORD_ALLOWED_USER_IDSto restrict access to specific Discord users - Voice channels — Join voice, speak with TTS, and leave via slash commands
Slack
The Slack channel uses Bolt for JavaScript and supports both HTTP receiver mode and Socket Mode for deployments behind firewalls. It handles app mentions, DMs, file sharing, threaded conversations, and slash commands.
Setup
Go to api.slack.com/apps and click Create New App. Choose From scratch, name it "OpenSentinel", and select your workspace.
Under OAuth & Permissions, add these Bot Token Scopes: app_mentions:read, chat:write, commands, files:read, im:history, im:read, im:write, reactions:read, reactions:write, users:read.
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_SIGNING_SECRET=your-signing-secret
SLACK_APP_TOKEN=xapp-your-app-token # For Socket Mode
SLACK_SOCKET_MODE=true # Use Socket Mode (recommended)
Slash Commands
| Command | Description |
|---|---|
/opensentinel ask <question> | Ask a single question |
/opensentinel chat <message> | Continue a multi-turn conversation |
/opensentinel clear | Clear your conversation history |
/opensentinel remind <time> <message> | Set a reminder (e.g., /opensentinel remind 5m Stand up) |
/opensentinel status | Check bot status and capabilities |
/opensentinel help | Show all available commands |
Individual slash commands are also available: /opensentinel-ask, /opensentinel-chat, /opensentinel-clear, /opensentinel-remind, /opensentinel-status, /opensentinel-help.
Features
- App mentions — @mention the bot in any channel to ask a question; replies are threaded
- Direct messages — Chat privately with the bot in DMs
- Threaded conversations — Thread-aware session tracking preserves context across a full thread
- File handling — Shared audio files are automatically transcribed
- Processing indicators — An hourglass reaction is added while processing and removed on completion
- Socket Mode — No public URL needed; works behind firewalls and NAT
- User/channel restrictions — Set
SLACK_ALLOWED_USER_IDSorSLACK_ALLOWED_CHANNEL_IDSto control access
The WhatsApp channel uses the Baileys library to connect to WhatsApp Web. It authenticates via QR code scan, supports multi-device mode, and persists authentication state across restarts.
Setup
WHATSAPP_ENABLED=true
WHATSAPP_AUTH_DIR=./whatsapp-auth # Credential storage path
WHATSAPP_ALLOWED_NUMBERS=+1234567890 # Comma-separated allowed numbers
On first launch, a QR code is printed to the terminal. Open WhatsApp on your phone, go to Linked Devices, and scan it. Authentication persists in the whatsapp-auth directory, so you only need to scan once.
Features
- Text messages — Full AI conversations with tool execution
- Typing indicators — Shows "composing" while processing, then "paused" when done
- Auto-reconnect — Automatically reconnects on disconnect (unless logged out)
- Number allowlist — Set
WHATSAPP_ALLOWED_NUMBERSto restrict access - Per-conversation context — Last 10 messages are maintained per contact
whatsapp-auth directory. Subsequent restarts reconnect automatically without rescanning.Signal
The Signal channel uses signal-cli in JSON-RPC mode to send and receive encrypted messages. All messages remain end-to-end encrypted through Signal's protocol.
Setup
# Install signal-cli (Linux)
$ wget https://github.com/AsamK/signal-cli/releases/latest/download/signal-cli-0.13.2-Linux.tar.gz
$ tar xf signal-cli-*.tar.gz -C /opt/
$ ln -s /opt/signal-cli-*/bin/signal-cli /usr/local/bin/
# Link to your existing Signal account
$ signal-cli link -n "OpenSentinel"
SIGNAL_ENABLED=true
SIGNAL_PHONE_NUMBER=+1234567890
SIGNAL_CLI_PATH=signal-cli # Path to binary (default: signal-cli)
SIGNAL_ALLOWED_NUMBERS=+1234567890 # Comma-separated allowed numbers
Features
- End-to-end encryption — All messages use Signal's encryption protocol
- JSON-RPC interface — OpenSentinel spawns signal-cli as a child process and communicates via JSON-RPC over stdin/stdout
- Number allowlist — Restrict access to specific phone numbers
- Per-contact context — Last 10 messages maintained per sender
// Signal-cli runs as a subprocess in JSON-RPC mode
// OpenSentinel reads incoming messages from stdout
// and writes outgoing messages to stdin
signal-cli -u +1234567890 jsonRpc
stdout → OpenSentinel (receives messages)
stdin ← OpenSentinel (sends replies)
iMessage
The iMessage channel supports two modes: BlueBubbles (requires a BlueBubbles server running on macOS) and AppleScript (direct macOS integration via the Messages app). Both modes provide full AI conversation capabilities.
Setup
# .env - BlueBubbles mode (any platform, Mac server required)
IMESSAGE_ENABLED=true
IMESSAGE_MODE=bluebubbles
IMESSAGE_BLUEBUBBLES_URL=http://192.168.1.100:1234
IMESSAGE_BLUEBUBBLES_PASSWORD=your-password
IMESSAGE_ALLOWED_NUMBERS=+1234567890
Features
- BlueBubbles mode — Connects to a BlueBubbles server via REST API. Run OpenSentinel on any platform while the Mac server handles iMessage
- AppleScript mode — Direct integration with the Messages app on macOS. Requires Full Disk Access permission for the terminal/process
- Polling — Both modes use configurable polling intervals (default: 5 seconds) to check for new messages
- Number restriction — Set
IMESSAGE_ALLOWED_NUMBERSto control who can interact with the bot
WebSocket
The WebSocket channel provides real-time, bidirectional communication for custom integrations. It is always available at ws://localhost:8030/ws and uses Bun's native WebSocket implementation for high performance.
Message Protocol
The WebSocket interface uses a JSON-based message protocol. Clients send typed messages and receive streamed responses including text chunks, tool execution events, and completion signals.
// Send a message with tool execution
{
"type": "chat_with_tools",
"id": "msg-123",
"payload": {
"messages": [
{ "role": "user", "content": "What files are in my Downloads?" }
],
"userId": "user-1"
}
}
// Text chunks arrive in real-time
{ "type": "chunk", "id": "msg-123", "payload": { "text": "Let me check " } }
{ "type": "tool_start", "id": "msg-123", "payload": { "toolName": "shell" } }
{ "type": "tool_result", "id": "msg-123", "payload": { "toolName": "shell", "toolResult": "..." } }
{ "type": "complete", "id": "msg-123", "payload": { "content": "..." } }
Supported Message Types
| Client Message | Description |
|---|---|
chat | Simple chat without tool execution, streamed response |
chat_with_tools | Full chat with tool execution, streams chunks + tool events |
ping | Keepalive ping; server responds with pong |
cancel | Cancel an in-flight request by message ID |
Features
- Streaming responses — Text arrives token-by-token in real-time
- Tool execution events — Observe tool_start and tool_result events as they happen
- Request cancellation — Cancel long-running requests mid-stream
- Connection tracking — Each connection gets a unique ID and activity timestamp
- Broadcast support — Server can broadcast messages to all connected clients
Web Dashboard
OpenSentinel includes a built-in React web dashboard accessible at http://localhost:8030. It provides five views: Chat, Memories, Graph, Email, and Settings. The dashboard is always available when the server is running.
Features
- Chat interface — Full-featured chat UI with markdown rendering, code highlighting, and file attachments
- Memory explorer — Browse and search the RAG vector memory system
- OSINT Graph Explorer — Interactive D3 visualization of entity relationships and knowledge graph
- Web email client — Browse inbox, read HTML emails, download/view attachments, compose with attachments, reply, and forward
- Settings panel — Configure personality, active tools, and channel preferences
- Real-time streaming — Uses the WebSocket channel under the hood for token-by-token streaming
- Mobile responsive — Works on phones and tablets
Building the Dashboard
The dashboard is pre-built in production. For development:
$ cd src/web && bun install && bun run build
REST API
The REST API is built on Hono and provides full programmatic access to OpenSentinel. It is always available at http://localhost:8030 alongside the web dashboard.
Primary Endpoint
$ curl -X POST http://localhost:8030/api/ask \
-H "Content-Type: application/json" \
-d '{"message": "What is the weather in NYC?"}'
Response Format
{
"content": "The current weather in New York City is...",
"inputTokens": 1250,
"outputTokens": 340,
"toolsUsed": ["web_search"]
}
Multi-turn Conversations
Pass a message array for multi-turn conversations:
$ curl -X POST http://localhost:8030/api/ask \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "Remember that my name is Alex"},
{"role": "assistant", "content": "Got it! I will remember that your name is Alex."},
{"role": "user", "content": "What is my name?"}
]
}'
Features
- Full tool execution — The API has access to all tools (shell, search, files, etc.)
- Conversation context — Pass full message arrays for multi-turn dialogue
- Token usage — Every response includes input and output token counts
- Tool reporting — The
toolsUsedfield lists all tools invoked during the response
Voice
The Voice channel enables hands-free interaction with OpenSentinel through wake word detection, voice activity detection (VAD), and continuous conversation mode. It uses local audio capture with arecord (Linux) and processes speech through OpenAI Whisper for transcription.
Setup
VOICE_ENABLED=true
OPENAI_API_KEY=sk-proj-... # Required for Whisper STT
ELEVENLABS_API_KEY=your-elevenlabs-key # Optional, for TTS responses
Wake Word Detection
Say "Hey OpenSentinel" to activate the assistant. The detector uses a hybrid approach combining local MFCC-based keyword spotting with cloud-based STT for high accuracy and low latency.
| Feature | Details |
|---|---|
| Default wake word | hey opensentinel |
| Accepted variations | hey open sentinel, hey opensentinal, hey open sentimental, and more |
| Matching | Levenshtein distance + phonetic encoding for fuzzy matching |
| Confidence threshold | 0.6 minimum (configurable) |
| Detection timeout | 5 seconds of inactivity returns to sleep |
Processing Pipeline
Microphone → 16kHz PCM → VAD (speech detection)
→ MFCC local spotting (pre-filter)
→ Whisper STT (transcription)
→ Wake word matching (fuzzy + phonetic)
→ Command extraction
→ Claude AI (processing)
→ ElevenLabs TTS (voice reply)
Features
- Wake word detection — Hybrid MFCC + STT approach filters audio locally before sending to cloud, reducing API calls
- Voice Activity Detection — Detects speech start/end to segment audio accurately. Configured for -35 dB silence threshold with 200ms minimum speech duration
- Continuous conversation — After wake word activation, the assistant stays awake for 5 seconds of inactivity, allowing natural multi-turn voice conversations
- Command extraction — Text after the wake word is automatically extracted as a command (e.g., "Hey OpenSentinel, what time is it?" extracts "what time is it?")
- Customizable wake word — Change the wake word at runtime. New phonetic variations are added automatically
- TTS responses — Replies under 1000 characters are automatically spoken aloud via ElevenLabs
arecord (ALSA utils) which is available on Linux. macOS and Windows support is planned for a future release.