diff --git a/lib/utils/email-utils.ts b/lib/utils/email-utils.ts index e0b2999f..cc75815d 100644 --- a/lib/utils/email-utils.ts +++ b/lib/utils/email-utils.ts @@ -346,112 +346,51 @@ export function formatReplyEmail(originalEmail: EmailMessage | LegacyEmailMessag // Get header information const { fromStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail); - // Extract content using centralized utility - get simpler text version when possible - const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail); - - // Simpler approach - prefer text content when available for clean replies - let replyBody = ''; - let textReply = ''; + // Extract just the text content for a clean reply + let emailText = ''; - // Create a header that works in both HTML and plain text - const headerHtml = `
On ${dateStr}, ${fromStr} wrote:
`; - - // Use extracted text content when available for cleaner replies - if (originalTextContent) { - // Use text content with proper line breaks - limit to a reasonable size - const maxChars = 1500; - const truncatedText = originalTextContent.length > maxChars - ? originalTextContent.slice(0, maxChars) + '... [message truncated]' - : originalTextContent; - - replyBody = ` - ${headerHtml} -
- ${truncatedText.replace(/\n/g, '
')} -
- `; - - textReply = ` -On ${dateStr}, ${fromStr} wrote: -> ${truncatedText.split('\n').join('\n> ')} - `; + // Try to get text directly from content.text first + if (originalEmail.content && typeof originalEmail.content === 'object' && originalEmail.content.text) { + emailText = originalEmail.content.text; } - // If no text, try to sanitize and simplify HTML - else if (originalHtmlContent) { - try { - // Sanitize the original HTML to remove problematic elements and simplify - const sanitizedHtml = sanitizeHtml(originalHtmlContent); - - // Extract the text content from the sanitized HTML for the plaintext version - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = sanitizedHtml; - const extractedText = tempDiv.textContent || tempDiv.innerText || ''; - - // Limit to a reasonable size - const maxChars = 1500; - const truncatedText = extractedText.length > maxChars - ? extractedText.slice(0, maxChars) + '... [message truncated]' - : extractedText; - - replyBody = ` - ${headerHtml} -
- ${truncatedText.replace(/\n/g, '
')} -
- `; - - textReply = ` + // Otherwise, fall back to extractEmailContent which tries various formats + else { + const { text } = extractEmailContent(originalEmail); + emailText = text; + } + + // Create simple reply with header + const cleanReplyHeader = `
On ${dateStr}, ${fromStr} wrote:
`; + + // Limit text to reasonable size and format as simple HTML + const maxChars = 1000; + const truncatedText = emailText.length > maxChars + ? emailText.slice(0, maxChars) + '... [message truncated]' + : emailText; + + const cleanHtml = ` + ${cleanReplyHeader} +
+

${truncatedText.replace(/\n/g, '

')}

+
+ `; + + // Plain text version + const plainText = ` On ${dateStr}, ${fromStr} wrote: > ${truncatedText.split('\n').join('\n> ')} - `; - } catch (error) { - console.error('Error processing HTML for reply:', error); - // Fallback to a basic template if everything fails - replyBody = ` - ${headerHtml} -
- [Original message content could not be processed] -
- `; - - textReply = ` -On ${dateStr}, ${fromStr} wrote: -> [Original message content could not be processed] - `; - } - } else { - // Empty or unrecognized content - replyBody = ` - ${headerHtml} -
- [Original message content not available] -
- `; - - textReply = ` -On ${dateStr}, ${fromStr} wrote: -> [Original message content not available] - `; - } - - // Process the content with proper direction - const processed = processContentWithDirection(replyBody); - - // Extract any inline images as attachments - const inlineImages = extractInlineImages(originalHtmlContent); + `; return { to, cc, subject: subject.startsWith('Re:') ? subject : `Re: ${subject}`, content: { - text: textReply.trim(), - html: processed.html, + text: plainText.trim(), + html: cleanHtml, isHtml: true, - direction: processed.direction - }, - // Include inline images as attachments if any were found - attachments: inlineImages.length > 0 ? inlineImages : undefined + direction: 'ltr' + } }; } @@ -475,17 +414,23 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe // Get header information const { fromStr, toStr, ccStr, dateStr, subject } = getFormattedHeaderInfo(originalEmail); - // Extract content using centralized utility - get simpler text version when possible - const { text: originalTextContent, html: originalHtmlContent } = extractEmailContent(originalEmail); - - // Simpler approach - prefer text content when available for clean forwards - let forwardBody = ''; - let textForward = ''; + // Extract just the text content for a clean forward + let emailText = ''; - // Create metadata header that works in both HTML and plain text - const headerHtml = ` -
-
---------- Forwarded message ---------
+ // Try to get text directly from content.text first + if (originalEmail.content && typeof originalEmail.content === 'object' && originalEmail.content.text) { + emailText = originalEmail.content.text; + } + // Otherwise, fall back to extractEmailContent which tries various formats + else { + const { text } = extractEmailContent(originalEmail); + emailText = text; + } + + // Create simple forward with metadata header + const cleanForwardHeader = ` +
+
---------- Forwarded message ---------
From: ${fromStr}
Date: ${dateStr}
Subject: ${subject || ''}
@@ -494,22 +439,21 @@ export function formatForwardedEmail(originalEmail: EmailMessage | LegacyEmailMe
`; - // Use extracted text content when available for cleaner forwards - if (originalTextContent) { - // Use text content with proper line breaks - limit to a reasonable size - const maxChars = 2000; - const truncatedText = originalTextContent.length > maxChars - ? originalTextContent.slice(0, maxChars) + '... [message truncated]' - : originalTextContent; - - forwardBody = ` - ${headerHtml} -
- ${truncatedText.replace(/\n/g, '
')} -
- `; - - textForward = ` + // Limit text to reasonable size and format as simple HTML + const maxChars = 1500; + const truncatedText = emailText.length > maxChars + ? emailText.slice(0, maxChars) + '... [message truncated]' + : emailText; + + const cleanHtml = ` + ${cleanForwardHeader} +
+

${truncatedText.replace(/\n/g, '

')}

+
+ `; + + // Plain text version + const plainText = ` ---------- Forwarded message --------- From: ${fromStr} Date: ${dateStr} @@ -518,114 +462,26 @@ To: ${toStr} ${ccStr ? `Cc: ${ccStr}\n` : ''} ${truncatedText} - `; - } - // If no text, try to sanitize and simplify HTML - else if (originalHtmlContent) { - try { - // Sanitize the original HTML to remove problematic elements and simplify - const sanitizedHtml = sanitizeHtml(originalHtmlContent); - - // Extract the text content from the sanitized HTML for the plaintext version - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = sanitizedHtml; - const extractedText = tempDiv.textContent || tempDiv.innerText || ''; - - // Limit to a reasonable size - const maxChars = 2000; - const truncatedText = extractedText.length > maxChars - ? extractedText.slice(0, maxChars) + '... [message truncated]' - : extractedText; - - forwardBody = ` - ${headerHtml} -
- ${truncatedText.replace(/\n/g, '
')} -
- `; - - textForward = ` ----------- Forwarded message --------- -From: ${fromStr} -Date: ${dateStr} -Subject: ${subject || ''} -To: ${toStr} -${ccStr ? `Cc: ${ccStr}\n` : ''} + `; -${truncatedText} - `; - } catch (error) { - console.error('Error processing HTML for forward:', error); - // Fallback to a basic template if everything fails - forwardBody = ` - ${headerHtml} -
- [Original message content could not be processed] -
- `; - - textForward = ` ----------- Forwarded message --------- -From: ${fromStr} -Date: ${dateStr} -Subject: ${subject || ''} -To: ${toStr} -${ccStr ? `Cc: ${ccStr}\n` : ''} - -[Original message content could not be processed] - `; - } - } else { - // Empty or unrecognized content - forwardBody = ` - ${headerHtml} -
- [Original message content not available] -
- `; - - textForward = ` ----------- Forwarded message --------- -From: ${fromStr} -Date: ${dateStr} -Subject: ${subject || ''} -To: ${toStr} -${ccStr ? `Cc: ${ccStr}\n` : ''} - -[Original message content not available] - `; - } - - // Process the content with proper direction - const processed = processContentWithDirection(forwardBody); - - // Check if the original email has attachments - const originalAttachments = originalEmail.attachments || []; - - // Extract any inline images and add to attachments - const inlineImages = extractInlineImages(originalHtmlContent); - - // Combine original attachments and inline images - const combinedAttachments = [ - ...originalAttachments.map(att => ({ - filename: att.filename || 'attachment', - contentType: att.contentType || 'application/octet-stream', - content: att.content - })), - ...inlineImages - ]; + // Check if original has attachments + const attachments = originalEmail.attachments || []; return { to: '', subject: subject.startsWith('Fwd:') ? subject : `Fwd: ${subject}`, content: { - text: textForward.trim(), - html: processed.html, + text: plainText.trim(), + html: cleanHtml, isHtml: true, direction: 'ltr' }, - // Include attachments if any were found - attachments: combinedAttachments.length > 0 ? combinedAttachments : undefined + // Only include attachments if they exist + attachments: attachments.length > 0 ? attachments.map(att => ({ + filename: att.filename || 'attachment', + contentType: att.contentType || 'application/octet-stream', + content: att.content + })) : undefined }; }