Functions and cron
Functions are Deno-compatible TypeScript declared in the app manifest.
Authenticated Function
functions:
- name: summarize
entrypoint: functions/summarize/index.ts
verifyJwt: true
requiredSecrets:
- AI_API_KEYimport { defineFunction } from "@opencloud/server";
defineFunction(async ({ input, secrets, db, requestId, log }) => {
const body = await input.json<{ itemId?: string }>();
const secret = secrets.require("AI_API_KEY");
const items = body.itemId
? await db.from("items").select("id,title", {
filters: { id: body.itemId },
})
: [];
log.info("summary requested", { itemId: body.itemId ?? null });
return Response.json({
ok: true,
secretPresent: Boolean(secret),
items,
requestId,
});
});The platform creates the request ID before module loading and catches import errors, rejected promises, timeouts, invalid responses, and failed platform calls. The server library binds database, Auth, Storage, secrets, input, and structured logging to the current app environment. See development sessions for explicit dev invocation and diagnostics.
Table reads and writes use one consistent filter envelope:
await db.from("items").select("*", { filters: { state: "open" } });
await db.from("items").update(
{ state: "closed" },
{ filters: { id: itemId } },
);
await db.from("items").delete({ filters: { id: itemId } });Call PostgreSQL functions with db.rpc(name, args). For atomic multi-step work, put the steps in one PostgreSQL function and call db.transaction(name, args); one RPC is the transaction boundary. Use compareAndSet(value, { filters, expected }) for RLS-scoped optimistic concurrency. Application errors such as OUT_OF_STOCK retain their explicit code through the Function response and verification diagnostics.
await opencloud.functions.invoke("summarize", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ itemId }),
});Public Function
Declare verifyJwt: false and call invokePublic. Public means no user JWT verification; the SDK still sends the gateway’s anonymous project identity.
Cron
cron:
- name: hourly-summary
schedule: "0 * * * *"
function: summarize
enabled: trueCron uses five-field UTC expressions. It invokes the Function with POST, a scheduling envelope, and x-opencloud-invocation: cron.
Verification triggers the declared active cron job deterministically and then reads the normal structured invocation history. The schedule cadence no longer needs to fit inside a verifier timeout.
Secrets
Declare names in the manifest and provision values separately. Generate values that do not need to be known:
"$OPENCLOUD_CLI" secret generate "$APP_ID" INTERNAL_SIGNING_KEYFor a user-supplied provider key:
"$OPENCLOUD_CLI" secret entry-link "$APP_ID" AI_API_KEYThe returned one-time browser page keeps the value out of the agent conversation. Return only a presence flag, version marker, or one-way digest. Never return or log plaintext secrets.