prism/server/routes/ntfy.ts

60 lines
1.6 KiB
TypeScript

import { createGroup, sendGroupMessage } from '@/modules/signal';
import { getGroupId, register } from '@/modules/store';
import { withAuth } from '@/utils/auth';
import { logError, logVerbose } from '@/utils/log';
const handleNtfyPublish = async (req: Request) => {
try {
const url = new URL(req.url);
const topic = url.pathname.slice(1);
if (!topic || topic.includes('/')) {
return new Response('Invalid topic', { status: 400 });
}
const body = await req.text();
if (!body) {
return new Response('Message required', { status: 400 });
}
const title = req.headers.get('X-Title') || req.headers.get('Title') || req.headers.get('t');
const topicKey = `ntfy-${topic}`;
let groupId = getGroupId(topicKey);
if (!groupId) {
groupId = await createGroup(topic);
register(topicKey, groupId, topic);
logVerbose(`Created new group for ntfy topic: ${topic}`);
}
const message = title ? `**${title}**\n${body}` : body;
await sendGroupMessage(groupId, message);
logVerbose(`Sent ntfy message to topic ${topic}: ${title || body.substring(0, 50)}`);
return new Response(
JSON.stringify({
id: Date.now().toString(),
time: Math.floor(Date.now() / 1000),
event: 'message',
topic,
message: body,
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
);
} catch (error) {
logError('Failed to handle ntfy publish:', error);
return new Response('Internal server error', { status: 500 });
}
};
export const ntfyRoutes = {
'/:topic': {
POST: withAuth(handleNtfyPublish),
},
};