// src/hooks/sendNewsletterConfirmation.ts import type { CollectionAfterChangeHook } from 'payload' import type { NewsletterSubscriber, Tenant } from '../payload-types' import { sendTenantEmail } from '../lib/email/tenant-email-service' import { getConfirmationEmailHtml, getConfirmationEmailText, type NewsletterTemplateData, } from '../lib/email/newsletter-templates' /** * Hook: Sendet automatisch Double Opt-In E-Mail bei neuen Newsletter-Anmeldungen * * Wird nur bei neuen Subscribern mit Status "pending" ausgeführt. * Vermeidet doppelten Versand durch Prüfung ob E-Mail bereits über API/Service gesendet wurde. * * Der Hook wird NICHT ausgeführt wenn: * - Die Erstellung via overrideAccess erfolgt (Newsletter-Service nutzt dies) * - Ein Kontext-Flag gesetzt ist */ export const sendNewsletterConfirmation: CollectionAfterChangeHook = async ({ doc, operation, req, previousDoc, context, }) => { // Skip wenn via Newsletter-Service erstellt (verwendet overrideAccess) // Der Service sendet die E-Mail selbst if (context?.skipNewsletterEmail) { return doc } // Nur bei neuen Anmeldungen (create) oder wenn Status auf "pending" geändert wird const isNew = operation === 'create' const isResubscribe = operation === 'update' && previousDoc?.status === 'unsubscribed' && doc.status === 'pending' if (!isNew && !isResubscribe) { return doc } // Nur bei Status "pending" (Double Opt-In ausstehend) if (doc.status !== 'pending') { return doc } // Prüfen ob Token vorhanden if (!doc.confirmationToken) { console.warn('[Newsletter] No confirmation token found for subscriber:', doc.id) return doc } // Tenant-ID ermitteln const tenantId = typeof doc.tenant === 'object' ? doc.tenant?.id : doc.tenant if (!tenantId) { console.warn('[Newsletter] No tenant found for subscriber:', doc.id) return doc } try { // Tenant laden const tenant = (await req.payload.findByID({ collection: 'tenants', id: tenantId, depth: 0, })) as Tenant if (!tenant) { console.error('[Newsletter] Tenant not found:', tenantId) return doc } // Template-Daten zusammenstellen const baseUrl = process.env.PAYLOAD_PUBLIC_SERVER_URL || 'https://pl.c2sgmbh.de' const tenantWebsite = tenant.domains?.[0]?.domain ? `https://${tenant.domains[0].domain}` : undefined const templateData: NewsletterTemplateData = { firstName: doc.firstName || undefined, email: doc.email, confirmationUrl: `${baseUrl}/api/newsletter/confirm?token=${doc.confirmationToken}`, // Für Confirmation-E-Mail Token verwenden (noch gültig), aber ID als Fallback unsubscribeUrl: `${baseUrl}/api/newsletter/unsubscribe?token=${doc.confirmationToken || doc.id}`, tenantName: tenant.name, tenantWebsite, privacyPolicyUrl: tenantWebsite ? `${tenantWebsite}/datenschutz` : undefined, } // Double Opt-In E-Mail senden const result = await sendTenantEmail(req.payload, tenantId, { to: doc.email, subject: `Newsletter-Anmeldung bestätigen - ${tenant.name}`, html: getConfirmationEmailHtml(templateData), text: getConfirmationEmailText(templateData), source: 'newsletter', metadata: { type: 'double-opt-in', subscriberId: doc.id, triggeredBy: 'hook', }, }) if (result.success) { console.log(`[Newsletter] Confirmation email sent to ${doc.email}`) } else { console.error(`[Newsletter] Failed to send confirmation email to ${doc.email}:`, result.error) } } catch (error) { console.error('[Newsletter] Error sending confirmation email:', error) } return doc }