panel 2 courier api
This commit is contained in:
parent
f573d79960
commit
eac631d72b
@ -144,9 +144,12 @@ export async function GET(
|
|||||||
to: foundMessage.envelope.to?.map((addr: any) => addr.address).join(', ') || '',
|
to: foundMessage.envelope.to?.map((addr: any) => addr.address).join(', ') || '',
|
||||||
subject: foundMessage.envelope.subject || '(No subject)',
|
subject: foundMessage.envelope.subject || '(No subject)',
|
||||||
date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(),
|
date: foundMessage.envelope.date?.toISOString() || new Date().toISOString(),
|
||||||
content: parsedEmail.html || parsedEmail.text || '',
|
content: typeof parsedEmail.html === 'string' ? parsedEmail.html :
|
||||||
textContent: parsedEmail.text || '',
|
typeof parsedEmail.text === 'string' ? parsedEmail.text : '',
|
||||||
rawContent: foundMessage.source.toString(), // Include raw content for fallback
|
textContent: typeof parsedEmail.text === 'string' ? parsedEmail.text : '',
|
||||||
|
rawContent: typeof foundMessage.source === 'object' ?
|
||||||
|
foundMessage.source.toString() :
|
||||||
|
String(foundMessage.source || ''),
|
||||||
read: foundMessage.flags.has('\\Seen'),
|
read: foundMessage.flags.has('\\Seen'),
|
||||||
starred: foundMessage.flags.has('\\Flagged'),
|
starred: foundMessage.flags.has('\\Flagged'),
|
||||||
folder: folder,
|
folder: folder,
|
||||||
|
|||||||
@ -106,8 +106,10 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
console.log("Content details:", {
|
console.log("Content details:", {
|
||||||
hasContent: Boolean(email.content),
|
hasContent: Boolean(email.content),
|
||||||
contentLength: email.content?.length || 0,
|
contentLength: email.content?.length || 0,
|
||||||
|
contentType: typeof email.content,
|
||||||
hasTextContent: Boolean(email.textContent),
|
hasTextContent: Boolean(email.textContent),
|
||||||
textContentLength: email.textContent?.length || 0,
|
textContentLength: email.textContent?.length || 0,
|
||||||
|
textContentType: typeof email.textContent,
|
||||||
hasRawContent: Boolean(email.rawContent),
|
hasRawContent: Boolean(email.rawContent),
|
||||||
rawContentLength: email.rawContent?.length || 0,
|
rawContentLength: email.rawContent?.length || 0,
|
||||||
hasBody: Boolean(email.body),
|
hasBody: Boolean(email.body),
|
||||||
@ -117,18 +119,35 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
// Use state to track if we've rendered content
|
// Use state to track if we've rendered content
|
||||||
const [renderedContent, setRenderedContent] = useState<boolean>(false);
|
const [renderedContent, setRenderedContent] = useState<boolean>(false);
|
||||||
|
|
||||||
|
// Special handling for potential nested content structure
|
||||||
|
const content = typeof email.content === 'object'
|
||||||
|
? JSON.stringify(email.content)
|
||||||
|
: email.content;
|
||||||
|
|
||||||
|
const textContent = typeof email.textContent === 'object'
|
||||||
|
? JSON.stringify(email.textContent)
|
||||||
|
: email.textContent;
|
||||||
|
|
||||||
|
const rawContent = typeof email.rawContent === 'object'
|
||||||
|
? JSON.stringify(email.rawContent)
|
||||||
|
: email.rawContent;
|
||||||
|
|
||||||
|
const body = typeof email.body === 'object'
|
||||||
|
? JSON.stringify(email.body)
|
||||||
|
: email.body;
|
||||||
|
|
||||||
// Use a more defensive approach with content
|
// Use a more defensive approach with content
|
||||||
const hasContent = email.content !== undefined && email.content !== null && email.content.trim() !== '';
|
const hasContent = content !== undefined && content !== null && content.trim() !== '';
|
||||||
const hasTextContent = email.textContent !== undefined && email.textContent !== null && email.textContent.trim() !== '';
|
const hasTextContent = textContent !== undefined && textContent !== null && textContent.trim() !== '';
|
||||||
const hasRawContent = email.rawContent !== undefined && email.rawContent !== null && email.rawContent.trim() !== '';
|
const hasRawContent = rawContent !== undefined && rawContent !== null && rawContent.trim() !== '';
|
||||||
const hasBody = email.body !== undefined && email.body !== null && email.body.trim() !== '';
|
const hasBody = body !== undefined && body !== null && body.trim() !== '';
|
||||||
|
|
||||||
// If textContent is available, render it directly
|
// If textContent is available, render it directly
|
||||||
if (hasTextContent && !renderedContent) {
|
if (hasTextContent && !renderedContent) {
|
||||||
setRenderedContent(true);
|
setRenderedContent(true);
|
||||||
return (
|
return (
|
||||||
<div className="email-content whitespace-pre-wrap">
|
<div className="email-content whitespace-pre-wrap">
|
||||||
{email.textContent || ''}
|
{textContent}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -139,7 +158,7 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
||||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(email.content || '') }}
|
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(content) }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -150,7 +169,7 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
className="email-content prose prose-sm max-w-none dark:prose-invert"
|
||||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(email.body || '') }}
|
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(body) }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -160,7 +179,7 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
setRenderedContent(true);
|
setRenderedContent(true);
|
||||||
return (
|
return (
|
||||||
<div className="email-content whitespace-pre-wrap text-sm bg-gray-50 p-3 rounded">
|
<div className="email-content whitespace-pre-wrap text-sm bg-gray-50 p-3 rounded">
|
||||||
{email.rawContent || ''}
|
{rawContent}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -171,10 +190,10 @@ function EmailContent({ email }: { email: Email }) {
|
|||||||
<p>No content available</p>
|
<p>No content available</p>
|
||||||
<div className="mt-2 p-2 bg-red-50 text-red-700 text-xs rounded">
|
<div className="mt-2 p-2 bg-red-50 text-red-700 text-xs rounded">
|
||||||
<p>Content flags:</p>
|
<p>Content flags:</p>
|
||||||
<p>- Has content: {hasContent ? 'Yes' : 'No'}</p>
|
<p>- Has content: {hasContent ? 'Yes' : 'No'} (type: {typeof email.content})</p>
|
||||||
<p>- Has text content: {hasTextContent ? 'Yes' : 'No'}</p>
|
<p>- Has text content: {hasTextContent ? 'Yes' : 'No'} (type: {typeof email.textContent})</p>
|
||||||
<p>- Has raw content: {hasRawContent ? 'Yes' : 'No'}</p>
|
<p>- Has raw content: {hasRawContent ? 'Yes' : 'No'} (type: {typeof email.rawContent})</p>
|
||||||
<p>- Has body: {hasBody ? 'Yes' : 'No'}</p>
|
<p>- Has body: {hasBody ? 'Yes' : 'No'} (type: {typeof email.body})</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -638,8 +657,20 @@ export default function CourrierPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullEmail = await response.json();
|
// Get the raw JSON string first to log it exactly as received
|
||||||
console.log("API RESPONSE for email:", JSON.stringify(fullEmail, null, 2));
|
const rawJsonText = await response.text();
|
||||||
|
console.log("Raw API response text:", rawJsonText);
|
||||||
|
|
||||||
|
// Then parse it
|
||||||
|
let fullEmail;
|
||||||
|
try {
|
||||||
|
fullEmail = JSON.parse(rawJsonText);
|
||||||
|
console.log("Parsed JSON API response:", fullEmail);
|
||||||
|
} catch (jsonError) {
|
||||||
|
console.error("Error parsing JSON response:", jsonError);
|
||||||
|
setSelectEmailLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a clean, processed version of the email ensuring all necessary fields exist
|
// Create a clean, processed version of the email ensuring all necessary fields exist
|
||||||
const processedEmail = {
|
const processedEmail = {
|
||||||
@ -658,7 +689,12 @@ export default function CourrierPage() {
|
|||||||
folder: fullEmail.folder || currentView
|
folder: fullEmail.folder || currentView
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Processed email for UI:", processedEmail);
|
console.log("Processed email for UI:", {
|
||||||
|
...processedEmail,
|
||||||
|
contentLength: processedEmail.content.length,
|
||||||
|
textContentLength: processedEmail.textContent.length,
|
||||||
|
rawContentLength: processedEmail.rawContent.length
|
||||||
|
});
|
||||||
|
|
||||||
// Set the selected email with complete information
|
// Set the selected email with complete information
|
||||||
setSelectedEmail(processedEmail);
|
setSelectedEmail(processedEmail);
|
||||||
@ -1060,13 +1096,28 @@ export default function CourrierPage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-xs overflow-auto max-h-[300px]">
|
<div className="text-xs overflow-auto max-h-[300px]">
|
||||||
<strong>Content:</strong> {selectedEmail.content
|
<strong>Content:</strong> {selectedEmail.content
|
||||||
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">{selectedEmail.content.substring(0, 500)}...</div>
|
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">
|
||||||
|
<p>Type: {typeof selectedEmail.content}</p>
|
||||||
|
<p>Value: {typeof selectedEmail.content === 'object'
|
||||||
|
? JSON.stringify(selectedEmail.content)
|
||||||
|
: selectedEmail.content.substring(0, 500)}...</p>
|
||||||
|
</div>
|
||||||
: 'Empty'}<br/>
|
: 'Empty'}<br/>
|
||||||
<strong>Text Content:</strong> {selectedEmail.textContent
|
<strong>Text Content:</strong> {selectedEmail.textContent
|
||||||
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">{selectedEmail.textContent.substring(0, 500)}...</div>
|
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">
|
||||||
|
<p>Type: {typeof selectedEmail.textContent}</p>
|
||||||
|
<p>Value: {typeof selectedEmail.textContent === 'object'
|
||||||
|
? JSON.stringify(selectedEmail.textContent)
|
||||||
|
: selectedEmail.textContent.substring(0, 500)}...</p>
|
||||||
|
</div>
|
||||||
: 'Empty'}<br/>
|
: 'Empty'}<br/>
|
||||||
<strong>Raw Content:</strong> {selectedEmail.rawContent
|
<strong>Raw Content:</strong> {selectedEmail.rawContent
|
||||||
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">{selectedEmail.rawContent.substring(0, 500)}...</div>
|
? <div className="mt-1 p-1 bg-white/80 rounded overflow-auto max-h-[100px]">
|
||||||
|
<p>Type: {typeof selectedEmail.rawContent}</p>
|
||||||
|
<p>Value: {typeof selectedEmail.rawContent === 'object'
|
||||||
|
? JSON.stringify(selectedEmail.rawContent)
|
||||||
|
: selectedEmail.rawContent.substring(0, 500)}...</p>
|
||||||
|
</div>
|
||||||
: 'Empty'}<br/>
|
: 'Empty'}<br/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import { simpleParser } from 'mailparser';
|
import { simpleParser } from 'mailparser';
|
||||||
|
|
||||||
function cleanHtml(html: string): string {
|
function cleanHtml(html: string | null | undefined): string {
|
||||||
|
if (!html) return '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Basic HTML cleaning without DOMPurify
|
// Basic HTML cleaning without DOMPurify
|
||||||
return html
|
return html
|
||||||
@ -17,7 +19,7 @@ function cleanHtml(html: string): string {
|
|||||||
.trim();
|
.trim();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error cleaning HTML:', error);
|
console.error('Error cleaning HTML:', error);
|
||||||
return html;
|
return html || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +33,25 @@ function getAddressText(address: any): string | null {
|
|||||||
|
|
||||||
export async function parseEmail(emailContent: string) {
|
export async function parseEmail(emailContent: string) {
|
||||||
try {
|
try {
|
||||||
|
// Add debug logging for the raw content length
|
||||||
|
console.log(`Starting to parse email content (length: ${emailContent ? emailContent.length : 0})`);
|
||||||
|
|
||||||
const parsed = await simpleParser(emailContent);
|
const parsed = await simpleParser(emailContent);
|
||||||
|
|
||||||
|
// Add debug logging for the parsed content
|
||||||
|
console.log('Parsed email fields:', {
|
||||||
|
hasSubject: !!parsed.subject,
|
||||||
|
hasHtml: !!parsed.html,
|
||||||
|
htmlLength: parsed.html?.length || 0,
|
||||||
|
hasText: !!parsed.text,
|
||||||
|
textLength: parsed.text?.length || 0,
|
||||||
|
attachmentsCount: parsed.attachments?.length || 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clean the HTML content if it exists
|
||||||
|
const cleanedHtml = parsed.html ? cleanHtml(parsed.html) : null;
|
||||||
|
|
||||||
|
// Return a properly structured object with all fields explicitly specified
|
||||||
return {
|
return {
|
||||||
subject: parsed.subject || null,
|
subject: parsed.subject || null,
|
||||||
from: getAddressText(parsed.from),
|
from: getAddressText(parsed.from),
|
||||||
@ -40,7 +59,7 @@ export async function parseEmail(emailContent: string) {
|
|||||||
cc: getAddressText(parsed.cc),
|
cc: getAddressText(parsed.cc),
|
||||||
bcc: getAddressText(parsed.bcc),
|
bcc: getAddressText(parsed.bcc),
|
||||||
date: parsed.date || null,
|
date: parsed.date || null,
|
||||||
html: parsed.html ? cleanHtml(parsed.html) : null,
|
html: cleanedHtml,
|
||||||
text: parsed.text || null,
|
text: parsed.text || null,
|
||||||
attachments: parsed.attachments || [],
|
attachments: parsed.attachments || [],
|
||||||
headers: Object.fromEntries(parsed.headers)
|
headers: Object.fromEntries(parsed.headers)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user