mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-03 02:11:48 +00:00
feat: add Mattermost and Matrix gateway adapters
Add support for Mattermost (self-hosted Slack alternative) and Matrix (federated messaging protocol) as messaging platforms. Mattermost adapter: - REST API v4 client for posts, files, channels, typing indicators - WebSocket listener for real-time 'posted' events with reconnect backoff - Thread support via root_id - File upload/download with auth-aware caching - Dedup cache (5min TTL, 2000 entries) - Full self-hosted instance support Matrix adapter: - matrix-nio AsyncClient with sync loop - Dual auth: access token or user_id + password - Optional E2EE via matrix-nio[e2e] (libolm) - Thread support via m.thread (MSC3440) - Reply support via m.in_reply_to with fallback stripping - Media upload/download via mxc:// URLs (authenticated v1.11+ endpoint) - Auto-join on room invite - DM detection via m.direct account data with sync fallback - Markdown to HTML conversion Fixes applied over original PR #1225 by @cyb0rgk1tty: - Mattermost: add timeout to file downloads, wrap API helpers in try/except for network errors, download incoming files immediately with auth headers instead of passing auth-required URLs - Matrix: use authenticated media endpoint (/_matrix/client/v1/media/), robust m.direct cache with sync fallback, prefer aiohttp over httpx Install Matrix support: pip install 'hermes-agent[matrix]' Mattermost needs no extra deps (uses aiohttp). Salvaged from PR #1225 by @cyb0rgk1tty with fixes.
This commit is contained in:
parent
07549c967a
commit
cd67f60e01
7 changed files with 1758 additions and 0 deletions
|
|
@ -2518,6 +2518,119 @@ def setup_gateway(config: dict):
|
|||
" Set SLACK_ALLOW_ALL_USERS=true or GATEWAY_ALLOW_ALL_USERS=true only if you intentionally want open workspace access."
|
||||
)
|
||||
|
||||
# ── Matrix ──
|
||||
existing_matrix = get_env_value("MATRIX_ACCESS_TOKEN") or get_env_value("MATRIX_PASSWORD")
|
||||
if existing_matrix:
|
||||
print_info("Matrix: already configured")
|
||||
if prompt_yes_no("Reconfigure Matrix?", False):
|
||||
existing_matrix = None
|
||||
|
||||
if not existing_matrix and prompt_yes_no("Set up Matrix?", False):
|
||||
print_info("Works with any Matrix homeserver (Synapse, Conduit, Dendrite, or matrix.org).")
|
||||
print_info(" 1. Create a bot user on your homeserver, or use your own account")
|
||||
print_info(" 2. Get an access token from Element, or provide user ID + password")
|
||||
print()
|
||||
homeserver = prompt("Homeserver URL (e.g. https://matrix.example.org)")
|
||||
if homeserver:
|
||||
save_env_value("MATRIX_HOMESERVER", homeserver.rstrip("/"))
|
||||
|
||||
print()
|
||||
print_info("Auth: provide an access token (recommended), or user ID + password.")
|
||||
token = prompt("Access token (leave empty for password login)", password=True)
|
||||
if token:
|
||||
save_env_value("MATRIX_ACCESS_TOKEN", token)
|
||||
user_id = prompt("User ID (@bot:server — optional, will be auto-detected)")
|
||||
if user_id:
|
||||
save_env_value("MATRIX_USER_ID", user_id)
|
||||
print_success("Matrix access token saved")
|
||||
else:
|
||||
user_id = prompt("User ID (@bot:server)")
|
||||
if user_id:
|
||||
save_env_value("MATRIX_USER_ID", user_id)
|
||||
password = prompt("Password", password=True)
|
||||
if password:
|
||||
save_env_value("MATRIX_PASSWORD", password)
|
||||
print_success("Matrix credentials saved")
|
||||
|
||||
if token or get_env_value("MATRIX_PASSWORD"):
|
||||
# E2EE
|
||||
print()
|
||||
if prompt_yes_no("Enable end-to-end encryption (E2EE)?", False):
|
||||
save_env_value("MATRIX_ENCRYPTION", "true")
|
||||
print_success("E2EE enabled")
|
||||
print_info(" Requires: pip install 'matrix-nio[e2e]'")
|
||||
|
||||
# Allowed users
|
||||
print()
|
||||
print_info("🔒 Security: Restrict who can use your bot")
|
||||
print_info(" Matrix user IDs look like @username:server")
|
||||
print()
|
||||
allowed_users = prompt(
|
||||
"Allowed user IDs (comma-separated, leave empty for open access)"
|
||||
)
|
||||
if allowed_users:
|
||||
save_env_value("MATRIX_ALLOWED_USERS", allowed_users.replace(" ", ""))
|
||||
print_success("Matrix allowlist configured")
|
||||
else:
|
||||
print_info(
|
||||
"⚠️ No allowlist set - anyone who can message the bot can use it!"
|
||||
)
|
||||
|
||||
# Home room
|
||||
print()
|
||||
print_info("📬 Home Room: where Hermes delivers cron job results and notifications.")
|
||||
print_info(" Room IDs look like !abc123:server (shown in Element room settings)")
|
||||
print_info(" You can also set this later by typing /set-home in a Matrix room.")
|
||||
home_room = prompt("Home room ID (leave empty to set later with /set-home)")
|
||||
if home_room:
|
||||
save_env_value("MATRIX_HOME_ROOM", home_room)
|
||||
|
||||
# ── Mattermost ──
|
||||
existing_mattermost = get_env_value("MATTERMOST_TOKEN")
|
||||
if existing_mattermost:
|
||||
print_info("Mattermost: already configured")
|
||||
if prompt_yes_no("Reconfigure Mattermost?", False):
|
||||
existing_mattermost = None
|
||||
|
||||
if not existing_mattermost and prompt_yes_no("Set up Mattermost?", False):
|
||||
print_info("Works with any self-hosted Mattermost instance.")
|
||||
print_info(" 1. In Mattermost: Integrations → Bot Accounts → Add Bot Account")
|
||||
print_info(" 2. Copy the bot token")
|
||||
print()
|
||||
mm_url = prompt("Mattermost server URL (e.g. https://mm.example.com)")
|
||||
if mm_url:
|
||||
save_env_value("MATTERMOST_URL", mm_url.rstrip("/"))
|
||||
token = prompt("Bot token", password=True)
|
||||
if token:
|
||||
save_env_value("MATTERMOST_TOKEN", token)
|
||||
print_success("Mattermost token saved")
|
||||
|
||||
# Allowed users
|
||||
print()
|
||||
print_info("🔒 Security: Restrict who can use your bot")
|
||||
print_info(" To find your user ID: click your avatar → Profile")
|
||||
print_info(" or use the API: GET /api/v4/users/me")
|
||||
print()
|
||||
allowed_users = prompt(
|
||||
"Allowed user IDs (comma-separated, leave empty for open access)"
|
||||
)
|
||||
if allowed_users:
|
||||
save_env_value("MATTERMOST_ALLOWED_USERS", allowed_users.replace(" ", ""))
|
||||
print_success("Mattermost allowlist configured")
|
||||
else:
|
||||
print_info(
|
||||
"⚠️ No allowlist set - anyone who can message the bot can use it!"
|
||||
)
|
||||
|
||||
# Home channel
|
||||
print()
|
||||
print_info("📬 Home Channel: where Hermes delivers cron job results and notifications.")
|
||||
print_info(" To get a channel ID: click channel name → View Info → copy the ID")
|
||||
print_info(" You can also set this later by typing /set-home in a Mattermost channel.")
|
||||
home_channel = prompt("Home channel ID (leave empty to set later with /set-home)")
|
||||
if home_channel:
|
||||
save_env_value("MATTERMOST_HOME_CHANNEL", home_channel)
|
||||
|
||||
# ── WhatsApp ──
|
||||
existing_whatsapp = get_env_value("WHATSAPP_ENABLED")
|
||||
if not existing_whatsapp and prompt_yes_no("Set up WhatsApp?", False):
|
||||
|
|
@ -2535,6 +2648,9 @@ def setup_gateway(config: dict):
|
|||
get_env_value("TELEGRAM_BOT_TOKEN")
|
||||
or get_env_value("DISCORD_BOT_TOKEN")
|
||||
or get_env_value("SLACK_BOT_TOKEN")
|
||||
or get_env_value("MATTERMOST_TOKEN")
|
||||
or get_env_value("MATRIX_ACCESS_TOKEN")
|
||||
or get_env_value("MATRIX_PASSWORD")
|
||||
or get_env_value("WHATSAPP_ENABLED")
|
||||
)
|
||||
if any_messaging:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue