feat(landing): Add newsletter double-opt-in

This commit is contained in:
2026-01-14 17:37:00 +01:00
parent d8b7e193a9
commit 7a5b666032
5 changed files with 258 additions and 24 deletions

View File

@@ -29,29 +29,71 @@ export default defineEventHandler(async (event) => {
})
}
// 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 Contacts API
const brevoBody: {
email: string
updateEnabled: boolean
listIds?: number[]
} = {
// Build request body for Brevo Double Opt-In API
const brevoBody = {
email,
updateEnabled: true
templateId,
redirectionUrl,
includeListIds: [listId]
}
// Add list ID if configured
if (config.brevoNewsletterListId) {
const listId = parseInt(config.brevoNewsletterListId, 10)
if (!isNaN(listId)) {
brevoBody.listIds = [listId]
}
}
console.log('Brevo DOI request body:', brevoBody)
const response = await $fetch('https://api.brevo.com/v3/contacts', {
await $fetch('https://api.brevo.com/v3/contacts/doubleOptinConfirmation', {
method: 'POST',
headers: {
'accept': 'application/json',
accept: 'application/json',
'api-key': config.brevoApiKey,
'content-type': 'application/json'
},
@@ -59,18 +101,18 @@ export default defineEventHandler(async (event) => {
})
return {
success: true,
id: (response as { id?: number })?.id
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: 'Already subscribed'
message: 'Confirmation email sent'
}
}