Skip to content

feat: customer webhooks via @profullstack/webhooks 0.2.1 (0.3.0) - #19

Merged
ralyodio merged 1 commit into
mainfrom
feat/webhooks
Oct 28, 2026
Merged

ralyodio merged 1 commit into
mainfrom
feat/webhooks

Conversation

@ralyodio

Copy link
Copy Markdown
Contributor

Customer webhooks on @profullstack/webhooks 0.2.1 (pinned exactly; deliveries never follow redirects).

What

  • AdNetwork.hooks = new Webhooks({ store: sqliteStore(store.db), source: origin, eventTypes: WEBHOOK_EVENTS }), tables in the existing SQLite file. hooks.start() once in serve().
  • hook(sub, type, data, subject): fire-and-forget emit to the account the event is about; never in the way of the action.
  • /api/v1/webhooks (list, create, get, test, rotate, deliveries, delete) mounted through the existing an_ API-key wrapper, so 401 without a key, owner = the key's account, writes count against the existing write limit.
  • /me#webhooks card: list, add (URL + event patterns), send a test, new secret, remove; secret shown once. Endpoints are deleted with the account.
  • CLI: adnetwork webhooks, adnetwork webhook add|test|rotate|rm|log. MCP: list_webhooks, create_webhook, test_webhook, rotate_webhook_secret, delete_webhook, webhook_deliveries. Help page + README document them.

Events (owner = the advertiser/publisher's CoinPay sub)

event when subject
ad.created a new ad ad:<ref>
ad.started / ad.paused crawlproof status flips in enforce(); reason: requested, funded, no_budget ad:<ref>
ad.deleted ad deleted ad:<ref>
budget.exhausted the sweep paused ads because the balance ran out account:<sub>
deposit.completed / deposit.failed a pending deposit settles (any non-complete terminal status is failed, with status) deposit:<id>
credit.added a credit code or invite grant lands (kind: code/invite, spend-only) account:<sub>
site.added / site.verified / site.removed publisher site lifecycle (verified by "Check my site" or the sweep) site:<host>
site.lost someone else proved a site this account never did (to the previous claimant) site:<host>
payout.requested a withdrawal to the site's wallet site:<host>

The candidate names ad.approved/ad.rejected/payout.sent from the brief do not exist in ad.network: crawlproof has no review step here, and payouts are a single crawlproof call whose answer is recorded as payout.requested with its status (confirmed or requested).

Existing endpoints

None: ad.network sent no outbound webhooks before this, so nothing to migrate and no receiver-visible shape change.

Tests

3 new tests: API auth + per-account scoping + SSRF/event validation; an end-to-end advertiser + publisher run asserting each event's payload and that every delivery verifies against the secret shown on /me (and fails with a wrong one), rotate/remove from the page; CLI + MCP. bun test 26/26, tsc --noEmit clean.

🤖 Generated with Claude Code

Advertisers and publishers can register webhook endpoints (/me#webhooks,
/api/v1/webhooks behind the an_ API key, `adnetwork webhook ...`, MCP
create_webhook etc.) and get signed CloudEvents for their own ads, money
and sites: ad.created, ad.started, ad.paused, ad.deleted, budget.exhausted,
deposit.completed, deposit.failed, credit.added, site.added, site.verified,
site.lost, site.removed, payout.requested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​profullstack/​webhooks@​0.2.17610010090100

View full report

@ralyodio
ralyodio merged commit b9671f3 into main Oct 28, 2026
3 checks passed
@ralyodio
ralyodio deleted the feat/webhooks branch October 28, 2026 15:16
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.

1 participant