Neah/app/api/parse-email/route.ts
2025-04-26 11:36:35 +02:00

113 lines
3.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { simpleParser } from 'mailparser';
import * as DOMPurify from 'isomorphic-dompurify';
import { cleanHtml as cleanHtmlCentralized } from '@/lib/mail-parser-wrapper';
interface EmailAddress {
name?: string;
address: string;
}
// Helper to extract email addresses from mailparser Address objects
function getEmailAddresses(addresses: any): EmailAddress[] {
if (!addresses) return [];
// Handle various address formats
if (Array.isArray(addresses)) {
return addresses.map(addr => ({
name: addr.name || undefined,
address: addr.address
}));
}
if (typeof addresses === 'object') {
const result: EmailAddress[] = [];
// Handle mailparser format with text, html, value properties
if (addresses.value) {
addresses.value.forEach((addr: any) => {
result.push({
name: addr.name || undefined,
address: addr.address
});
});
return result;
}
// Handle direct object with address property
if (addresses.address) {
return [{
name: addresses.name || undefined,
address: addresses.address
}];
}
}
return [];
}
/**
* @deprecated This function is deprecated and will be removed in future versions.
* Use the cleanHtml function from '@/lib/mail-parser-wrapper' instead.
* Maintained for backward compatibility only.
*/
function processHtml(html: string): string {
if (!html) return '';
// Delegate to the centralized implementation
return cleanHtmlCentralized(html, {
preserveStyles: true,
scopeStyles: true,
addWrapper: true
});
}
export async function POST(req: NextRequest) {
try {
const { email } = await req.json();
if (!email || typeof email !== 'string') {
return NextResponse.json(
{ error: 'Invalid email content' },
{ status: 400 }
);
}
const parsed = await simpleParser(email);
// Process the HTML content to make it safe and displayable
const html = parsed.html
? processHtml(parsed.html.toString())
: undefined;
const text = parsed.text
? parsed.text.toString()
: undefined;
// Extract attachments info if available
const attachments = parsed.attachments?.map(attachment => ({
filename: attachment.filename,
contentType: attachment.contentType,
contentDisposition: attachment.contentDisposition,
size: attachment.size
})) || [];
// Return all parsed email details
return NextResponse.json({
subject: parsed.subject,
from: getEmailAddresses(parsed.from),
to: getEmailAddresses(parsed.to),
cc: getEmailAddresses(parsed.cc),
bcc: getEmailAddresses(parsed.bcc),
date: parsed.date,
html,
text,
attachments
});
} catch (error) {
console.error('Error parsing email:', error);
return NextResponse.json(
{ error: 'Failed to parse email content' },
{ status: 500 }
);
}
}