feat(cli): add hermes send to pipe script output to any messaging platform#19631
Closed
teknium1 wants to merge 1 commit into
Closed
feat(cli): add hermes send to pipe script output to any messaging platform#19631teknium1 wants to merge 1 commit into
hermes send to pipe script output to any messaging platform#19631teknium1 wants to merge 1 commit into
Conversation
…latform
Introduces a thin CLI wrapper around the existing send_message_tool so
shell scripts, cron scripts, CI hooks, and monitoring daemons can reuse
the gateway's already-configured platform credentials without
reimplementing each platform's REST client.
## What
hermes send --to telegram "deploy finished"
echo "RAM 92%" | hermes send --to telegram:-1001234567890
hermes send --to discord:#ops --file report.md
hermes send --to slack:#eng --subject "[CI]" --file build.log
hermes send --list # all targets
hermes send --list telegram # filter by platform
Supports all platforms the send_message tool already does (Telegram,
Discord, Slack, Signal, SMS, WhatsApp, Matrix, Feishu, DingTalk, WeCom,
Weixin, Email, etc.), including threaded targets and #channel-name
resolution via the channel directory.
## How
hermes_cli/send_cmd.py delegates to tools.send_message_tool.send_message_tool,
which means there is zero new platform-specific code. The subcommand just:
1. Bridges ~/.hermes/.env and top-level ~/.hermes/config.yaml scalars into
os.environ (same bootstrap the gateway does at startup) — required so
TELEGRAM_HOME_CHANNEL and friends are visible to load_gateway_config().
2. Resolves the message body from positional arg, --file, or piped stdin.
3. Calls the shared tool and translates its JSON result to exit codes:
0 success, 1 delivery failure, 2 usage error.
No running gateway is required for bot-token platforms (Telegram, Discord,
Slack, Signal, SMS, WhatsApp) — the tool hits each platform's REST API
directly. Plugin platforms that rely on a live adapter connection still
need the gateway running; the error message is forwarded verbatim.
## Docs
- New guide: website/docs/guides/pipe-script-output.md covering real-world
patterns (memory watchdogs, CI hooks, cron pipes, long-running task
completion pings) and the security/gateway notes.
- Cross-links added from automate-with-cron.md ("no LLM? use hermes send")
and developer-guide/gateway-internals.md (delivery-path section).
## Tests
tests/hermes_cli/test_send_cmd.py (20 tests, all green):
- Happy paths: positional message, stdin, --file, --file -, --subject,
--json, --quiet.
- Error paths: missing --to, missing body, file not found, tool returns
error payload (exit 1), tool skipped-send result (exit 0).
- --list: human output, --json output, platform filter, unknown platform.
- Env loader: bridges config.yaml scalars into env, does not override
existing env vars, gracefully handles missing files.
- Registrar contract: register_send_subparser() returns a working parser.
Smoke-tested end-to-end against a live Telegram bot before commit.
This was referenced May 4, 2026
15 tasks
Contributor
Author
|
Closing in favor of #27188, which salvages this PR onto current main. One docs conflict resolved by merging both 'no-agent cron' and 'hermes send' tips into a single 'two zero-token options' callout — recurring use cases go to cron, one-shot/external triggers go to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
hermes sendCLI subcommand that pipes text from shell scripts, cron scripts, CI hooks, and monitoring daemons to any messaging platform Hermes is already configured for. Zero new platform-specific code — it's a thin wrapper over the existingsend_message_tool.This scratches the "I want to ping myself from a bash script" itch without having to re-paste bot tokens into every watchdog or re-implement each platform's REST API.
Examples
Exit codes follow the classic Unix convention:
0ok,1delivery failure,2usage error.Design
hermes_cli/send_cmd.py— single file, ~300 LOC, delegates all real work totools.send_message_tool.send_message_tool. Supports every platform the tool already does: Telegram, Discord, Slack, Signal, SMS, WhatsApp, Matrix, Feishu, DingTalk, WeCom, Weixin, Email, etc.~/.hermes/.env+~/.hermes/config.yaml. Plugin platforms that rely on a live adapter connection still require the gateway to be running; their error message is forwarded verbatim.gateway/run.py's startup bridge:load_dotenv(~/.hermes/.env)plus bridging top-levelconfig.yamlscalars intoos.environ(without overriding existing env vars). Necessary becauseTELEGRAM_HOME_CHANNELand friends are read viaos.getenvby the gateway config loader and live in config.yaml when set viahermes config set.--file PATH(or--file -) > piped stdin. When stdin is a TTY with no pipe, the CLI emits a clean usage error instead of blocking on input.hermes_cli/main.pynext to the other messaging subcommands (slack, whatsapp).Docs
website/docs/guides/pipe-script-output.md— walks through the watchdog pattern, CI notifications, cron piping, and scripting with--json/--quiet. Includes a comparison table vs raw curl, cron delivery, and thesend_messageagent tool so people land on the right approach for their use case.automate-with-cron.md(tip box: "no LLM? usehermes send")developer-guide/gateway-internals.md(delivery-path section)Tests
tests/hermes_cli/test_send_cmd.py— 20 tests, all green:--file,--file -,--subject,--json,--quiet--to, missing body, file not found, tool returns error (exit 1), tool skipped-send (exit 0)--list: human,--json, platform filter, unknown platformSmoke-tested end-to-end against a live Telegram bot before commit — successfully delivered a message from a fresh shell invocation.
Compatibility
Test Plan
scripts/run_tests.sh tests/hermes_cli/test_send_cmd.pypasses (20/20)scripts/run_tests.sh tests/hermes_cli/test_send_cmd.py tests/gateway/test_config.pypasses (60/60)hermes send --helprenders cleanlyhermes send --listprints the shared channel directory