diff --git a/app/api/courrier/[id]/route.ts b/app/api/courrier/[id]/route.ts index e63ece0a..a9eb7759 100644 --- a/app/api/courrier/[id]/route.ts +++ b/app/api/courrier/[id]/route.ts @@ -135,6 +135,23 @@ export async function GET( attachmentsCount: parsedEmail.attachments ? parsedEmail.attachments.length : 0 }); + // 10. Prepare the full email object with all needed data + const rawEmail = { + id, + from: foundMessage.envelope.from?.[0]?.address || '', + fromName: foundMessage.envelope.from?.[0]?.name || + foundMessage.envelope.from?.[0]?.address?.split('@')[0] || '', + to: foundMessage.envelope.to?.map((addr: any) => addr.address).join(', ') || '', + subject: foundMessage.envelope.subject || '(No subject)', + date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(), + html: parsedEmail.html || '', + text: parsedEmail.text || '', + rawSource: foundMessage.source?.toString() || '', + read: foundMessage.flags.has('\\Seen'), + starred: foundMessage.flags.has('\\Flagged'), + folder: folder + }; + // 10. Prepare the full email object with all needed data const fullEmail = { id, @@ -144,19 +161,19 @@ export async function GET( to: foundMessage.envelope.to?.map((addr: any) => addr.address).join(', ') || '', subject: foundMessage.envelope.subject || '(No subject)', date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(), - content: typeof parsedEmail.html === 'string' ? parsedEmail.html : - typeof parsedEmail.text === 'string' ? parsedEmail.text : '', - textContent: typeof parsedEmail.text === 'string' ? parsedEmail.text : '', - rawContent: typeof foundMessage.source === 'object' ? - foundMessage.source.toString() : - String(foundMessage.source || ''), + // Use the raw fields directly to avoid any complex processing + content: parsedEmail.html || parsedEmail.text || '', + textContent: parsedEmail.text || '', + rawContent: foundMessage.source?.toString() || '', read: foundMessage.flags.has('\\Seen'), starred: foundMessage.flags.has('\\Flagged'), folder: folder, hasAttachments: foundMessage.bodyStructure?.type === 'multipart', attachments: parsedEmail.attachments || [], flags: Array.from(foundMessage.flags), - headers: parsedEmail.headers || {} + headers: parsedEmail.headers || {}, + // Include the raw email for debugging + _raw: rawEmail }; // Log the structure of the email being returned @@ -190,11 +207,14 @@ export async function GET( } } + // Deep clone and stringify the email object to ensure no circular references + const sanitizedEmail = JSON.parse(JSON.stringify(fullEmail)); + // 12. Cache the email content - emailContentCache.set(cacheKey, fullEmail); + emailContentCache.set(cacheKey, sanitizedEmail); // 13. Return the full email - return NextResponse.json(fullEmail); + return NextResponse.json(sanitizedEmail); } finally { // 14. Close the connection try { diff --git a/app/courrier/page.tsx b/app/courrier/page.tsx index 1212a36e..c6706174 100644 --- a/app/courrier/page.tsx +++ b/app/courrier/page.tsx @@ -103,6 +103,13 @@ function splitEmailHeadersAndBody(emailBody: string): { headers: string; body: s function EmailContent({ email }: { email: Email }) { // Improved debugging with more details console.log("EmailContent rendering with EMAIL OBJECT:", email); + + // Check if we have a raw object with content + const rawEmail = (email as any)._raw; + if (rawEmail) { + console.log("Found _raw email field:", rawEmail); + } + console.log("Content details:", { hasContent: Boolean(email.content), contentLength: email.content?.length || 0, @@ -113,7 +120,11 @@ function EmailContent({ email }: { email: Email }) { hasRawContent: Boolean(email.rawContent), rawContentLength: email.rawContent?.length || 0, hasBody: Boolean(email.body), - bodyLength: email.body?.length || 0 + bodyLength: email.body?.length || 0, + hasRawHtml: Boolean(rawEmail?.html), + rawHtmlLength: rawEmail?.html?.length || 0, + hasRawText: Boolean(rawEmail?.text), + rawTextLength: rawEmail?.text?.length || 0 }); // Use state to track if we've rendered content @@ -135,12 +146,39 @@ function EmailContent({ email }: { email: Email }) { const body = typeof email.body === 'object' ? JSON.stringify(email.body) : email.body; + + // Also try to get content from the _raw field if it exists + const rawHtml = rawEmail?.html || ''; + const rawText = rawEmail?.text || ''; // Use a more defensive approach with content const hasContent = content !== undefined && content !== null && content.trim() !== ''; const hasTextContent = textContent !== undefined && textContent !== null && textContent.trim() !== ''; const hasRawContent = rawContent !== undefined && rawContent !== null && rawContent.trim() !== ''; const hasBody = body !== undefined && body !== null && body.trim() !== ''; + const hasRawHtml = rawHtml !== undefined && rawHtml !== null && rawHtml.trim() !== ''; + const hasRawText = rawText !== undefined && rawText !== null && rawText.trim() !== ''; + + // Try raw text first (most reliable format) + if (hasRawText && !renderedContent) { + setRenderedContent(true); + return ( +
- Has text content: {hasTextContent ? 'Yes' : 'No'} (type: {typeof email.textContent})
- Has raw content: {hasRawContent ? 'Yes' : 'No'} (type: {typeof email.rawContent})
- Has body: {hasBody ? 'Yes' : 'No'} (type: {typeof email.body})
+- Has raw HTML: {hasRawHtml ? 'Yes' : 'No'}
+- Has raw text: {hasRawText ? 'Yes' : 'No'}
); @@ -1119,6 +1159,20 @@ export default function CourrierPage() { : selectedEmail.rawContent.substring(0, 500)}... : 'Empty'}HTML: {(selectedEmail as any)._raw.html + ? `${(selectedEmail as any)._raw.html.substring(0, 200)}...` + : 'Empty'}
+Text: {(selectedEmail as any)._raw.text + ? `${(selectedEmail as any)._raw.text.substring(0, 200)}...` + : 'Empty'}
+