diff --git a/plugins/platforms/photon/adapter.py b/plugins/platforms/photon/adapter.py index 0747ab7db3e..30448da3a03 100644 --- a/plugins/platforms/photon/adapter.py +++ b/plugins/platforms/photon/adapter.py @@ -696,6 +696,10 @@ async def _standalone_send( def register(ctx) -> None: """Called by the Hermes plugin loader at startup.""" + # Local import to avoid argparse work at module load; reused for both the + # gateway-setup hook and the `hermes photon` CLI command below. + from . import cli as _cli + ctx.register_platform( name="photon", label="Photon iMessage", @@ -709,6 +713,9 @@ def register(ctx) -> None: "Spectrum project, links your phone number, installs the " "spectrum-ts sidecar)." ), + # Surfaces Photon in `hermes gateway setup` alongside every other + # channel β€” same unified onboarding wizard, no Photon-only detour. + setup_fn=_cli.gateway_setup, env_enablement_fn=_env_enablement, cron_deliver_env_var="PHOTON_HOME_CHANNEL", standalone_sender_fn=_standalone_send, @@ -717,8 +724,9 @@ def register(ctx) -> None: max_message_length=_MAX_MESSAGE_LENGTH, emoji="πŸ“±", # iMessage carries E.164 phone numbers β€” treat session descriptions - # as PII-sensitive so they get redacted in logs. - pii_safe=False, + # as PII-sensitive so they get redacted before reaching the LLM + # (matches the BlueBubbles iMessage channel in _PII_SAFE_PLATFORMS). + pii_safe=True, allow_update_command=True, platform_hint=( "You are communicating via Photon Spectrum (iMessage). " @@ -730,8 +738,6 @@ def register(ctx) -> None: ) # Register CLI subcommands β€” `hermes photon ...` - from . import cli as _cli # local import to avoid argparse at module load - ctx.register_cli_command( name="photon", help="Set up and manage the Photon iMessage integration", diff --git a/plugins/platforms/photon/cli.py b/plugins/platforms/photon/cli.py index 1316ace252b..615ed9db14a 100644 --- a/plugins/platforms/photon/cli.py +++ b/plugins/platforms/photon/cli.py @@ -300,6 +300,31 @@ def _cmd_webhook(args: argparse.Namespace) -> int: return 2 +# --------------------------------------------------------------------------- +# Gateway-setup entry point +# +# `hermes gateway setup` discovers platforms via the registry and calls each +# entry's zero-arg ``setup_fn``. Photon registers this function so it appears +# in the unified setup wizard alongside every other channel β€” same onboarding +# surface, no Photon-specific detour. It runs the identical device-login + +# project + user + sidecar flow as ``hermes photon setup`` with interactive +# defaults (phone is prompted when stdin is a TTY). + +def gateway_setup() -> None: + """Run Photon first-time setup from the `hermes gateway setup` wizard.""" + args = argparse.Namespace( + photon_command="setup", + project_name=None, + phone=None, + first_name=None, + last_name=None, + email=None, + no_browser=False, + skip_sidecar_install=False, + ) + _cmd_setup(args) + + # --------------------------------------------------------------------------- # Small interactive helpers diff --git a/website/docs/user-guide/messaging/photon.md b/website/docs/user-guide/messaging/photon.md index feb373618b4..41f4b54aa76 100644 --- a/website/docs/user-guide/messaging/photon.md +++ b/website/docs/user-guide/messaging/photon.md @@ -45,12 +45,20 @@ endpoint we'll retire the sidecar in a follow-up release. ## First-time setup +Either run the unified gateway wizard and pick **Photon iMessage**: + +```bash +hermes gateway setup +``` + +…or run the Photon setup directly (the wizard calls the same flow): + ```bash # Device-code login + project + user + sidecar deps, all in one hermes photon setup --phone +15551234567 ``` -The wizard: +The setup: 1. Opens `https://app.photon.codes/` for device approval 2. Creates a Spectrum-enabled project under your account @@ -62,6 +70,36 @@ Credentials are stored in `~/.hermes/auth.json` under `credential_pool.photon` (bearer token) and `credential_pool.photon_project` (project id + secret). +## Authorizing users + +Photon uses the same authorization model as every other Hermes +channel. Choose one approach: + +**DM pairing (default).** When an unknown number messages your Photon +line, Hermes replies with a pairing code. Approve it with: + +```bash +hermes pairing approve photon +``` + +Use `hermes pairing list` to see pending codes and approved users. + +**Pre-authorize specific numbers** (in `~/.hermes/.env`): + +```bash +PHOTON_ALLOWED_USERS=+15551234567,+15559876543 +``` + +**Open access** (dev only, in `~/.hermes/.env`): + +```bash +PHOTON_ALLOW_ALL_USERS=true +``` + +When `PHOTON_ALLOWED_USERS` is set, unknown senders are silently +ignored rather than offered a pairing code (the allowlist signals you +deliberately restricted access). + ## Registering the webhook Photon needs a public URL it can POST to. Expose your local listener @@ -109,17 +147,17 @@ Photon iMessage status ────────────────────── device token : βœ“ stored project id : 3c90c3cc-0d44-4b50-... - project secret : βœ“ stored + project key : βœ“ stored + webhook key : βœ“ set node binary : /usr/bin/node sidecar deps : βœ“ installed - webhook secret : βœ“ set ``` Common issues: - **`sidecar deps : βœ— run hermes photon install-sidecar`** β€” Node is installed but `spectrum-ts` isn't. Run the suggested command. -- **`webhook secret : ⚠ unset β€” verification disabled`** β€” the +- **`webhook key : ⚠ unset β€” verification disabled`** β€” the plugin will accept ANY POST to the webhook URL, which is unsafe. Re-run `hermes photon webhook register` and store the secret. - **`PHOTON_WEBHOOK_PORT` already in use** β€” set a different port via @@ -160,8 +198,11 @@ hermes photon webhook delete # remove one | `PHOTON_SIDECAR_AUTOSTART`| `true` | Whether the adapter spawns the sidecar | | `PHOTON_NODE_BIN` | `which node` | Override the Node binary path | | `PHOTON_HOME_CHANNEL` | (unset) | Default space ID for cron / notifications | +| `PHOTON_HOME_CHANNEL_NAME`| (unset) | Human label for the home channel | | `PHOTON_ALLOWED_USERS` | (unset) | Comma-separated E.164 allowlist | | `PHOTON_ALLOW_ALL_USERS` | `false` | Dev only β€” accept any sender | +| `PHOTON_API_HOST` | `spectrum.photon.codes` | Override the Spectrum management API host | +| `PHOTON_DASHBOARD_HOST` | `app.photon.codes` | Override the dashboard / device-login host | [photon]: https://photon.codes/ [app]: https://app.photon.codes/