import nodemailer from 'nodemailer'
import errorHandlingHelper from "../../../utils/errorHandlingHelper"
/**
* Email shipping labels (DHL or DPD) as PDF attachments.
*
* Body: {
* toEmail: string (required)
* ccEmail?: string
* subject?: string
* carrier?: 'dhl' | 'dpd' (cosmetic — used in subject/body)
* labels: Array<{ tracking_number: string; label_b64: string }> (required, 1+)
* }
*/
interface LabelInput {
tracking_number?: string
label_b64?: string
}
const isValidEmail = (s: any) => typeof s === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s.trim())
const buildHtml = (carrier: string, count: number, trackingNumbers: string[]) => {
const c = (carrier || 'shipping').toUpperCase()
const trackingList = trackingNumbers.map(t => `
${t}`).join('')
return `
${c} Shipping Label${count > 1 ? 's' : ''} |
|
Attached you'll find ${count > 1 ? `${count} shipping labels` : 'the shipping label'} from ${c}.
Tracking number${count > 1 ? 's' : ''}:
Sent automatically by LogShip ERP.
|
|
`
}
export default defineEventHandler(async (event) => {
try {
const body = await readBody(event)
const toEmail = String(body.toEmail || '').trim()
const ccEmail = body.ccEmail ? String(body.ccEmail).trim() : ''
const carrier = String(body.carrier || '').toLowerCase()
const labels: LabelInput[] = Array.isArray(body.labels) ? body.labels : []
if (!isValidEmail(toEmail)) {
return { status: 400, message: 'A valid recipient email is required' }
}
if (ccEmail && !isValidEmail(ccEmail)) {
return { status: 400, message: 'CC email is not valid' }
}
const validLabels = labels.filter(l => typeof l?.label_b64 === 'string' && l.label_b64.length > 0)
if (validLabels.length === 0) {
return { status: 400, message: 'No label PDFs provided' }
}
const trackingNumbers = validLabels.map(l => l.tracking_number || '—')
const carrierTag = carrier ? carrier.toUpperCase() : 'LABEL'
const attachments = validLabels.map((l, i) => ({
filename: `${carrierTag}-${l.tracking_number || `label-${i + 1}`}.pdf`,
content: Buffer.from(l.label_b64 || '', 'base64'),
contentType: 'application/pdf'
}))
const subject = String(body.subject || '').trim()
|| `${carrierTag} shipping label${validLabels.length > 1 ? 's' : ''} (${trackingNumbers.join(', ')})`
const transporter = nodemailer.createTransport({
host: 'localhost', port: 25, secure: false,
tls: { rejectUnauthorized: false }
})
const emailOptions: any = {
from: 'no-reply@logyou.de',
to: toEmail,
subject,
html: buildHtml(carrier, validLabels.length, trackingNumbers),
attachments
}
if (ccEmail) emailOptions.cc = ccEmail
try {
const info = await transporter.sendMail(emailOptions)
return { status: 200, message: 'Label email sent', messageId: info?.messageId, attachments: validLabels.length }
} catch (err: any) {
console.error('[Label Email] Send error:', err)
return { status: 500, message: `Failed to send email: ${err.message || err}` }
}
} catch (err: any) {
return errorHandlingHelper(err?.data ?? err, err?.data ?? err)
}
})