Webhook post.published, obrazek wraca przez Admin API.
Ghost wysyła webhooka przy publikacji. Odbierasz go u siebie, generujesz obrazek i wstawiasz go z powrotem jako `og_image` wpisu przez Admin API — bez dotykania motywu.
webhook.js
import GhostAdminAPI from '@tryghost/admin-api';
const ghost = new GhostAdminAPI({
url: process.env.GHOST_URL,
key: process.env.GHOST_ADMIN_KEY,
version: 'v5.0',
});
// Ghost calls this endpoint on the post.published event.
export default async function handler(req, res) {
const post = req.body.post.current;
const image = await fetch('https://imageapi.dev/v1/images?wait=true', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.IMAGE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
template: 'blog-og',
modifications: {
title: post.title,
author: post.primary_author?.name ?? '',
site: new URL(process.env.GHOST_URL).host,
},
}),
}).then((r) => r.json());
await ghost.posts.edit({
id: post.id,
updated_at: post.updated_at, // Ghost requires this for version control
og_image: image.url,
});
res.status(204).end();
}
Ghost odrzuci edycję bez aktualnego `updated_at` — to jego zabezpieczenie przed nadpisaniem cudzych zmian. Przekaż wartość z webhooka, nie sprzed minuty.
Z ?wait=true czekasz na gotowy obrazek w tym samym połączeniu — zwykle około sekundy.
{
"id": "img_01m08s3ez1zcv28h335g9923bw",
"status": "completed",
"url": "https://cdn.imageapi.dev/renders/img_01m08s3ez1zcv28h335g9923bw.png",
"duration_ms": 912
}
Sto obrazków miesięcznie za darmo, potem $9 za dwa tysiące. Ten sam wpis wyrenderowany drugi raz zwraca istniejący adres i nie zużywa limitu — więc przebudowanie strony nic nie kosztuje.