Files
gremiumhub/landing/server/api/newsletter/subscribe.post.ts

127 lines
3.4 KiB
TypeScript

import { z } from 'zod'
const subscribeSchema = z.object({
email: z.string().email()
})
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
// Validate request body
const body = await readBody(event)
const result = subscribeSchema.safeParse(body)
if (!result.success) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid email address'
})
}
const { email } = result.data
// Check if API key is configured
if (!config.brevoApiKey) {
console.error('BREVO_API_KEY is not configured')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
// Check if DOI template ID is configured
if (!config.brevoDoiTemplateId) {
console.error('BREVO_DOI_TEMPLATE_ID is not configured')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
console.log('DOI_TEMPLATE_ID', config.brevoDoiTemplateId)
// Check if public site URL is configured (for DOI redirect)
if (!config.public.siteUrl) {
console.error('NUXT_PUBLIC_SITE_URL is not configured')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
// Check if newsletter list ID is configured
if (!config.brevoNewsletterListId) {
console.error('BREVO_NEWSLETTER_LIST_ID is not configured')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
const templateId = parseInt(config.brevoDoiTemplateId, 10)
if (isNaN(templateId)) {
console.error('BREVO_DOI_TEMPLATE_ID is not a valid number')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
const listId = parseInt(config.brevoNewsletterListId, 10)
if (isNaN(listId)) {
console.error('BREVO_NEWSLETTER_LIST_ID is not a valid number')
throw createError({
statusCode: 500,
statusMessage: 'Newsletter service is not configured'
})
}
// Build the redirection URL to the confirmation page
const redirectionUrl = `${config.public.siteUrl}/newsletter-bestaetigt`
try {
// Build request body for Brevo Double Opt-In API
const brevoBody = {
email,
templateId,
redirectionUrl,
includeListIds: [listId]
}
console.log('Brevo DOI request body:', brevoBody)
await $fetch('https://api.brevo.com/v3/contacts/doubleOptinConfirmation', {
method: 'POST',
headers: {
accept: 'application/json',
'api-key': config.brevoApiKey,
'content-type': 'application/json'
},
body: brevoBody
})
return {
success: true
}
} catch (error: unknown) {
// Handle Brevo API errors
const fetchError = error as { statusCode?: number; data?: { code?: string; message?: string } }
// Contact already exists (duplicate_parameter error) - treat as success
// User will receive another confirmation email
if (fetchError.data?.code === 'duplicate_parameter') {
return {
success: true,
message: 'Confirmation email sent'
}
}
console.error('Brevo API error:', fetchError.data || error)
throw createError({
statusCode: fetchError.statusCode || 500,
statusMessage: fetchError.data?.message || 'Failed to subscribe to newsletter'
})
}
})