Files
openclaw/src/gateway/server-methods/push.ts
Mariano 99d099aa84 Gateway: add APNs push test pipeline (#20307)
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 6a1c4422079b075fb7900890fa09819f41aee8b1
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
2026-02-18 19:32:42 +00:00

74 lines
2.2 KiB
TypeScript

import {
loadApnsRegistration,
normalizeApnsEnvironment,
resolveApnsAuthConfigFromEnv,
sendApnsAlert,
} from "../../infra/push-apns.js";
import { ErrorCodes, errorShape, validatePushTestParams } from "../protocol/index.js";
import { respondInvalidParams, respondUnavailableOnThrow } from "./nodes.helpers.js";
import type { GatewayRequestHandlers } from "./types.js";
function normalizeOptionalString(value: unknown): string | undefined {
if (typeof value !== "string") {
return undefined;
}
const trimmed = value.trim();
return trimmed.length > 0 ? trimmed : undefined;
}
export const pushHandlers: GatewayRequestHandlers = {
"push.test": async ({ params, respond }) => {
if (!validatePushTestParams(params)) {
respondInvalidParams({
respond,
method: "push.test",
validator: validatePushTestParams,
});
return;
}
const nodeId = String(params.nodeId ?? "").trim();
if (!nodeId) {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
return;
}
const title = normalizeOptionalString(params.title) ?? "OpenClaw";
const body = normalizeOptionalString(params.body) ?? `Push test for node ${nodeId}`;
await respondUnavailableOnThrow(respond, async () => {
const registration = await loadApnsRegistration(nodeId);
if (!registration) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`node ${nodeId} has no APNs registration (connect iOS node first)`,
),
);
return;
}
const auth = await resolveApnsAuthConfigFromEnv(process.env);
if (!auth.ok) {
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, auth.error));
return;
}
const overrideEnvironment = normalizeApnsEnvironment(params.environment);
const result = await sendApnsAlert({
auth: auth.value,
registration: {
...registration,
environment: overrideEnvironment ?? registration.environment,
},
nodeId,
title,
body,
});
respond(true, result, undefined);
});
},
};