Initial commit

This commit is contained in:
2026-04-17 23:26:01 +00:00
commit 2ea4ca5d52
409 changed files with 63459 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
import { getAccessToken, getServiceAccount } from './fcmAuth.ts'
export async function handleFcmPush(req: Request): Promise<Response> {
const secret = Deno.env.get('SIDECAR_SECRET')
if (secret && req.headers.get('x-sidecar-secret') !== secret) {
return new Response('Unauthorized', { status: 401 })
}
let body: {
tokens: string[]
title: string
body: string
data?: Record<string, string>
}
try {
body = await req.json()
} catch {
return new Response('Invalid JSON', { status: 400 })
}
const { tokens, title, body: messageBody, data } = body
if (!tokens?.length) {
return new Response('No tokens provided', { status: 400 })
}
const { project_id } = getServiceAccount()
const accessToken = await getAccessToken()
const results = await Promise.allSettled(
tokens.map(token =>
fetch(
`https://fcm.googleapis.com/v1/projects/${project_id}/messages:send`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: {
token,
notification: { title, body: messageBody },
...(data ? { data } : {})
}
})
}
).then(async (r) => {
if (!r.ok) {
const err = await r.json()
throw new Error(err.error?.message ?? r.statusText)
}
return r.json()
})
)
)
let successCount = 0
let failureCount = 0
results.forEach((result, i) => {
if (result.status === 'fulfilled') {
successCount++
} else {
failureCount++
console.error(`FCM failed for token ${tokens[i]}:`, result.reason)
}
})
console.log(`FCM: ${successCount} sent, ${failureCount} failed`)
return Response.json({ successCount, failureCount })
}