matrix-hookshot on the web VM: inbound webhook bridge for reptide feedback channel #324

Open
opened 2026-08-10 23:13:22 +02:00 by dominik.polakovics · 0 comments

Reptide's feedback flow (Postgres trigger → forward-feedback edge function → Matrix room, see reptide MANUAL_SETUP.md §8 and supabase/functions/forward-feedback/) needs an inbound-webhook bridge on our Matrix homeserver. The function POSTs {"text": "..."} to a MATRIX_WEBHOOK_URL; that payload is natively understood by matrix-hookshot generic webhooks. We run Synapse + MAS + four mautrix appservice bridges on the fw web VM (hosts/fw/vms/web/matrix.nix) but no webhook bridge. services.matrix-hookshot (hookshot.nix) is available on our channel (nixos-26.05) — verified.

⚠️ Manual steps FIRST (operator, before implementation)

  1. Generate the two hookshot appservice tokens:
    openssl rand -hex 32   # run twice
    
  2. Add them to the web VM's secrets file via sops under these keys:
    nix-shell -p sops --run 'sops hosts/fw/vms/web/secrets.sops.yaml'
    # add:
    #   hookshot-as-token: <first token>
    #   hookshot-hs-token: <second token>
    
  3. Then flip this issue's label from ready-for-human to ready-for-agent — everything below is agent-implementable.

Agent implementation (after label flip)

New module hosts/fw/vms/web/hookshot.nix, imported from the web VM config:

  • services.matrix-hookshot with an appservice registration built from the two sops tokens (follow the existing runtime-rendered registration pattern used for double-puppet in matrix.nix — secrets land via /run, not the store); sender_localpart e.g. hookshot.
  • Register with Synapse via services.matrix-synapse.settings.app_service_config_files.
  • Enable generic webhooks only (generic.enabled); GitHub/GitLab/Jira/feeds stay off.
  • nginx: expose only the inbound-webhook path on the existing matrix.cloonar.com vhost (e.g. location /webhook/ → hookshot's webhook listener on localhost); public because Supabase's egress must reach it. The webhook URL itself is the secret capability — same trust model as the Loki push credential (#323).
  • Verify: hookshot bot user exists on the homeserver, service healthy, webhook path reachable over HTTPS, everything else on hookshot's listener not exposed.

Manual steps AFTER deploy (operator)

  1. Create the feedback room, invite the hookshot bot, and set up a generic webhook for the room via the bot's admin room → yields the webhook URL (https://matrix.cloonar.com/webhook/<id>).
  2. Reptide side, per its MANUAL_SETUP.md:
    supabase secrets set MATRIX_WEBHOOK_URL="<url>" FORWARD_FEEDBACK_TOKEN="<token>" --project-ref majxbigjafpzayzboxsf
    supabase functions deploy forward-feedback --no-verify-jwt --project-ref majxbigjafpzayzboxsf
    
  3. End-to-end: insert/submit a feedback row → message appears in the room (markdown: quoted body + footer).

Out of scope (noted for later)

Once hookshot exists, the reptide crash-signal alert (#323, currently Pushover) could optionally gain a Matrix contact point via Grafana webhook → hookshot generic webhook with a small JS transformation. Separate decision, not part of this issue.

Reptide's feedback flow (Postgres trigger → `forward-feedback` edge function → Matrix room, see reptide `MANUAL_SETUP.md` §8 and `supabase/functions/forward-feedback/`) needs an inbound-webhook bridge on our Matrix homeserver. The function POSTs `{"text": "..."}` to a `MATRIX_WEBHOOK_URL`; that payload is natively understood by **matrix-hookshot** generic webhooks. We run Synapse + MAS + four mautrix appservice bridges on the fw web VM (`hosts/fw/vms/web/matrix.nix`) but no webhook bridge. `services.matrix-hookshot` (`hookshot.nix`) is available on our channel (nixos-26.05) — verified. ## ⚠️ Manual steps FIRST (operator, before implementation) 1. Generate the two hookshot appservice tokens: ```bash openssl rand -hex 32 # run twice ``` 2. Add them to the web VM's secrets file via sops under these keys: ```bash nix-shell -p sops --run 'sops hosts/fw/vms/web/secrets.sops.yaml' # add: # hookshot-as-token: <first token> # hookshot-hs-token: <second token> ``` 3. **Then flip this issue's label from `ready-for-human` to `ready-for-agent`** — everything below is agent-implementable. ## Agent implementation (after label flip) New module `hosts/fw/vms/web/hookshot.nix`, imported from the web VM config: - `services.matrix-hookshot` with an appservice registration built from the two sops tokens (follow the existing runtime-rendered registration pattern used for double-puppet in `matrix.nix` — secrets land via `/run`, not the store); `sender_localpart` e.g. `hookshot`. - Register with Synapse via `services.matrix-synapse.settings.app_service_config_files`. - Enable **generic webhooks** only (`generic.enabled`); GitHub/GitLab/Jira/feeds stay off. - nginx: expose only the inbound-webhook path on the existing `matrix.cloonar.com` vhost (e.g. `location /webhook/` → hookshot's webhook listener on localhost); public because Supabase's egress must reach it. The webhook URL itself is the secret capability — same trust model as the Loki push credential (#323). - Verify: hookshot bot user exists on the homeserver, service healthy, webhook path reachable over HTTPS, everything else on hookshot's listener not exposed. ## Manual steps AFTER deploy (operator) 1. Create the feedback room, invite the hookshot bot, and set up a generic webhook for the room via the bot's admin room → yields the webhook URL (`https://matrix.cloonar.com/webhook/<id>`). 2. Reptide side, per its `MANUAL_SETUP.md`: ```bash supabase secrets set MATRIX_WEBHOOK_URL="<url>" FORWARD_FEEDBACK_TOKEN="<token>" --project-ref majxbigjafpzayzboxsf supabase functions deploy forward-feedback --no-verify-jwt --project-ref majxbigjafpzayzboxsf ``` 3. End-to-end: insert/submit a feedback row → message appears in the room (markdown: quoted body + footer). ## Out of scope (noted for later) Once hookshot exists, the reptide crash-signal alert (#323, currently Pushover) could optionally gain a Matrix contact point via Grafana webhook → hookshot generic webhook with a small JS transformation. Separate decision, not part of this issue.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/nixos#324
No description provided.