184 lines
5.4 KiB
JavaScript

import { z } from 'zod'
const testSendSchema = z.object({
email: z.string().email('Valid email is required'),
notificationId: z.string().uuid().optional(),
testData: z.object({
title: z.string(),
channels: z.array(z.string()),
emailSubject: z.string().optional(),
emailContent: z.string().optional(),
pushTitle: z.string().optional(),
pushBody: z.string().optional(),
callToActionText: z.string().optional(),
callToActionUrl: z.string().optional()
}).optional()
})
export default defineEventHandler(async (event) => {
try {
const body = await readValidatedBody(event, testSendSchema.parse)
const { $db } = useNitroApp()
let notificationData = body.testData
// If notificationId is provided, fetch from database
if (body.notificationId) {
const result = await $db.query(`
SELECT n.*, nc.channel_type, nt.subject as template_subject,
nt.email_content as template_email_content,
nt.push_title as template_push_title,
nt.push_body as template_push_body
FROM notifications n
LEFT JOIN notification_channels nc ON n.id = nc.notification_id
LEFT JOIN notification_templates nt ON n.template_id = nt.id
WHERE n.id = $1
`, [body.notificationId])
if (result.rows.length === 0) {
throw createError({
statusCode: 404,
statusMessage: 'Notification not found'
})
}
const notification = result.rows[0]
const channels = result.rows.map(row => row.channel_type).filter(Boolean)
notificationData = {
title: notification.title,
channels,
emailSubject: notification.email_subject || notification.template_subject,
emailContent: notification.email_content || notification.template_email_content,
pushTitle: notification.push_title || notification.template_push_title,
pushBody: notification.push_body || notification.template_push_body,
callToActionText: notification.call_to_action_text,
callToActionUrl: notification.call_to_action_url
}
}
if (!notificationData) {
throw createError({
statusCode: 400,
statusMessage: 'Either notificationId or testData is required'
})
}
const results = []
// Send test email
if (notificationData.channels.includes('email') && notificationData.emailContent) {
try {
await sendTestEmail({
to: body.email,
subject: notificationData.emailSubject || 'Test Notification',
content: notificationData.emailContent,
callToActionText: notificationData.callToActionText,
callToActionUrl: notificationData.callToActionUrl
})
results.push({
channel: 'email',
status: 'sent',
message: 'Test email sent successfully'
})
} catch (error) {
results.push({
channel: 'email',
status: 'failed',
message: error.message
})
}
}
// Send test push notification
if (notificationData.channels.includes('push') && notificationData.pushTitle) {
try {
await sendTestPush({
email: body.email, // Use email to identify user for push
title: notificationData.pushTitle,
body: notificationData.pushBody
})
results.push({
channel: 'push',
status: 'sent',
message: 'Test push notification sent successfully'
})
} catch (error) {
results.push({
channel: 'push',
status: 'failed',
message: error.message
})
}
}
return {
success: true,
data: {
message: 'Test notifications processed',
results
}
}
} catch (error) {
console.error('Error sending test notification:', error)
if (error.statusCode) {
throw error
}
throw createError({
statusCode: 500,
statusMessage: 'Failed to send test notification'
})
}
})
// Mock email sending function - replace with your actual email service
async function sendTestEmail({ to, subject, content, callToActionText, callToActionUrl }) {
// This is a mock implementation
// Replace with your actual email service (SendGrid, Mailgun, etc.)
console.log('Sending test email:', {
to,
subject,
content: content.substring(0, 100) + '...',
cta: callToActionText
})
// Simulate email sending delay
await new Promise(resolve => setTimeout(resolve, 1000))
// For demo purposes, we'll just log and return success
// In a real implementation, you would:
// 1. Connect to your email service
// 2. Send the actual email
// 3. Handle any errors appropriately
return true
}
// Mock push notification function - replace with your actual push service
async function sendTestPush({ email, title, body }) {
// This is a mock implementation
// Replace with your actual push service (Firebase, OneSignal, etc.)
console.log('Sending test push notification:', {
email,
title,
body
})
// Simulate push sending delay
await new Promise(resolve => setTimeout(resolve, 800))
// For demo purposes, we'll just log and return success
// In a real implementation, you would:
// 1. Find user's device tokens by email
// 2. Send to push notification service
// 3. Handle any errors appropriately
return true
}