feat: syndication webhook on incremental builds
Add an eleventy.after hook that triggers syndication immediately after incremental rebuilds, cutting latency from ~2 min (poller) to ~5 sec. Uses built-in crypto for HS256 JWT — no new dependencies. Confab-Link: http://localhost:8080/sessions/d116ad5b-ef8a-424e-9ebe-76c06bef1df6
This commit is contained in:
@@ -9,7 +9,7 @@ import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
|
||||
import { minify } from "html-minifier-terser";
|
||||
import registerUnfurlShortcode, { getCachedCard, prefetchUrl } from "./lib/unfurl-shortcode.js";
|
||||
import matter from "gray-matter";
|
||||
import { createHash } from "crypto";
|
||||
import { createHash, createHmac } from "crypto";
|
||||
import { execFileSync } from "child_process";
|
||||
import { readFileSync, readdirSync, existsSync, mkdirSync, writeFileSync, copyFileSync } from "fs";
|
||||
import { resolve, dirname } from "path";
|
||||
@@ -1096,6 +1096,41 @@ export default function (eleventyConfig) {
|
||||
|
||||
}
|
||||
|
||||
// Syndication webhook — trigger after incremental rebuilds (new posts are now live)
|
||||
// Cuts syndication latency from ~2 min (poller) to ~5 sec (immediate trigger)
|
||||
if (incremental) {
|
||||
const syndicateUrl = process.env.SYNDICATE_WEBHOOK_URL;
|
||||
if (syndicateUrl) {
|
||||
try {
|
||||
const secretFile = process.env.SYNDICATE_SECRET_FILE || "/app/data/config/.secret";
|
||||
const secret = readFileSync(secretFile, "utf-8").trim();
|
||||
|
||||
// Build a minimal HS256 JWT using built-in crypto (no jsonwebtoken dependency)
|
||||
const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const payload = Buffer.from(JSON.stringify({
|
||||
me: siteUrl,
|
||||
scope: "update",
|
||||
iat: now,
|
||||
exp: now + 300, // 5 minutes
|
||||
})).toString("base64url");
|
||||
const signature = createHmac("sha256", secret)
|
||||
.update(`${header}.${payload}`)
|
||||
.digest("base64url");
|
||||
const token = `${header}.${payload}.${signature}`;
|
||||
|
||||
const res = await fetch(`${syndicateUrl}?token=${token}`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
signal: AbortSignal.timeout(30000),
|
||||
});
|
||||
console.log(`[syndicate-hook] Triggered syndication: ${res.status}`);
|
||||
} catch (err) {
|
||||
console.error(`[syndicate-hook] Failed:`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WebSub hub notification — skip on incremental rebuilds
|
||||
if (incremental) return;
|
||||
const hubUrl = "https://websubhub.com/hub";
|
||||
|
||||
Reference in New Issue
Block a user