feat: Add /push/request-location endpoint for manual location pings
- POST /push/request-location with { roomSlug } triggers silent push
- Returns count of sent/failed notifications
- Useful for on-demand location refresh
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ca1cd4877d
commit
4ee33f4992
|
|
@ -469,6 +469,60 @@ const server = createServer(async (req, res) => {
|
||||||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||||
res.end(JSON.stringify({ error: 'Failed to send test' }));
|
res.end(JSON.stringify({ error: 'Failed to send test' }));
|
||||||
}
|
}
|
||||||
|
} else if (pathname === '/push/request-location' && req.method === 'POST') {
|
||||||
|
// Manually trigger location request for a room
|
||||||
|
try {
|
||||||
|
const { roomSlug } = await parseJsonBody(req);
|
||||||
|
|
||||||
|
if (!roomSlug) {
|
||||||
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ error: 'roomSlug required' }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subs = pushSubscriptions.get(roomSlug);
|
||||||
|
if (!subs || subs.size === 0) {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ success: true, sent: 0, message: 'No subscribers in room' }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sent = 0;
|
||||||
|
let failed = 0;
|
||||||
|
const failedEndpoints = [];
|
||||||
|
|
||||||
|
for (const sub of subs) {
|
||||||
|
try {
|
||||||
|
await webpush.sendNotification(sub, JSON.stringify({
|
||||||
|
silent: true,
|
||||||
|
data: { type: 'location_request', roomSlug }
|
||||||
|
}));
|
||||||
|
sent++;
|
||||||
|
} catch (error) {
|
||||||
|
failed++;
|
||||||
|
if (error.statusCode === 404 || error.statusCode === 410) {
|
||||||
|
failedEndpoints.push(sub.endpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up failed subscriptions
|
||||||
|
for (const endpoint of failedEndpoints) {
|
||||||
|
for (const sub of subs) {
|
||||||
|
if (sub.endpoint === endpoint) {
|
||||||
|
subs.delete(sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[${roomSlug}] Manual location request: ${sent} sent, ${failed} failed`);
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ success: true, sent, failed }));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Location request error:', error);
|
||||||
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||||||
|
res.end(JSON.stringify({ error: 'Failed to request location' }));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
res.writeHead(404);
|
res.writeHead(404);
|
||||||
res.end('Not found');
|
res.end('Not found');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue