You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 7cfefd1
Browse filesBrowse the repository at this point in the historyBrowse files
feat(webhooks): send through @profullstack/webhooks 0.2.0 (0.4.0) (#142)
Domain and project webhooks now go through the shared hub: CloudEvents
bodies, Standard Webhooks signatures, a durable queue with retries and a
delivery log, drained by hooks.start() at server boot (instrumentation.ts).
- lib/webhook-store.ts: a WebhookStore on the app's libSQL-shaped client
(Postgres via libsql-pg in prod, file: in tests), hub_ tables from the
package's DDL.
- Existing endpoints are copied once into the hub with their ids, URLs,
subscriptions and on/off state. The old sender keyed the HMAC with the
whole secret string; the stored secret becomes whsec_ + base64 of it,
the same key, so receivers verify unchanged (tested).
- Domain events waitlist.signup, bid.placed/won/accepted and inbound.*
relays are emitted via hooks.emit; the x-moshcoding-hop header is kept.
- /api/v1/webhooks?dn= mounts webhooksApi behind session or API key,
scoped to a domain the account owns.
- Dashboard Webhooks tab: event filter on add, per-target test, rotate,
delivery log. Project webhook routes answer as before.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@@ -100,6 +118,11 @@ export async function POST(req: NextRequest) {
100
118
if(isSelfWebhookUrl(url)){
101
119
returnNextResponse.json({error: "That's an inbound receiver URL — sending events there would loop back into this dashboard. Use the URL of your own server."},{status: 400});
<pclassName="sub">Every parked domain gets hosted webhooks — no server to run. <b>Inbound:</b> POST events to the URL below. <b>Outbound:</b> we POST domain events (waitlist.signup, bid.placed/won/accepted) to your URLs, signed (Standard Webhooks).</p>
1020
+
<pclassName="sub">Every parked domain gets hosted webhooks — no server to run. <b>Inbound:</b> POST events to the URL below. <b>Outbound:</b> we POST domain events (waitlist.signup, bid.placed/won/accepted, inbound.*) to your URLs as CloudEvents, signed (Standard Webhooks), retried with backoff. Also scriptable: <code>/api/v1/webhooks?dn=<domain></code> with an API key.</p>
<inputclassName="inp"style={{maxWidth: 220}}placeholder="events: all, or e.g. bid.*, waitlist.signup"title={`Comma-separated. Available: ${(data.eventTypes||[]).join(", ")}`}value={events}onChange={(e)=>setEvents(e.target.value)}/>
onClick={()=>{if(window.confirm("Rotate the signing secret? The old one stops working at once."))act({action: "rotate",id: w.id},"Secret rotated. Copy the new one now.");}}
0 commit comments