@@ -6,6 +6,7 @@ import { getMailboxPathFromNodeParameter, parameterSelectMailbox } from "../../.
66import { emailSearchParameters , getEmailSearchParametersFromNode } from "../../../utils/EmailSearchParameters" ;
77import { simpleParser } from 'mailparser' ;
88import { getEmailPartsInfoRecursive } from "../../../utils/EmailParts" ;
9+ import { NodeHtmlMarkdown } from 'node-html-markdown' ;
910
1011
1112enum EmailParts {
@@ -48,54 +49,40 @@ function textToSimplifiedHtml(text: string): string {
4849 . replace ( / \r / g, '<br>' ) ;
4950}
5051
51- function formatEmailAddresses ( addresses : any [ ] ) : string [ ] {
52- if ( ! addresses || ! Array . isArray ( addresses ) ) return [ ] ;
5352
54- return addresses . map ( addr => {
55- if ( typeof addr === 'string' ) return addr ;
56- if ( addr . name && addr . address ) {
57- return `${ addr . name } <${ addr . address } >` ;
58- }
59- return addr . address || '' ;
60- } ) . filter ( addr => addr ) ;
53+ // Initialize HTML to Markdown converter
54+ const nhm = new NodeHtmlMarkdown ( ) ;
55+
56+ function htmlToMarkdown ( html : string ) : string {
57+ if ( ! html ) return '' ;
58+ return nhm . translate ( html ) ;
6159}
6260
63- function simplifyHtmlToReadable ( html : string ) : string {
61+ function htmlToText ( html : string ) : string {
6462 if ( ! html ) return '' ;
6563
6664 // Remove script and style elements completely
67- let simplified = html . replace ( / < s c r i p t [ ^ > ] * > [ \s \S ] * ?< \/ s c r i p t > / gi, '' ) ;
68- simplified = simplified . replace ( / < s t y l e [ ^ > ] * > [ \s \S ] * ?< \/ s t y l e > / gi, '' ) ;
65+ let text = html . replace ( / < s c r i p t [ ^ > ] * > [ \s \S ] * ?< \/ s c r i p t > / gi, '' ) ;
66+ text = text . replace ( / < s t y l e [ ^ > ] * > [ \s \S ] * ?< \/ s t y l e > / gi, '' ) ;
6967
70- // Convert common HTML elements to readable format
71- simplified = simplified
72- // Convert headers to readable format
73- . replace ( / < h [ 1 - 6 ] [ ^ > ] * > ( .* ?) < \/ h [ 1 - 6 ] > / gi, '\n\n$1\n' + '=' . repeat ( 50 ) + '\n' )
74- // Convert paragraphs
75- . replace ( / < p [ ^ > ] * > ( .* ?) < \/ p > / gi, '\n\n$1\n' )
68+ // Convert HTML elements to plain text
69+ text = text
7670 // Convert line breaks
7771 . replace ( / < b r [ ^ > ] * > / gi, '\n' )
78- // Convert divs to line breaks
72+ // Convert paragraphs
73+ . replace ( / < p [ ^ > ] * > ( .* ?) < \/ p > / gi, '\n\n$1\n\n' )
74+ // Convert headers
75+ . replace ( / < h [ 1 - 6 ] [ ^ > ] * > ( .* ?) < \/ h [ 1 - 6 ] > / gi, '\n\n$1\n\n' )
76+ // Convert divs
7977 . replace ( / < d i v [ ^ > ] * > ( .* ?) < \/ d i v > / gi, '\n$1\n' )
8078 // Convert lists
8179 . replace ( / < u l [ ^ > ] * > ( .* ?) < \/ u l > / gi, '\n$1\n' )
8280 . replace ( / < o l [ ^ > ] * > ( .* ?) < \/ o l > / gi, '\n$1\n' )
8381 . replace ( / < l i [ ^ > ] * > ( .* ?) < \/ l i > / gi, '• $1\n' )
8482 // Convert blockquotes
8583 . replace ( / < b l o c k q u o t e [ ^ > ] * > ( .* ?) < \/ b l o c k q u o t e > / gi, '\n> $1\n' )
86- // Convert links to readable format
84+ // Convert links to plain text with URL
8785 . replace ( / < a [ ^ > ] * h r e f = [ " ' ] ( [ ^ " ' ] * ) [ " ' ] [ ^ > ] * > ( .* ?) < \/ a > / gi, '$2 ($1)' )
88- // Convert emphasis
89- . replace ( / < ( s t r o n g | b ) [ ^ > ] * > ( .* ?) < \/ ( s t r o n g | b ) > / gi, '**$2**' )
90- . replace ( / < ( e m | i ) [ ^ > ] * > ( .* ?) < \/ ( e m | i ) > / gi, '*$2*' )
91- // Convert code
92- . replace ( / < c o d e [ ^ > ] * > ( .* ?) < \/ c o d e > / gi, '`$1`' )
93- . replace ( / < p r e [ ^ > ] * > ( .* ?) < \/ p r e > / gi, '\n```\n$1\n```\n' )
94- // Convert tables to readable format
95- . replace ( / < t a b l e [ ^ > ] * > ( .* ?) < \/ t a b l e > / gi, '\n$1\n' )
96- . replace ( / < t r [ ^ > ] * > ( .* ?) < \/ t r > / gi, '\n$1\n' )
97- . replace ( / < t d [ ^ > ] * > ( .* ?) < \/ t d > / gi, '$1 | ' )
98- . replace ( / < t h [ ^ > ] * > ( .* ?) < \/ t h > / gi, '$1 | ' )
9986 // Remove all remaining HTML tags
10087 . replace ( / < [ ^ > ] * > / g, '' )
10188 // Decode HTML entities
@@ -113,7 +100,7 @@ function simplifyHtmlToReadable(html: string): string {
113100 . replace ( / \n / g, '\n' ) // Remove leading spaces from lines
114101 . replace ( / \n / g, '\n' ) ; // Remove trailing spaces from lines
115102
116- return simplified . trim ( ) ;
103+ return text . trim ( ) ;
117104}
118105
119106
@@ -214,8 +201,8 @@ export const getEmailsListOperation: IResourceOperationDef = {
214201 name : 'enhancedFields' ,
215202 type : 'boolean' ,
216203 default : true ,
217- description : 'Whether to include email body content (text and HTML) in the results' ,
218- hint : 'Returns both text and HTML versions of the email body content' ,
204+ description : 'Whether to include email body content in the results' ,
205+ hint : 'Returns text, markdown, and html fields with email body content' ,
219206 }
220207 ] ,
221208 async executeImapAction ( context : IExecuteFunctions , itemIndex : number , client : ImapFlow ) : Promise < INodeExecutionData [ ] | null > {
@@ -322,18 +309,7 @@ export const getEmailsListOperation: IResourceOperationDef = {
322309 item_json . size = email . size ;
323310 }
324311
325- // Always include structured fields from envelope (clean format)
326- if ( email . envelope ) {
327- item_json . title = email . envelope . subject || '' ;
328- item_json . from = formatEmailAddresses ( email . envelope . from || [ ] ) ;
329- item_json . to = formatEmailAddresses ( email . envelope . to || [ ] ) ;
330- item_json . cc = formatEmailAddresses ( email . envelope . cc || [ ] ) ;
331- item_json . bcc = formatEmailAddresses ( email . envelope . bcc || [ ] ) ;
332- item_json . replyTo = formatEmailAddresses ( email . envelope . replyTo || [ ] ) ;
333- item_json . date = email . envelope . date ;
334- item_json . messageId = email . envelope . messageId ;
335- item_json . inReplyTo = email . envelope . inReplyTo ;
336- }
312+ // Note: All envelope fields are already included in the envelope object above
337313
338314 // process the headers
339315 if ( includeParts . includes ( EmailParts . Headers ) ) {
@@ -409,11 +385,11 @@ export const getEmailsListOperation: IResourceOperationDef = {
409385 if ( textContent . content ) {
410386 item_json . textContent = await streamToString ( textContent . content ) ;
411387
412- // if include body is enabled, also provide simplified HTML version
388+ // if include body is enabled, provide text content
413389 if ( enhancedFields ) {
414- item_json . contentText = item_json . textContent ;
415- item_json . contentHtml = textToSimplifiedHtml ( item_json . textContent ) ;
416- item_json . contentReadable = item_json . textContent ; // Text content is already readable
390+ item_json . text = item_json . textContent ;
391+ item_json . markdown = item_json . textContent ; // Plain text is already readable
392+ item_json . html = textToSimplifiedHtml ( item_json . textContent ) ;
417393 }
418394 }
419395 }
@@ -428,25 +404,24 @@ export const getEmailsListOperation: IResourceOperationDef = {
428404 if ( htmlContent . content ) {
429405 item_json . htmlContent = await streamToString ( htmlContent . content ) ;
430406
431- // if include body is enabled, also provide the HTML content
407+ // if include body is enabled, provide HTML content
432408 if ( enhancedFields ) {
433- item_json . contentHtml = item_json . htmlContent ;
434- // if we don't have text content, create readable text from the HTML content
435- if ( ! item_json . contentText ) {
436- item_json . contentText = simplifyHtmlToReadable ( item_json . htmlContent ) ;
409+ item_json . html = item_json . htmlContent ;
410+ item_json . markdown = htmlToMarkdown ( item_json . htmlContent ) ;
411+ // if we don't have text content, create plain text from the HTML content
412+ if ( ! item_json . text ) {
413+ item_json . text = htmlToText ( item_json . htmlContent ) ;
437414 }
438- // Always provide a readable version of the HTML content
439- item_json . contentReadable = simplifyHtmlToReadable ( item_json . htmlContent ) ;
440415 }
441416 }
442417 }
443418 }
444419
445420 // if include body is enabled but no content was found, set empty values
446- if ( enhancedFields && ! item_json . contentText && ! item_json . contentHtml ) {
447- item_json . contentText = '' ;
448- item_json . contentHtml = '' ;
449- item_json . contentReadable = '' ;
421+ if ( enhancedFields && ! item_json . text && ! item_json . html ) {
422+ item_json . text = '' ;
423+ item_json . markdown = '' ;
424+ item_json . html = '' ;
450425 }
451426 }
452427
0 commit comments