Files
orca/cloud/apps/push/src/push-dispatcher.ts
Jinwoo Hong eb2f2d52ae feat(cloud): native push gateway and dedicated infrastructure (1/3) (#19912)
* refactor(cloud): share PostgreSQL schema startup between services

* feat(cloud): add durable native push notification gateway

* infra(push): define dedicated gateway resources and operational checks

* fix(push): bound cross-host admission and simplify gateway configuration

* fix(push): validate deploy configuration and preserve topic-error registrations
2026-09-10 17:59:46 -04:00

53 lines
1.9 KiB
TypeScript

import type { ApnsClient } from './apns-client.js'
import type { PushDeviceRegistryStore } from './device-registry-store.js'
import type { FcmClient } from './fcm-client.js'
import { fingerprintLogPrefix } from './host-fingerprint.js'
import type { PushDelivery } from './push-delivery-message.js'
import type { PushProviderOutcome } from './push-provider-outcome.js'
export type PushDispatcherOptions = {
devices: PushDeviceRegistryStore
apns?: ApnsClient
fcm?: FcmClient
onOutcome?: (outcome: PushProviderOutcome['status']) => void
}
// Retires the registration when the provider says the token is gone.
export class PushDispatcher {
constructor(private readonly options: PushDispatcherOptions) {}
async sendOnce(delivery: PushDelivery): Promise<PushProviderOutcome> {
const device = await this.options.devices.findById(delivery.registrationId)
if (!device || device.dead) return { status: 'dead', reason: 'registration_unavailable' }
let outcome: PushProviderOutcome
if (device.platform === 'ios') {
outcome = this.options.apns
? await this.options.apns.send(delivery, {
token: device.token,
apnsEnvironment: device.apnsEnvironment ?? 'production'
})
: { status: 'error', reason: 'apns_not_configured' }
} else {
outcome = this.options.fcm
? await this.options.fcm.send(delivery, { token: device.token })
: { status: 'error', reason: 'fcm_not_configured' }
}
this.options.onOutcome?.(outcome.status)
if (outcome.status === 'dead') {
await this.options.devices.markDead(device)
}
if (outcome.status !== 'sent') {
console.warn(
JSON.stringify({
event: 'orca_push_delivery_failed',
platform: device.platform,
status: outcome.status,
reason: outcome.reason,
host: fingerprintLogPrefix(delivery.hostFingerprint)
})
)
}
return outcome
}
}