Integration guides
Cloudflare Workers
Moderate content from a Worker, with the key as a Worker secret.
A Worker runs on the server side of your application, so it can hold the key. Call it from your front end, and let it call openshield.
Set the key as a secret
npx wrangler secret put OPENMOD_API_KEY
For local development, put it in a .dev.vars file that is not committed:
OPENMOD_API_KEY=om_live_...
The Worker
src/index.ts
export interface Env {
OPENMOD_API_KEY: string
}
const base = "https://api.openshield.dev"
export default {
async fetch(request: Request, env: Env): Promise<Response> {
if (request.method !== "POST") return new Response("Method not allowed", { status: 405 })
const { text, ref } = (await request.json()) as { text: string; ref?: string }
let answer: Response
try {
answer = await fetch(`${base}/v1/text`, {
method: "POST",
headers: {
Authorization: `Bearer ${env.OPENMOD_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text, ref }),
signal: AbortSignal.timeout(10_000),
})
} catch {
// The check could not be made: fail closed, keep the content hidden.
return Response.json({ decision: "hold" })
}
const body = (await answer.json()) as {
summary?: { action: string; reject_reason: Array<{ id: string }> }
error?: { type: string }
request_id?: string
}
if (!answer.ok || body.summary === undefined) {
const refused = [400, 413, 415].includes(answer.status)
return Response.json({ decision: refused ? "refuse" : "hold", error: body.error?.type ?? "unknown" })
}
const { action, reject_reason } = body.summary
return Response.json({
decision: action === "accept" ? "publish" : action === "review" ? "hold" : "refuse",
reason: reject_reason[0]?.id ?? null,
requestId: body.request_id,
})
},
}
Your Worker is the one that calls openshield, from Cloudflare's servers. A browser must call your Worker, never openshield: a request to our API with an
Origin header is refused.