# Hookshot Outbound Webhook Payload Discovery # Generated: 2026-04-09 (Phase 6.0, Question 4) # # NOTE: Hookshot is BLOCKED for this use case (E2EE + MAS incompatibility). # This file documents the payload shape for completeness and future reference. ## Outbound Webhook Config Enable in hookshot config.yml: ```yaml generic: outbound: true ``` ## HTTP Method and Content-Type - **Method:** PUT (default) or POST (configurable per-connection) - **Content-Type:** multipart/form-data - **Two parts:** 1. `event` file: Raw Matrix event JSON 2. `media` file (optional): Attached media if the event references it ## Headers | Header | Description | |--------|-------------| | X-Matrix-Hookshot-EventId | Matrix event ID | | X-Matrix-Hookshot-RoomId | Room ID | | X-Matrix-Hookshot-Token | Per-webhook auth token (for receiver verification) | ## Event Type Coverage ALL events in the room are forwarded. Specifically: | Event Type | Forwarded? | Notes | |------------|-----------|-------| | m.room.message | Yes | Normal messages | | m.room.redaction | Yes | Deletions | | m.room.message with m.relates_to/m.replace | Yes | Edits (m.new_content present) | | m.room.message with m.relates_to/m.in_reply_to | Yes | Replies | | m.reaction | Yes | Reactions | | m.room.member | Yes | Joins/leaves/invites | | State events | Yes | All state changes | The docs state: "All events that occur in the room will be sent to the outbound URL, so be careful to ensure your remote service can filter the traffic appropriately." ## Encrypted Room Behavior IF encryption is working (which it's NOT with MAS — see hookshot_e2ee_discovery.ref): - The `event` payload contains DECRYPTED plaintext content - The receiver sees the same JSON as an unencrypted room IF encryption is NOT working: - The `event` payload contains the encrypted blob (m.room.encrypted type) - Content is unusable ciphertext ## Sample Payload (from docs/source) ```json { "type": "m.room.message", "sender": "@signal_abc123:echo6.co", "event_id": "$abc123:echo6.co", "room_id": "!XUeWZuPdWQQnUYLJBJ:echo6.co", "origin_server_ts": 1775773462151, "content": { "msgtype": "m.text", "body": "Hello from Signal" }, "unsigned": { "age": 42 } } ``` Edit event example: ```json { "type": "m.room.message", "sender": "@signal_abc123:echo6.co", "event_id": "$edit123:echo6.co", "room_id": "!XUeWZuPdWQQnUYLJBJ:echo6.co", "origin_server_ts": 1775773462200, "content": { "msgtype": "m.text", "body": "* Hello from Signal (edited)", "m.new_content": { "msgtype": "m.text", "body": "Hello from Signal (edited)" }, "m.relates_to": { "rel_type": "m.replace", "event_id": "$abc123:echo6.co" } } } ``` ## Filtering No built-in filtering. The receiver must filter by `type` field. Hookshot sends everything — the receiver decides what to keep. ## Retry Behavior Failed deliveries are retried up to 5 times with increasing delays. ## Source - https://matrix-org.github.io/matrix-hookshot/latest/setup/webhooks.html - https://github.com/matrix-org/matrix-hookshot/blob/main/docs/setup/webhooks.md - https://github.com/matrix-org/matrix-hookshot/pull/945