Skip to content

Conversation

@tintinthong
Copy link
Contributor

@tintinthong tintinthong commented Jan 13, 2026

PR Webhook Events from Github -> Matrix Events inside a room

Summary of Changes

  • Added a submissions endpoint to handle GitHub webhooks.
  • Transforms webhook events into Matrix events.
  • Sends Matrix events to the room derived from branch naming.

GitHub Webhook Events to Matrix Events

  • Current webhook handler only accepts pull_request and pull_request_review.
  • Webhook handling posts a Matrix event using the derived room id.
Webhook event Action / state Matrix event type Example Matrix status/message
pull_request opened app.boxel.pr PR opened
pull_request closed + merged=false app.boxel.pr PR closed (not merged)
pull_request closed + merged=true app.boxel.pr PR merged
pull_request_review submitted + state=approved app.boxel.pr-review PR review approved
pull_request_review submitted + state=changes_requested app.boxel.pr-review PR review rejected

Branch Naming and Room Mapping

  • Branch names are expected to include a Matrix room id prefix so webhook events can be routed to a room.
  • The prefix is room- and is followed by a base64url-encoded Matrix room id.
  • Branch names can include a suffix after the room id segment (for example, room-<encoded>/feature-name).
  • Listing names are normalized to kebab-case when generating a branch name.
  • If the prefix or encoding is invalid, the room id cannot be derived and the webhook will not map to a room.

Example:

  • Room id: !FEdiqYthEnvYNuBigm:boxel.ai
  • Listing name: SomeSampleListing
  • Encoded room id segment: room-IUZFZGlxWXRoRW52WU51QmlnbTpib3hlbC5haQ
  • Branch name: room-IUZFZGlxWXRoRW52WU51QmlnbTpib3hlbC5haQ/some-sample-listing
flowchart LR
  A["roomId: !FEdiqYthEnvYNuBigm:boxel.ai 
  listingName: SomeSampleListing"] -->|toBranchName| B["branch: room-IUZFZGlxWXRoRW52WU51QmlnbTpib3hlbC5haQ/some-sample-listing"]
  B -->|branchNameToMatrixRoomId| C["roomId: !FEdiqYthEnvYNuBigm:boxel.ai"]
Loading

Testing catalog submissions locally

  • Example with hardcoded values:
    RESOLVED_CATALOG_REALM_URL="https://82610557c687.ngrok-free.app/catalog/" \
    CATALOG_WEBHOOK_SECRET=some-secret \
    CATALOG_ENV=testing \
    USE_EXTERNAL_CATALOG=1 \
    pnpm start:all
  • Start ngrok on the realm server port (default 4201): ngrok http 4201
  • Validate ngrok is set up with the realm server:
    curl --location '<RESOLVED_CATALOG_REALM_URL>_readiness-check' \
    --header 'Accept: application/vnd.api+json'
  • Configure the GitHub webhook URL
    • Payload URL = <RESOLVED_CATALOG_REALM_URL>/submissions
    • Secret = <CATALOG_WEBHOOK_SECRET>
    • Content-type = application/json

@github-actions
Copy link

Preview deployments

@github-actions
Copy link

github-actions bot commented Jan 13, 2026

Host Test Results

    1 files  ±  0      1 suites  ±0   1h 40m 53s ⏱️ + 9m 28s
1 877 tests +220  1 862 ✅ +222  15 💤 ±0  0 ❌  - 1 
1 892 runs  +221  1 877 ✅ +224  15 💤 ±0  0 ❌  - 2 

Results for commit 9386001. ± Comparison against base commit e19775a.

This pull request removes 1 and adds 221 tests. Note that renamed tests count towards both.
Chrome ‑ Global error: Uncaught TypeError: Failed to fetch at http://localhost:7357/assets/chunk.a21cf6bdda5429279545.js, line 153748  While executing test: Integration | card-copy: copy button does not appear when right and left stacks are the same index item and there is a selection on one side 
Chrome ‑ Integration | Store: added instance that was previously not saved will begin to auto save after being added
Chrome ‑ Integration | Store: an instance can be restored after a loader reset
Chrome ‑ Integration | Store: an instance can debounce auto saves
Chrome ‑ Integration | Store: an instance can live update thru an error state
Chrome ‑ Integration | Store: an instance live updates from indexing events for a code update
Chrome ‑ Integration | Store: an instance live updates from indexing events for an instance update
Chrome ‑ Integration | Store: an instance that started out with a local ID can be restored after a loader reset
Chrome ‑ Integration | Store: an instance will NOT auto save when its data changes, if the user does not have write permissions
Chrome ‑ Integration | Store: an instance will auto save when its data changes
Chrome ‑ Integration | Store: an unsaved instance live updates when realm event matching local ID is received
…

♻️ This comment has been updated with latest results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants