example · ghost

06 / 06

Ghost spam filter.

Updated May 12, 2026

This Ghost example is a webhook receiver that scores member signup notes, comment text, or any custom form payload before you accept it downstream. Configure a Ghost integration webhook (or a forwarding Worker) to POST events to this handler. It concatenates the text fields you care about, calls Siftfy, drops high-confidence spam, and queues the rest for downstream processing.

A webhook-style worker for scoring Ghost member signup notes, comment text, or custom form payloads before you accept them downstream.

javascript
// Generic Ghost webhook receiver. Adapt the field mapping to your event.
export default {
  async fetch(req, env) {
    if (req.method !== "POST") return new Response("method", { status: 405 });
    const event = await req.json();

    const text = [
      event.member?.name,
      event.member?.email,
      event.comment?.html,
      event.message,
    ].filter(Boolean).join("\n");

    let probability = 0;
    let ceiling = null;
    const resp = await fetch("https://api.siftfy.io/v1/predict", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-API-Key": env.SIFTFY_KEY,
      },
      body: JSON.stringify({ text }),
    });
    if (resp.ok) {
      const data = await resp.json();
      probability = data.spam_probability;
      ceiling = data.max_confidence ?? null;
    }

    // Drop only ABOVE the ceiling the response reports. At the ceiling the score
    // is censored, so a fixed constant never fires on the model's own opinion.
    if (ceiling !== null && probability > ceiling) return new Response("ok", { status: 200 });
    await env.CLEAN_QUEUE.send({ event, probability });
    return new Response("ok", { status: 200 });
  },
};

Production notes

  1. 01`max_confidence` is the highest score the model is allowed to return on its own word; only a score above it is more than the model's opinion.
  2. 02Ghost event payloads differ by feature and plugin; map the text fields you actually collect.
  3. 03Classify user-generated text, not just email addresses.
  4. 04For member signup fraud, combine Siftfy with email validation and rate limits.

Common questions

How do I add spam filtering to a Ghost site?

Create a Ghost custom integration with a webhook that posts events to a small worker. The worker concatenates the user-generated text fields, calls Siftfy, and only forwards clean events to your downstream queue or notifier. The full worker is shown above.

Which Ghost fields should I send to Siftfy?

Send the human-written text you actually care about: comment HTML, member signup notes, custom form `message` fields. Don't send only the email address — Siftfy is a text classifier, not an email-reputation service.

Can this handle Ghost comment moderation too?

Yes. Map `event.comment?.html` into the concatenated text, then push high-probability comments to a moderation queue you check daily. Combine with Ghost's built-in member-only commenting for a strong baseline.

How do I stop fake Ghost member signups?

Score the signup `note` and email-domain together, rate-limit by IP, and require email verification. For domains seen abusing signups, add them to a denylist so the worker rejects them before calling Siftfy.

Get a free API key

More patterns: all examples, contact forms, API reference.