feat(webhooks): add per-verb subscriptions and bulk-create debounce
Subscriptions now declare a `verb` (create | delete | bulk-create). POST /:did/webhooks defaults to inserting both create and delete rows when no verb is given, preserving existing all-events behavior. Update events fold into the create verb. The new bulk-create verb debounces creates per DID over 400 ms and delivers a `records` array. Migration adds the verb column with default 'create' and clones every existing row for the delete verb so legacy subscriptions keep firing on both events.
This commit is contained in:
19
server.ts
19
server.ts
@@ -5,6 +5,7 @@ import {
|
||||
getNotes,
|
||||
getNotesByDid,
|
||||
getNotesByDids,
|
||||
type WebhookVerb,
|
||||
} from "./src/data/db.ts";
|
||||
import { log } from "./src/log.ts";
|
||||
|
||||
@@ -84,18 +85,30 @@ router.post("/notes/feed", async (ctx) => {
|
||||
ctx.response.body = getNotesByDids(dids, cursor, Number(limit) || PAGINATION);
|
||||
});
|
||||
|
||||
const ALLOWED_VERBS = ["create", "delete", "bulk-create"] as const;
|
||||
|
||||
router.post("/:did/webhooks", async (ctx) => {
|
||||
const { did } = ctx.params;
|
||||
const body = await ctx.request.body.json();
|
||||
const { method, url, token } = body ?? {};
|
||||
const { method, url, token, verb } = body ?? {};
|
||||
if (!method || !url) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = { error: "method and url are required" };
|
||||
return;
|
||||
}
|
||||
const subscription = addWebhookSubscription({ did, method, url, token });
|
||||
if (verb !== undefined && !ALLOWED_VERBS.includes(verb)) {
|
||||
ctx.response.status = 400;
|
||||
ctx.response.body = {
|
||||
error: `verb must be one of ${ALLOWED_VERBS.join(", ")}`,
|
||||
};
|
||||
return;
|
||||
}
|
||||
const verbsToInsert: WebhookVerb[] = verb ? [verb] : ["create", "delete"];
|
||||
const subscriptions = verbsToInsert.map((v) =>
|
||||
addWebhookSubscription({ did, method, url, token, verb: v })
|
||||
);
|
||||
ctx.response.status = 201;
|
||||
ctx.response.body = subscription;
|
||||
ctx.response.body = subscriptions;
|
||||
});
|
||||
|
||||
router.delete("/:did/webhooks", (ctx) => {
|
||||
|
||||
Reference in New Issue
Block a user