
Company News
Socket Joins New OpenJS Program to Fund Node.js Security Work
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.
@profullstack/autoblog
Advanced tools
CloudEvents + Standard Webhooks SDK for autoblog publishing. Build and send normalized post-published events from a CMS or AI writer; verify, parse, and quality-gate them in your blog receiver.
The autoblog publishing/receiving SDK. Three protocols, one package.
| Module | Standard | What it does |
|---|---|---|
@profullstack/autoblog | CloudEvents 1.0 + Standard Webhooks | Normalized post-published events. Build, sign, send, verify, parse. The default channel for AI-writer → blog publishing. |
@profullstack/autoblog/micropub | W3C Micropub | Inbound publishing API. Mount the handler at your /micropub endpoint and accept posts from Quill, Indigenous, Omnibear, etc. |
@profullstack/autoblog/activitypub | W3C ActivityPub | Protocol surface for federating your blog: Actor + WebFinger builders, ActivityStreams Note/Article shapes, HTTP Signatures sign + verify, signed-POST fan-out. |
npm i @profullstack/autoblog
# or
pnpm add @profullstack/autoblog
Node 18+. ESM only.
import { buildEvent, sendWebhook, type Post } from "@profullstack/autoblog";
const post: Post = {
id: "p_123",
url: "https://crawlproof.com/blog/why-llms-txt",
title: "Why your llms.txt matters",
slug: "why-llms-txt",
html: "<p>…</p>",
status: "published",
published_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
tags: ["seo", "ai bots"],
categories: [],
};
const event = buildEvent(post, { source: "https://crawlproof.com" });
const result = await sendWebhook("https://receiver.example/api/webhook", event, {
secret: process.env.WEBHOOK_SECRET!,
});
console.log(result.ok ? "delivered" : `failed (${result.status})`);
Sends Authorization: Bearer … plus the three Standard Webhooks headers:
webhook-id: <event id>
webhook-timestamp: <unix seconds>
webhook-signature: v1,<base64 HMAC-SHA256 of "${id}.${timestamp}.${body}">
content-type: application/cloudevents+json
import { verifyAndParse } from "@profullstack/autoblog";
export async function POST(req: Request) {
const body = await req.text(); // raw bytes — needed for signature
const r = verifyAndParse({
headers: Object.fromEntries(req.headers),
body,
opts: { secret: process.env.WEBHOOK_SECRET! },
});
if (!r.ok) return new Response(r.reason, { status: r.status });
await savePost(r.post); // your CMS / DB
return new Response(null, { status: 200 });
}
verifyAndParse validates the bearer (constant-time), the Standard Webhooks signature, and the envelope shape. Failure modes split cleanly into 400 (bad body) and 401 (auth).
import { createMicropubHandler } from "@profullstack/autoblog/micropub";
const handler = createMicropubHandler({
// Validate the IndieAuth bearer however you like — local table,
// remote validator, your own /token endpoint.
verify: async (token) => {
const row = await db.tokens.find({ token });
return row ? { ok: true, me: row.profileUrl, scope: row.scopes } : { ok: false, reason: "unknown token" };
},
onCreate: async (entry, identity) => {
const slug = entry.slug ?? slugify(entry.name ?? "untitled");
const url = `https://example.com/blog/${slug}`;
await db.posts.insert({ url, title: entry.name, html: entry.content, tags: entry.category });
return { url };
},
onDelete: async (url) => { await db.posts.delete({ url }); },
});
// Wire into your framework — example (Next.js route handler):
export async function POST(req: Request) {
const body = await req.text();
const res = await handler({
method: "POST",
headers: Object.fromEntries(req.headers),
body,
});
return new Response(res.body, { status: res.status, headers: res.headers });
}
import {
generateActorKeypair,
buildActor,
buildWebFinger,
buildNote,
buildCreateActivity,
deliverToInboxes,
verifyHttpSignature,
} from "@profullstack/autoblog/activitypub";
// One-time: create + persist your actor key.
const { publicKeyPem, privateKeyPem } = generateActorKeypair();
// Store privateKeyPem encrypted; publicKeyPem goes in the Actor object.
// /.well-known/webfinger?resource=acct:admin@example.com
const finger = buildWebFinger({
username: "admin",
host: "example.com",
actorUrl: "https://example.com/users/admin",
});
// /users/admin
const actor = buildActor({
id: "https://example.com/users/admin",
preferredUsername: "admin",
name: "Example Blog",
publicKeyPem,
});
// When a post lands → build + sign + deliver to followers' inboxes.
const note = buildNote(post, { actorId: actor.id });
const activity = buildCreateActivity({ actorId: actor.id, note });
await deliverToInboxes({
actorId: actor.id,
privateKeyPem,
inboxUrls: followerInboxes, // from your followers table
activity,
});
// Inbox verification on POST /users/admin/inbox:
const r = await verifyHttpSignature({
method: "POST",
url: "https://example.com/users/admin/inbox",
headers,
body,
fetchPublicKey: async (keyId) => {
// Strip the fragment, fetch the actor JSON, return publicKey.publicKeyPem
const actorUrl = keyId.split("#")[0];
const res = await fetch(actorUrl, {
headers: { accept: "application/activity+json" },
});
if (!res.ok) return null;
const a = await res.json();
return a?.publicKey?.publicKeyPem ?? null;
},
});
What the SDK doesn't do: store followers, run an outbox queue, or remember which followers you've already delivered to. Those are persistence concerns and they're the host app's job.
0.x: API may change between minor versions. After 1.0, semver.
MIT
FAQs
CloudEvents + Standard Webhooks SDK for autoblog publishing. Build and send normalized post-published events from a CMS or AI writer; verify, parse, and quality-gate them in your blog receiver.
The npm package @profullstack/autoblog receives a total of 77 weekly downloads. As such, @profullstack/autoblog popularity was classified as not popular.
We found that @profullstack/autoblog demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.

Company News
Socket is joining the OpenJS Security Stewardship Program to fund Node.js vulnerability research, maintainer remediation, and security releases.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.