Salvage of PR #27978 cherry-picked onto current main, resolving conflicts with main's intervening SimpleX plugin fixes (resp-envelope normalization, health-monitor reconnect-churn fix, bare-form DM addressing). What's new: - Group support via SIMPLEX_GROUP_ALLOWED (comma-separated IDs or '*'); inbound items surface chat_id=group:<id> + chat_type=group. Disabled by default so a bot in a group doesn't process every member's traffic. - Inbound files/voice via rcvFileDescrReady (immediate /freceive) deferred through _pending_file_transfers, replayed on rcvFileComplete. Voice notes -> MessageType.VOICE. - Native outbound media: send_image (PNG/JPEG + inline thumbnail), send_voice (msgContent.type=voice), send_video, send_document. All addressed by numeric ID via /_send ... json [...]. - MEDIA:<path> tags in agent replies stripped and dispatched as voice/document. - Text-burst batching (HERMES_SIMPLEX_TEXT_BATCH_DELAY, default 0.8s). - Auto-accept contact requests (SIMPLEX_AUTO_ACCEPT, default true). - Group send path uses structured /_send #<id> json form (the bracket #[<id>] form is parsed as display-name lookup and silently drops). plugin.yaml bumped to 1.1.0; docs updated. All inside plugins/platforms/simplex/ - no core edits. Co-authored-by: Juraj Bednar <juraj@bednar.io>
5.3 KiB
SimpleX Chat
SimpleX Chat is a private, decentralised messaging platform where users own their contacts and groups. Unlike other platforms, SimpleX assigns no persistent user IDs — every contact is identified by an opaque internal ID generated at connection time, which makes it one of the most private messengers available.
Run
hermes gateway setupand pick SimpleX for a guided walk-through.
Prerequisites
- The simplex-chat CLI installed and running as a daemon
- Python package websockets (
pip install websockets)
Install simplex-chat
Download the latest release from the simplex-chat GitHub releases page:
# Linux / macOS binary
curl -L https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-ubuntu-22_04-x86_64 -o simplex-chat
chmod +x simplex-chat
The SimpleX Chat project does not publish a prebuilt Docker image for the chat client; to run it under Docker, build from source from the simplex-chat repository.
Start the daemon
simplex-chat -p 5225
The daemon listens on WebSocket at ws://127.0.0.1:5225 by default.
Configure Hermes
Via setup wizard
hermes gateway setup
Select SimpleX Chat and follow the prompts.
Via environment variables
Add these to ~/.hermes/.env:
SIMPLEX_WS_URL=ws://127.0.0.1:5225
SIMPLEX_ALLOWED_USERS=<contact-id-1>,<contact-id-2>
SIMPLEX_HOME_CHANNEL=<contact-id>
| Variable | Required | Description |
|---|---|---|
SIMPLEX_WS_URL |
Yes | WebSocket URL of the simplex-chat daemon |
SIMPLEX_ALLOWED_USERS |
Recommended | Comma-separated allowlist. Each entry can be a numeric contactId or a display name — both forms work. |
SIMPLEX_ALLOW_ALL_USERS |
Optional | Set true to allow every contact (use carefully) |
SIMPLEX_AUTO_ACCEPT |
Optional | Auto-accept incoming contact requests (default: true) |
SIMPLEX_GROUP_ALLOWED |
Optional | Comma-separated group IDs the bot participates in, or * for any group. Omit to ignore group messages entirely |
SIMPLEX_HOME_CHANNEL |
Optional | Default contact/group ID for cron job delivery |
SIMPLEX_HOME_CHANNEL_NAME |
Optional | Human label for the home channel |
HERMES_SIMPLEX_TEXT_BATCH_DELAY |
Optional | Quiet-period seconds (default: 0.8) used to concatenate rapid-fire inbound text messages into one event |
Find your contact ID or display name
After starting the daemon, open a conversation with your agent contact. The numeric contactId appears in session logs or via hermes send_message action=list. If you'd rather use the display name shown in the SimpleX UI, that works too — SIMPLEX_ALLOWED_USERS accepts either form.
Authorization
By default all contacts are denied. You must either:
- Set
SIMPLEX_ALLOWED_USERSto a comma-separated list ofcontactIds and/or display names (e.g.SIMPLEX_ALLOWED_USERS=4,alicematches either contactId 4 or the contact whose display name is "alice"), or - Use DM pairing — send any message to the bot and it will reply with a pairing code. Enter that code via
hermes pairing approve simplex <CODE>.
Group chats
By default the adapter ignores group messages — a bot in a group otherwise processes every member's traffic. Opt-in explicitly:
SIMPLEX_GROUP_ALLOWED=12,34 # specific group IDs
# or
SIMPLEX_GROUP_ALLOWED=* # any group the bot is in
Address groups by prefixing the chat ID with group:, e.g.
simplex:group:12 in send_message or as a cron deliver= target.
Attachments
The adapter supports native SimpleX attachments in both directions:
- Inbound — incoming images, voice notes, and files are accepted via
the daemon's XFTP flow (
rcvFileDescrReady→/freceive→ wait forrcvFileComplete) and surfaced asMessageEvent.media_urlswith the appropriateMessageType(PHOTO,VOICE,TEXT+ document). - Outbound —
send_image_file,send_voice,send_document, andsend_videoall use the structured/_sendform withfilePath, so the receiving SimpleX client renders images inline and plays voice notes inline rather than offering them as downloads.
Agent replies can also embed MEDIA:/path/to/file tags in plain text —
the adapter strips the tag from the body and sends the file as either a
voice note (audio extensions) or a document.
Using SimpleX with cron jobs
cronjob(
action="create",
schedule="every 1h",
deliver="simplex", # uses SIMPLEX_HOME_CHANNEL
prompt="Check for alerts and summarise."
)
Or target a specific contact:
send_message(target="simplex:<contact-id>", message="Done!")
Privacy notes
- SimpleX never reveals phone numbers or email addresses — contacts use opaque IDs
- The connection between Hermes and the daemon is local WebSocket (
ws://127.0.0.1:5225) — no data leaves your machine - Messages are end-to-end encrypted by the SimpleX protocol before reaching the daemon
Troubleshooting
"Cannot reach daemon" — Ensure simplex-chat -p 5225 is running and the port matches SIMPLEX_WS_URL.
"websockets not installed" — Run pip install websockets.
Messages not received — Check that the contact's ID is in SIMPLEX_ALLOWED_USERS or approve them via DM pairing.