Add guest push notifications and queue alerts

This commit is contained in:
Codex Agent
2025-11-12 20:38:49 +01:00
parent 2c412e3764
commit 574aa47ce7
34 changed files with 1806 additions and 74 deletions

View File

@@ -0,0 +1,71 @@
import { getDeviceId } from '../lib/device';
type PushSubscriptionPayload = {
endpoint: string;
keys: {
p256dh: string;
auth: string;
};
expirationTime?: number | null;
contentEncoding?: string | null;
};
function buildHeaders(): HeadersInit {
return {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Device-Id': getDeviceId(),
};
}
export async function registerPushSubscription(eventToken: string, subscription: PushSubscription): Promise<void> {
const json = subscription.toJSON() as PushSubscriptionPayload;
const body = {
endpoint: json.endpoint,
keys: json.keys,
expiration_time: json.expirationTime ?? null,
content_encoding: json.contentEncoding ?? null,
};
const response = await fetch(`/api/v1/events/${encodeURIComponent(eventToken)}/push-subscriptions`, {
method: 'POST',
headers: buildHeaders(),
credentials: 'include',
body: JSON.stringify(body),
});
if (!response.ok) {
const message = await parseError(response);
throw new Error(message ?? 'Push-Registrierung fehlgeschlagen.');
}
}
export async function unregisterPushSubscription(eventToken: string, endpoint: string): Promise<void> {
const response = await fetch(`/api/v1/events/${encodeURIComponent(eventToken)}/push-subscriptions`, {
method: 'DELETE',
headers: buildHeaders(),
credentials: 'include',
body: JSON.stringify({ endpoint }),
});
if (!response.ok) {
const message = await parseError(response);
throw new Error(message ?? 'Push konnte nicht deaktiviert werden.');
}
}
async function parseError(response: Response): Promise<string | null> {
try {
const payload = await response.clone().json();
const errorMessage = payload?.error?.message ?? payload?.message;
if (typeof errorMessage === 'string' && errorMessage.trim() !== '') {
return errorMessage;
}
} catch (error) {
console.warn('Failed to parse push API error', error);
}
return null;
}