English | 简体中文 | 繁体中文 | 繁体中文香港 | Français
Hermes Lansenger Adapter
💠 Lansenger gateway adapter + media & message tools plugin for Hermes Agent.
Connects Hermes Agent to Lansenger — an enterprise messaging platform — via WebSocket long-connection for real-time message reception and HTTP API for message delivery.
This repo contains two plugins:
| Plugin | Kind | What it does |
|---|---|---|
platforms/lansenger/ |
platform | Gateway channel adapter — receive & send messages |
lansenger-tools/ |
standalone (tool) | Agent-callable tools: send messages/cards/files, revoke messages, query groups |
Features
Platform Adapter
- Real-time messaging via WebSocket long-connection (built-in ping/pong)
- Markdown support using
formatTextmsgType (with optional @mentions, newer API) - Approval cards — appCard / approveCard with dynamic in-place status updates after approval/rejection
- Home channel auto-detection — first p2p message sets the default delivery target
- Chat type persistence — inbound chat_id→group/dm map persisted for cross-process routing
- Cron delivery — scheduled notifications via
standalone_sender_fn - User authorization — allowed users / allow all users via env vars
- Zero core modification — pure plugin mode,
git diff HEADstays PRISTINE - Group chat policy — open/allowlist/disabled with per-group overrides (require_mention, allow_from sender filtering)
- Auto @mention reply — auto @sender in group replies using fromType (0=user→userIds, 1=bot→botIds)
- Auto quote reply — auto refMsgId referencing inbound message (groups + DMs)
- Multi-workspace support — respects HERMES_HOME; token/chat_type/owner files scoped per profile
- FormatText inbound — parses msgType=format Markdown from OpenClaw and other bots
Media & Message Tools Plugin
- lansenger_send_text — Send plain text with optional @mentions and attachments
- lansenger_send_markdown — Send Markdown-formatted text with optional @mentions (newer API, no attachments)
- lansenger_send_file — Send any local file/image/video to a specific user or group
- lansenger_send_image_url — Send an image from a URL to a specific user or group
- lansenger_revoke_message — Revoke a sent Lansenger message (auto-detects group/DM from chat_id)
- lansenger_send_link_card — Send a linkCard card message (6 required fields per spec)
- lansenger_send_app_articles — Send an appArticles multi-article card
- lansenger_send_app_card — Send an appCard rich card with optional dynamic updates
- lansenger_send_approve_card — Send an approveCard with clickable buttons for interactive workflows
- lansenger_update_dynamic_card — Update a dynamic appCard's status in-place
- lansenger_query_groups — Query the bot's group ID list
- lansenger_get_group_info — Get detailed group information (name, members, state)
- lansenger_get_group_members — Get the member list of a group with pagination
- lansenger_check_in_group — Check whether a staff or bot is in a group
- Auto media type detection — images/videos/documents classified by extension
- Credential gating — tools hidden when LANSENGER_APP_ID/SECRET not set
Quick Install
Via Hermes Plugin Manager (recommended)
hermes plugins install lansenger-pm/hermes-lansenger-adapter
hermes plugins enable hermes-lansenger-adapter
hermes gateway restart
Manual Install
Clone this repo into ~/.hermes/plugins/:
cd ~/.hermes/plugins/
git clone https://github.com/lansenger-pm/hermes-lansenger-adapter.git hermes-lansenger-adapter
hermes plugins enable hermes-lansenger-adapter
hermes gateway restart
Via pip (advanced)
pip install hermes-lansenger-adapter
hermes plugins enable hermes-lansenger-adapter
hermes gateway restart
Note: The bundle auto-expands on first gateway restart. Sub-plugins (
lansenger-platformandlansenger-tools) are automatically copied to~/.hermes/plugins/, auto-enabled inconfig.yaml, and loaded in-place — no need to run separatehermes plugins enablecommands for each sub-plugin.
Configuration
Required Environment Variables
Add these to ~/.hermes/.env:
| Variable | Description | Example |
|---|---|---|
LANSENGER_APP_ID |
Bot App ID | your-app-id |
LANSENGER_APP_SECRET |
Bot App Secret | your-app-secret |
LANSENGER_API_GATEWAY_URL |
API Gateway URL | https://your-api-gateway-url |
Credential path: Lansenger desktop → Contacts → Bots → Personal Bots → click the ℹ️ icon to view credentials (mobile client does not support viewing credentials)
Optional Environment Variables
| Variable | Description | Default |
|---|---|---|
LANSENGER_ALLOWED_USERS |
Allowed user IDs (comma-separated) | — |
LANSENGER_ALLOW_ALL_USERS |
Allow any user (dev only) | false |
LANSENGER_HOME_CHANNEL |
Default cron delivery chat ID | Auto-detected |
LANSENGER_HOOK_LOGGING |
Enable/disable hook logging | true |
config.yaml
Credentials can be configured via environment variables (recommended) or config.yaml. Environment variables take precedence.
platforms:
lansenger:
enabled: true
extra:
# Credentials (optional if set via env vars; env vars take precedence)
# app_id: "your-app-id"
# app_secret: "your-app-secret"
api_gateway_url: "https://your-api-gateway-url" # required
# Optional: disable hook logging (default: true)
# hook_logging: false
Media & Message Tools (from lansenger-tools)
These tools let the Agent send messages, files, images, cards, revoke messages, and query groups — all independently callable from the LLM. Credentials are read from env vars (LANSENGER_APP_ID/SECRET), not from load_gateway_config().
| Tool | Parameters | Description |
|---|---|---|
lansenger_send_text |
chat_id, content, reminder_all?, reminder_user_ids?, file_path?, media_type? |
Send plain text with optional @mentions and attachments |
lansenger_send_markdown |
chat_id, content, reminder_all?, reminder_user_ids? |
Send Markdown-formatted text with optional @mentions (newer API, no attachments) |
lansenger_send_file |
chat_id, file_path, caption?, media_type? |
Send a local file/image/video to a user or group |
lansenger_send_image_url |
chat_id, image_url, caption? |
Download image from URL and send as native image |
lansenger_revoke_message |
message_ids, chat_id? |
Revoke a sent message (pass chat_id; auto-detects group/DM) |
lansenger_send_link_card |
chat_id, title, link, description, icon_link, from_name, from_icon_link, pc_link? |
Send a linkCard (6 fields required per spec, pc_link optional) |
lansenger_send_app_articles |
chat_id, articles |
Send an appArticles multi-article card |
lansenger_send_app_card |
chat_id, body_title, head_title?, is_dynamic?, head_status_info?, ... |
Send an appCard rich card with optional dynamic updates |
lansenger_send_approve_card |
chat_id, head_title, body_title, body_content?, buttons, fields?, head_status?, head_status_color? |
Send an approveCard with clickable buttons |
lansenger_update_dynamic_card |
msg_id, head_status_info?, is_last_update? |
Update a dynamic appCard's status in-place |
lansenger_query_groups |
page_offset?, page_size? |
Query the bot's group ID list |
lansenger_get_group_info |
group_id |
Get detailed group information (name, members, state) |
lansenger_get_group_members |
group_id, page_offset?, page_size? |
Get a group's member list with pagination |
lansenger_check_in_group |
group_id, staff_id? |
Check whether a staff/bot is in a group |
lansenger_download_media |
media_id |
Download a media file by media_id (re-download files lost on restart) |
Usage examples (Agent prompts):
"Send the report.pdf to user 2285568-abc123"
"Share that chart image with the project group chat"
"Download this URL image and send it to my colleague"
"Revoke the message I just sent to the user"
"Send a link card with the title 'Project Documentation' and link https://..."
"Send an appCard approval card for the dangerous command"
"Update the approval card status to 'approved'"
Limitations:
- File size limits are determined by the organization's Lansenger configuration (no fixed cap)
- Media captions use plain text (no Markdown) — for Markdown text, send separately
lansenger_send_fileauto-detects media_type from extension if not specifiedlansenger_revoke_message: system message is fixed (not customizable)lansenger_send_link_card: 6 fields required per API spec (title, description, iconLink, link, fromName, fromIconLink); pc_link optionallansenger_send_markdown@mentions: newer API capability; older versions silently accept without triggering notification- Video (mediaType=1) requires 2 mediaIds: [videoId, coverImageId] (upload video and cover image separately, then combine)
Architecture
hermes plugins install → clone to ~/.hermes/plugins/hermes-lansenger-adapter/
├── plugin.yaml # root manifest (kind: bundle)
├── platforms/lansenger/ # Gateway adapter
│ ├── plugin.yaml # manifest (kind: platform)
│ ├── __init__.py # register() → ctx.register_platform()
│ ├── adapter.py # core adapter (multi-inheritance from Mixin modules)
│ ├── commands.py # slash command registration
│ └── _*.py / ws_*.py # modular Mixin files (WS, messages, token, media, groups, cards, approval, i18n)
├── lansenger-tools/ # Media & message tools
│ ├── plugin.yaml # manifest (kind: standalone)
│ ├── __init__.py # register() → ctx.register_tool()
│ ├── schemas.py # LLM-facing tool descriptions
│ └── tools.py # handler implementations
├── skills/ # Agent decision-making skill
│ └── lansenger-messaging/ # skill directory (SKILL.md + references/)
├── README.md
├── LICENSE
├── VERSION
├── after-install.md
├── pyproject.toml # pip entry-point
└── .gitignore
Dependencies
websockets— WebSocket client for long-connectionhttpx— HTTP client for API calls (also used by media tools)
Upgrade
To update to the latest version:
hermes plugins update hermes-lansenger-adapter
hermes gateway restart
Changelog
See CHANGELOG.md for detailed version history.
License
MIT — see LICENSE.
Metadata
Release files for hermes-lansenger-adapter 2.9.17
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hermes_lansenger_adapter-2.9.17.tar.gz | 80.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hermes_lansenger_adapter-2.9.17-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 151.5 kB
Release files / hermes_lansenger_adapter-2.9.17.tar.gz
| Download URL | hermes_lansenger_adapter-2.9.17.tar.gz |
|---|---|
| Size | 80.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f105f81ba943e69ca9775ffb733edb45d9583ee0ec7d63b4f42d7f58b4b95d5
|
|
BLAKE2b-256 checksum How to use checksums |
477446ec9ae78d79ceb39f6004f0215eb447554edf84e503432435e156d5c6b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / hermes_lansenger_adapter-2.9.17-py3-none-any.whl
| Download URL | hermes_lansenger_adapter-2.9.17-py3-none-any.whl |
|---|---|
| Size | 71.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fcd6789e1bc08f179bb2fa1fb6fc73da9c8441105fcfe2ccf9f8b5601d3dd8bb
|
|
BLAKE2b-256 checksum How to use checksums |
e93745a7d17b872ba4b5bda99836b0578ea0c0a515626c0f9e0637efb25dc64b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Security for hermes-lansenger-adapter 2.9.17
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.