UNPKG

@snehal96/unimail

Version:

Unified email fetching & document extraction layer for modern web apps

43 lines (42 loc) 2.51 kB
import { simpleParser } from 'mailparser'; export class EmailParserService { async parseEmail(rawEmail, providerMessageId, provider) { try { const parsed = await simpleParser(rawEmail); const attachments = (parsed.attachments || []).map(att => ({ filename: att.filename || 'untitled', mimeType: att.contentType, size: att.size, buffer: Buffer.isBuffer(att.content) ? att.content : undefined, contentId: att.contentId, })); // Filter out inline images if they are not explicitly requested or handled differently // For now, we include all. PRD: "Skips inline images" - this needs more specific logic. // A common way is to check `att.contentDisposition === 'inline'` or if it has a contentId referenced in HTML. return { id: providerMessageId, // Use provider's ID threadId: parsed.messageId, // mailparser's messageId might be useful, or use provider's threadId from: parsed.from?.text || '', to: Array.isArray(parsed.to) ? parsed.to.flatMap(addr => addr.text.split(',').map((t) => t.trim())) : (parsed.to?.text.split(',').map((t) => t.trim()) || []), cc: Array.isArray(parsed.cc) ? parsed.cc.flatMap(addr => addr.text.split(',').map((t) => t.trim())) : (parsed.cc?.text.split(',').map((t) => t.trim()) || []), subject: parsed.subject, bodyText: parsed.text, bodyHtml: parsed.html || undefined, // Ensure it's string or undefined attachments, date: parsed.date || new Date(), labels: parsed.references ? (Array.isArray(parsed.references) ? parsed.references : [parsed.references]) : [], // Example, Gmail labels are different provider, raw: parsed // Optionally include the full parsed object }; } catch (error) { console.error('Error parsing email:', error); throw new Error(`Failed to parse email: ${error.message}`); } } static isInlineAttachment(attachment) { // Basic check for inline disposition. More sophisticated checks might be needed. // e.g., checking if contentId is referenced in the HTML body. return attachment.contentDisposition === 'inline' || (!!attachment.contentId && attachment.contentId.startsWith('<')); } }