121 lines
4.2 KiB
TypeScript
121 lines
4.2 KiB
TypeScript
/**
|
|
* Test Notification Channel — send a test message.
|
|
*/
|
|
|
|
import { NextRequest, NextResponse } from 'next/server';
|
|
import { postgresClient } from '@/lib/services/postgres-client';
|
|
|
|
export async function POST(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
|
try {
|
|
const { id } = await params;
|
|
const result = await postgresClient.query(
|
|
`SELECT * FROM notification_channels WHERE id = $1`, [id]
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return NextResponse.json({ error: 'Channel not found' }, { status: 404 });
|
|
}
|
|
|
|
const channel = result.rows[0];
|
|
const testMessage = `🧪 Test notification from Pulse Pipeline Engine\nChannel: ${channel.name}\nTime: ${new Date().toISOString()}`;
|
|
|
|
let resp: Response;
|
|
|
|
switch (channel.channel_type) {
|
|
case 'teams': {
|
|
if (!channel.config.webhook_url) {
|
|
return NextResponse.json({ error: 'Missing webhook_url in channel config' }, { status: 400 });
|
|
}
|
|
const card = {
|
|
type: 'message',
|
|
attachments: [{
|
|
contentType: 'application/vnd.microsoft.card.adaptive',
|
|
content: {
|
|
type: 'AdaptiveCard',
|
|
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
|
|
version: '1.4',
|
|
body: [
|
|
{ type: 'TextBlock', text: '🧪 Pulse Test Notification', weight: 'bolder', size: 'medium' },
|
|
{ type: 'TextBlock', text: `Channel: ${channel.name}`, wrap: true },
|
|
{ type: 'TextBlock', text: `Time: ${new Date().toISOString()}`, size: 'small', isSubtle: true },
|
|
],
|
|
},
|
|
}],
|
|
};
|
|
resp = await fetch(channel.config.webhook_url, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(card),
|
|
});
|
|
break;
|
|
}
|
|
|
|
case 'telegram': {
|
|
if (!channel.config.bot_token || !channel.config.chat_id) {
|
|
return NextResponse.json({ error: 'Missing bot_token or chat_id in channel config' }, { status: 400 });
|
|
}
|
|
resp = await fetch(`https://api.telegram.org/bot${channel.config.bot_token}/sendMessage`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
chat_id: channel.config.chat_id,
|
|
text: testMessage,
|
|
parse_mode: channel.config.parse_mode || 'HTML',
|
|
}),
|
|
});
|
|
break;
|
|
}
|
|
|
|
case 'ntfy': {
|
|
if (!channel.config.topic) {
|
|
return NextResponse.json({ error: 'Missing topic in channel config' }, { status: 400 });
|
|
}
|
|
const serverUrl = channel.config.server_url || 'https://ntfy.sh';
|
|
const headers: Record<string, string> = {
|
|
'Title': 'Pulse Test Notification',
|
|
'Priority': 'default',
|
|
'Tags': 'test_tube',
|
|
};
|
|
if (channel.config.auth_token) {
|
|
headers['Authorization'] = `Bearer ${channel.config.auth_token}`;
|
|
}
|
|
resp = await fetch(`${serverUrl}/${channel.config.topic}`, {
|
|
method: 'POST',
|
|
headers,
|
|
body: testMessage,
|
|
});
|
|
break;
|
|
}
|
|
|
|
case 'webhook': {
|
|
if (!channel.config.url) {
|
|
return NextResponse.json({ error: 'Missing url in channel config' }, { status: 400 });
|
|
}
|
|
resp = await fetch(channel.config.url, {
|
|
method: channel.config.method || 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...(channel.config.headers || {}),
|
|
},
|
|
body: JSON.stringify({ test: true, message: testMessage, timestamp: new Date().toISOString() }),
|
|
});
|
|
break;
|
|
}
|
|
|
|
default:
|
|
return NextResponse.json({ error: `Unknown channel type: ${channel.channel_type}` }, { status: 400 });
|
|
}
|
|
|
|
const status = resp.status;
|
|
const responseText = await resp.text();
|
|
|
|
return NextResponse.json({
|
|
success: resp.ok,
|
|
status,
|
|
response: responseText.substring(0, 500),
|
|
});
|
|
} catch (error) {
|
|
const msg = error instanceof Error ? error.message : String(error);
|
|
return NextResponse.json({ error: msg }, { status: 500 });
|
|
}
|
|
}
|