Imported from D3codes/WebhookListenerExtension (
AGENTS.md). Install upstream withnpx skills add D3codes/WebhookListenerExtension. Copyright stays with the author.
AGENTS.md
Project Summary
Postback Watcher is a Chrome/Edge Manifest V3 browser extension for monitoring HTTP postbacks sent to a webhook endpoint. It opens as a browser side panel, creates or connects to a Webhook.site endpoint, polls for received requests, and lets the user inspect request body, headers, query parameters, and raw request metadata.
The extension is intentionally lightweight:
- No build step.
- No package manager.
- No local server.
- No paid backend requirement.
- All extension code is plain HTML, CSS, and JavaScript.
User Goal
The user wants a free-to-use browser extension for watching postbacks as they arrive. The extension should make it easy to:
- Create a free webhook endpoint.
- Connect an existing Webhook.site endpoint.
- Hide setup once connected, showing only the monitoring UI.
- Copy the endpoint URL.
- Send a test postback.
- Watch incoming postbacks refresh automatically.
- Click a received postback and inspect its body.
- Use settings to change the endpoint later.
Current Backend Choice
The current implementation uses the public Webhook.site API.
Relevant endpoints:
POST https://webhook.site/token- Creates a free webhook token.
GET https://webhook.site/token/{tokenId}/requests- Lists captured requests for the token.
GET https://webhook.site/token/{tokenId}/request/{requestId}- Fetches detail for one captured request.
DELETE https://webhook.site/token/{tokenId}/request- Clears captured requests for the token.
Important constraints:
- Free Webhook.site URLs can expire.
- Free Webhook.site URLs can have a request cap.
- Payloads are stored by Webhook.site while the token is active.
- Do not treat this as a secure production secret store.
- If the backend is changed later, preserve the free/no-account path unless the user explicitly chooses otherwise.
File Layout
manifest.json
Defines the Manifest V3 extension.
Important fields:
permissionsclipboardWrite: copy endpoint/body text.sidePanel: show the extension in the Chrome/Edge side panel.storage: persist token and settings.
host_permissionshttps://webhook.site/*: allow API calls and test postbacks.
icons- Uses generated square PNG assets in
icons/.
- Uses generated square PNG assets in
action.default_icon- Uses the same generated PNG assets for toolbar/browser action surfaces.
background.service_workerbackground.js.
side_panel.default_pathpanel.html.
icon.png and icons/
icon.png is the source icon supplied by the user. The browser-facing icon assets are generated from it into icons/.
Current generated sizes:
icons/icon-16.pngicons/icon-32.pngicons/icon-48.pngicons/icon-128.png
The source image is not square, so the generated assets are transparent-padded square PNGs rather than cropped images.
background.js
Small service worker that configures side panel behavior.
What it does:
- On install, calls
chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true })when available. - On toolbar icon click, tries to open the side panel.
- Falls back to opening
panel.htmlas a normal extension tab if the side panel API is unavailable.
Keep this file simple. The live monitoring logic belongs in panel.js.
panel.html
Defines the UI structure.
Main UI sections:
- Top bar with title, status text, and settings gear.
settingsPanel: small settings panel for the current endpoint and changing endpoints.setupView: create/connect webhook form.monitorView: active monitoring UI after an endpoint is connected.- Endpoint bar: copy endpoint and send test postback.
- Toolbar: search, refresh interval, manual refresh, pause/resume.
- Request list: captured postbacks.
- Details area: selected request body, headers, query, and raw tabs.
The setup screen should be hidden once a token is active.
panel.css
Styles the side panel UI.
Important patterns:
[hidden] { display: none !important; }is required so setup/settings/monitor sections hide reliably.- Layout is responsive for narrow side-panel widths.
- Request rows are buttons, making them keyboard-focusable and clickable.
.request-actiongives each row a visible "View body" affordance.- Avoid large decorative layouts; this is an operational debugging tool.
panel.js
Main application logic.
Key state:
state.token- Current Webhook.site token and URL.
state.requests- Latest fetched request list.
state.knownRequestIds- Tracks requests already seen.
state.newRequestIds- Tracks newly arrived requests for visual highlighting.
state.selectedRequestId- Currently selected postback.
state.activeTab- One of
body,headers,query,raw.
- One of
state.settings- Refresh interval and pause state.
Key functions:
init()- Loads persisted token/settings and starts polling when a token exists.
createToken()- Creates a new Webhook.site endpoint.
connectExistingToken()- Parses and connects to an existing Webhook.site URL or token ID.
useToken(token)- Saves the token, hides setup, resets request state, fetches requests, and starts polling.
fetchRequests()- Polls the list endpoint and updates request state.
selectRequest(requestId)- Selects a row, switches to the body tab, and fetches detailed request data.
fetchRequestDetail(requestId)- Loads one request's detail so body content is available.
renderShell()- Coordinates setup/monitor/settings visibility and overall render state.
renderRequestList()- Draws request rows.
renderDetails()- Draws the selected request details.
changeEndpoint()- Clears the active token and returns the user to setup.
storageGet()/storageSet()- Use Chrome local storage in extension context, localStorage fallback outside it.
Runtime Flow
- User opens extension.
panel.jsloads stored token/settings.- If no token exists:
- Show setup UI.
- Hide monitor UI.
- Hide settings button.
- If a token exists:
- Hide setup UI.
- Show monitor UI.
- Show settings button.
- Fetch request list.
- Schedule polling unless paused.
- User clicks a request:
- Row becomes selected.
- Body tab becomes active.
- Request detail endpoint is fetched.
- Body content is rendered in the details panel.
- User changes endpoint from settings:
- Token is removed from storage.
- Request state is cleared.
- Setup UI returns.
Development Notes
- Keep the project dependency-free unless the user asks for a build system.
- Prefer plain JavaScript and Web Extension APIs.
- Maintain Chrome and Edge compatibility.
- Use Manifest V3-compatible APIs only.
- Keep backend use free to set up and free to use.
- Do not add API keys or paid-only services.
- Do not store captured payloads anywhere except extension state/storage and Webhook.site's own request history.
- Avoid opening the webhook endpoint URL directly for inspection, because visiting it can create a captured GET request. Use the test postback button when intentionally generating a request.
Verification Checklist
After changes, run:
node --check panel.js
node --check background.js
Get-Content manifest.json | ConvertFrom-Json | Out-Null
Manual browser check:
- Reload the unpacked extension in
chrome://extensionsoredge://extensions. - Open the side panel from the extension icon.
- Create a free webhook.
- Confirm setup disappears and monitor UI appears.
- Send a test postback.
- Confirm the request appears in the list.
- Click the request.
- Confirm the body appears in the details panel.
- Open settings and choose Change endpoint.
- Confirm setup UI returns.
Known Gaps / Future Improvements
- There is no notification badge count yet.
- There is no export/download feature yet.
- There is no local encrypted payload cache.
- There is no custom response editor for webhook replies.
- Polling is simple
setTimeoutpolling from the panel page; if the panel is closed, monitoring pauses. - The UI currently targets Webhook.site only. Supporting other providers will need a backend adapter layer.
Git Notes
The repository was initialized after the first implementation. At the time this file was added, the initial extension files were staged but not committed. If continuing from that point, check git status --short before editing and avoid unstaging or reverting user work unless explicitly requested.