@monok/server
v1.3.0
Published
Monok server integration helpers (Express router + linkback client)
Readme
@monok/server
Monok server integration helpers for Node.js/Express. Easily connect your backend to Monok to receive articles, expose site info, and send linkbacks.
⚡ Quick Start
import express from "express";
import { createMonokRouter, type MonokArticle } from "@monok/server";
const app = express();
app.use(
"/monok",
createMonokRouter({
apiKey: process.env.MONOK_API_KEY!,
onArticle: async (article: MonokArticle, { saveThumbImage, action }) => {
const imagePath = await saveThumbImage();
if (action === "publish") {
// auto-publish in your CMS
} else {
// save as draft (default)
}
}
})
);
app.listen(3000);📦 Install
npm install @monok/server express📚 Usage
Express setup (TypeScript)
import express from "express";
import {
createMonokRouter,
sendMonokLinkback,
type MonokArticle
} from "@monok/server";
const app = express();
app.use(
"/monok",
createMonokRouter({
apiKey: process.env.MONOK_API_KEY!,
imageDir: "./uploads", // optional
// Optional: provide site info if you want Monok to query it
getSiteInfo: {
js_scripts: "Enabled",
version: "1.0.0",
name: "My Site",
logo: "https://example.com/logo.png",
categories: ["Content", "News Articles", "Uncategorized"],
post_types: ["post", "page"],
tags: ["Tech", "Health", "News"],
authors: [
{
name: "Jane Doe",
profile: "Editor-in-chief",
id: "1",
avatar: "https://example.com/avatars/jane.png",
roles: ["administrator"]
}
]
},
onArticle: async (article: MonokArticle, { saveThumbImage, action }) => {
const imagePath = await saveThumbImage();
console.log("Received article:", article.title);
if (action === "publish") {
// publish immediately
} else {
// save as draft
}
// when you publish later, notify Monok:
// await sendMonokLinkback({
// monokId: article.id,
// publicUrl: "https://example.com/blog/" + (article.slug ?? article.id),
// title: article.title,
// articleTextSample: article.text?.slice(0, 500),
// thumbnailUrl: imagePath
// ? "https://example.com/uploads/" + require("path").basename(imagePath)
// : undefined
// });
}
})
);
app.listen(3000);CommonJS (JavaScript)
const express = require("express");
const { createMonokRouter } = require("@monok/server");
const app = express();
app.use(
"/monok",
createMonokRouter({
apiKey: process.env.MONOK_API_KEY,
onArticle: async (article, { saveThumbImage, action }) => {
const img = await saveThumbImage();
console.log("Got article:", article.title, "Saved image:", img);
if (action === "publish") {
// publish immediately
} else {
// save as draft
}
}
})
);
app.listen(3000);🔑 Endpoints
POST /monok/push[?action=draft|publish]Monok pushes new article data here. Header:token: <your-api-key>Body: JSON payload of the article.actionquery param may bedraftorpublishdepending on GUI dropdown selection.
GET /monok/info?apikey=<your-api-key>IfgetSiteInfois configured, Monok fetches this to learn your site branding, categories, tags, and authors. IfgetSiteInfois not provided, this route responds with404.
🔗 Linkback after publishing
import { sendMonokLinkback } from "@monok/server";
await sendMonokLinkback({
monokId: article.id,
publicUrl: "https://example.com/blog/" + (article.slug ?? article.id),
title: article.title,
articleTextSample: article.text?.slice(0, 500),
thumbnailUrl: "https://example.com/uploads/" + imageFile
});⚙️ Options (createMonokRouter)
| Option | Type | Required | Description |
| ------------- | ----------------------------------------- | -------- | --------------------------------------------------------------------------------- |
| apiKey | string | ✅ | Token Monok sends in headers / query. |
| onArticle | (article, ctx) => void \| Promise<void> | ✅ | Handle new article pushes. ctx includes saveThumbImage and optional action. |
| getSiteInfo | SiteInfo \| () => SiteInfo | ❌ | Return site info in the Monok format. If omitted, GET /info responds 404. |
| imageDir | string | ❌ | Directory to save thumbImageData. |
| basePath | string | ❌ | Custom prefix for routes (default ""). |
🛠 Development
Build the package:
npm run build