UNPKG

n8n-nodes-imap-ai

Version:

Simplified IMAP node for n8n with AI-agent support. Clean and modular email and mailbox management for automation workflows.

509 lines 23.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getEmailsListOperation = void 0; const mailparser_1 = require("mailparser"); const EmailParts_1 = require("../../../shared/constants/EmailParts"); const ParameterHelpers_1 = require("../../../shared/utils/ParameterHelpers"); const StreamHelpers_1 = require("../../../shared/utils/StreamHelpers"); const EmailParts_2 = require("../../../utils/EmailParts"); const SearchFieldParameters_1 = require("../../../utils/SearchFieldParameters"); exports.getEmailsListOperation = { operation: { name: 'Get Many', value: 'getEmailsList', description: 'Retrieve emails from an IMAP mailbox with advanced search and filtering capabilities. Perfect for AI agents to find specific emails, analyze content, or process email data automatically.', }, parameters: [ { ...SearchFieldParameters_1.parameterSelectMailbox, description: 'Select the mailbox to search for emails. AI agents can specify: INBOX, Sent, Drafts, or custom folder names.', }, { displayName: 'Date Range', name: 'emailDateRange', type: 'collection', placeholder: 'Add Date Range', default: { since: '' }, description: "Filter emails by date range. AI agents can specify dates like 'last week', 'yesterday', or specific dates.", options: [ { displayName: 'Since Date', name: 'since', type: 'dateTime', default: '', description: "Start date of search. AI can specify: 'yesterday', 'last week', '2024-01-01', etc.", }, { displayName: 'Before Date', name: 'before', type: 'dateTime', default: '', description: "End date of search. AI can specify: 'today', 'last month', '2024-12-31', etc.", }, ], }, { displayName: 'Email Flags Filter', name: 'emailFlags', type: 'collection', placeholder: 'Add Flag Filter', default: {}, description: "Filter emails by their status flags. AI can specify: 'unread emails', 'flagged emails', 'draft emails', etc.", options: [ { displayName: 'Is Answered', name: 'answered', type: 'boolean', default: false, description: 'Whether emails have been replied to', }, { displayName: 'Is Deleted', name: 'deleted', type: 'boolean', default: false, description: 'Whether emails are marked for deletion', }, { displayName: 'Is Draft', name: 'draft', type: 'boolean', default: false, description: 'Whether emails are drafts (unsent emails)', }, { displayName: 'Is Flagged', name: 'flagged', type: 'boolean', default: false, description: 'Whether emails are important/flagged', }, { displayName: 'Is Read/Unread', name: 'seen', type: 'boolean', default: false, description: 'Whether emails are read (true) or unread (false)', }, { displayName: 'Is Recent', name: 'recent', type: 'boolean', default: false, description: 'Whether emails are recently received', }, ], }, { displayName: 'Email Search Filters', name: 'emailSearchFilters', type: 'collection', placeholder: 'Add Search Filter', default: {}, description: 'Advanced search filters for finding specific emails. AI can intelligently populate these based on natural language requests.', options: [ { displayName: 'BCC Email Address', name: 'bcc', type: 'string', default: "={{ $fromAI('bcc_email', 'Email address in BCC field') }}", description: 'Email address or name in BCC field', placeholder: 'admin@company.com', }, { displayName: 'CC Email Address', name: 'cc', type: 'string', default: "={{ $fromAI('cc_email', 'Email address in CC field') }}", description: 'Email address or name in CC field', placeholder: 'manager@company.com', }, { displayName: 'Email Content Contains', name: 'text', type: 'string', default: "={{ $fromAI('content_keywords', 'Keywords to search in email body content') }}", description: 'Search for specific text in email body content', placeholder: 'password reset, order confirmation, delivery', }, { displayName: 'From Email Address', name: 'from', type: 'string', default: "={{ $fromAI('sender_email', 'Email address of the sender to search for') }}", description: 'Email address or name of the sender', placeholder: 'john@example.com or John Doe', }, { displayName: 'Specific Email UIDs', name: 'uid', type: 'string', default: "={{ $fromAI('email_uids', 'Comma-separated list of specific email UIDs to retrieve') }}", description: 'Comma-separated list of specific email UIDs', placeholder: '1,2,3,15,42', }, { displayName: 'Subject Contains', name: 'subject', type: 'string', default: "={{ $fromAI('subject_keywords', 'Keywords to search in email subject line') }}", description: 'Search for specific text in email subject line', placeholder: 'invoice, meeting, urgent, project update', }, { displayName: 'To Email Address', name: 'to', type: 'string', default: "={{ $fromAI('recipient_email', 'Email address of the recipient to search for') }}", description: 'Email address or name of the recipient', placeholder: 'support@company.com or Support Team', }, ], }, { displayName: 'Email Content to Include', name: 'includeParts', type: 'multiOptions', placeholder: 'Select Content Types', default: [], description: 'Select which parts of the email to include in the response. AI agents can choose based on their specific needs.', options: [ { name: 'Text Content (Plain Text)', value: EmailParts_1.EmailParts.TextContent, description: 'Include the plain text content - ideal for reading and analysis', }, { name: 'HTML Content', value: EmailParts_1.EmailParts.HtmlContent, description: 'Include HTML formatted content - useful for preserving formatting', }, { name: 'Attachments Info', value: EmailParts_1.EmailParts.AttachmentsInfo, description: 'Include attachment information - useful for file processing', }, { name: 'Email Flags', value: EmailParts_1.EmailParts.Flags, description: 'Include email status flags - useful for status analysis', }, { name: 'Email Size', value: EmailParts_1.EmailParts.Size, description: 'Include email size in bytes - useful for storage analysis', }, { name: 'Email Structure', value: EmailParts_1.EmailParts.BodyStructure, description: 'Include technical email structure - useful for advanced processing', }, { name: 'Email Headers', value: EmailParts_1.EmailParts.Headers, description: 'Include email headers - useful for routing and technical analysis', }, ], }, { displayName: 'Include All Headers', name: 'includeAllHeaders', type: 'boolean', default: true, description: 'Whether to include all email headers or only specific ones', displayOptions: { show: { includeParts: [EmailParts_1.EmailParts.Headers], }, }, }, { displayName: 'Headers to Include', name: 'headersToInclude', type: 'string', default: "={{ $fromAI('email_headers', 'Comma-separated list of specific email headers to include for analysis') }}", description: 'Comma-separated list of specific email headers to include', placeholder: 'received,authentication-results,return-path,date,message-ID', displayOptions: { show: { includeParts: [EmailParts_1.EmailParts.Headers], includeAllHeaders: [false], }, }, }, { displayName: 'Maximum Results', name: 'maxResults', type: 'number', default: 10, description: 'Maximum number of emails to return. AI agents should use small numbers for "latest" searches (10-50) to avoid data overload.', placeholder: '10', typeOptions: { minValue: 1, maxValue: 1000, }, }, { displayName: 'From Email Address (AI Direct)', name: 'From_Email_Address', type: 'string', default: "={{ $fromAI('from_email', 'Email address or name of sender to search for. Can use partial names like \"conny\" for fuzzy matching.') }}", description: 'Direct AI parameter for sender email address or name. Supports partial matching - e.g., "conny" will find "conny@domain.com" and "Conny Smith".', placeholder: 'conny, john@example.com, or "John Doe"', }, { displayName: 'Subject Contains (AI Direct)', name: 'Subject_Contains', type: 'string', default: "={{ $fromAI('subject_contains', 'Keywords or phrases to search in email subject. Supports partial matching.') }}", description: 'Direct AI parameter for subject keywords. Supports partial matching - e.g., "meeting" finds "Team Meeting" and "Meeting Notes".', placeholder: 'meeting, urgent, invoice, "project update"', }, { displayName: 'Email Content Contains (AI Direct)', name: 'Email_Content_Contains', type: 'string', default: "={{ $fromAI('content_contains', 'Keywords or phrases to search in email content. Supports partial matching.') }}", description: 'Direct AI parameter for content keywords. Supports partial matching - finds text anywhere in email body.', placeholder: 'password, confirmation, delivery, "thank you"', }, { displayName: 'To Email Address (AI Direct)', name: 'To_Email_Address', type: 'string', default: "={{ $fromAI('to_email', 'Email address or name of recipient to search for. Can use partial names for fuzzy matching.') }}", description: 'Direct AI parameter for recipient email address or name. Supports partial matching like sender field.', placeholder: 'support, admin@company.com, or "Support Team"', }, { displayName: 'Since Date (AI Direct)', name: 'Since_Date', type: 'string', default: "={{ $fromAI('since_date', 'Start date for email search (YYYY-MM-DD format)') }}", description: 'Direct AI parameter for start date', placeholder: '2025-01-01', }, { displayName: 'Before Date (AI Direct)', name: 'Before_Date', type: 'string', default: "={{ $fromAI('before_date', 'End date for email search (YYYY-MM-DD format)') }}", description: 'Direct AI parameter for end date', placeholder: '2025-12-31', }, { displayName: 'Show Unread Only (AI Direct)', name: 'Show_Unread_Only', type: 'boolean', default: false, description: 'Whether to show only unread emails', }, { displayName: 'Include Email Content (AI Direct)', name: 'Include_Email_Content', type: 'boolean', default: true, description: 'Whether to include email text content in response', }, { displayName: 'Include All Headers (AI Direct)', name: 'Include_All_Headers', type: 'boolean', default: false, description: 'Whether to include all email headers in the response', }, { displayName: 'Maximum Results (AI Direct)', name: 'Maximum_Results', type: 'number', default: 10, description: 'Direct AI parameter for limiting results', placeholder: '10', typeOptions: { minValue: 1, maxValue: 1000, }, }, { displayName: 'Sort By Latest First (AI Direct)', name: 'Sort_By_Latest_First', type: 'boolean', default: true, description: 'Whether to sort emails by newest first (recommended for "latest" or "recent" searches)', }, ], async executeImapAction(context, itemIndex, client) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; const returnData = []; const mailboxPath = (0, SearchFieldParameters_1.getMailboxPathFromNodeParameter)(context, itemIndex); (_a = context.logger) === null || _a === void 0 ? void 0 : _a.info(`Getting emails list from ${mailboxPath}`); await client.mailboxOpen(mailboxPath); const searchObject = (0, ParameterHelpers_1.getEmailSearchParametersFromNode)(context, itemIndex); const interfaceMode = context.getNodeParameter('interfaceMode', itemIndex, 'ai_simple'); let includeParts = []; let includeAllHeaders = false; if (interfaceMode === 'ai_simple') { const includeEmailContent = context.getNodeParameter('Include_Email_Content', itemIndex, true, { extractValue: true }); includeAllHeaders = context.getNodeParameter('Include_All_Headers', itemIndex, false, { extractValue: true, }); if (includeEmailContent) { includeParts.push(EmailParts_1.EmailParts.TextContent); } if (includeAllHeaders) { includeParts.push(EmailParts_1.EmailParts.Headers); } includeParts.push(EmailParts_1.EmailParts.Flags); } else { includeParts = context.getNodeParameter('includeParts', itemIndex, []); if (includeParts.includes(EmailParts_1.EmailParts.Headers)) { includeAllHeaders = context.getNodeParameter('includeAllHeaders', itemIndex, true); } } const fetchQuery = { uid: true, envelope: true, }; if (includeParts.includes(EmailParts_1.EmailParts.BodyStructure)) { fetchQuery.bodyStructure = true; } if (includeParts.includes(EmailParts_1.EmailParts.Flags)) { fetchQuery.flags = true; } if (includeParts.includes(EmailParts_1.EmailParts.Size)) { fetchQuery.size = true; } if (includeParts.includes(EmailParts_1.EmailParts.Headers)) { fetchQuery.headers = true; if (interfaceMode !== 'ai_simple' && !includeAllHeaders) { const headersToInclude = context.getNodeParameter('headersToInclude', itemIndex, ''); (_b = context.logger) === null || _b === void 0 ? void 0 : _b.info(`Including headers: ${headersToInclude}`); if (headersToInclude) { fetchQuery.headers = headersToInclude.split(',').map((header) => header.trim()); (_c = context.logger) === null || _c === void 0 ? void 0 : _c.info(`Including headers: ${fetchQuery.headers}`); } } } const includeAttachmentsInfo = includeParts.includes(EmailParts_1.EmailParts.AttachmentsInfo); if (includeAttachmentsInfo) { fetchQuery.bodyStructure = true; } const includeTextContent = includeParts.includes(EmailParts_1.EmailParts.TextContent); const includeHtmlContent = includeParts.includes(EmailParts_1.EmailParts.HtmlContent); if (includeTextContent || includeHtmlContent) { fetchQuery.bodyStructure = true; } (_d = context.logger) === null || _d === void 0 ? void 0 : _d.debug(`Search object: ${JSON.stringify(searchObject)}`); (_e = context.logger) === null || _e === void 0 ? void 0 : _e.debug(`Fetch query: ${JSON.stringify(fetchQuery)}`); let maxResults = context.getNodeParameter('Maximum_Results', itemIndex, 0, { extractValue: true, }); if (!maxResults || maxResults === 0) { maxResults = context.getNodeParameter('maxResults', itemIndex, 10); } (_f = context.logger) === null || _f === void 0 ? void 0 : _f.info(`Limiting results to ${maxResults} emails`); const emailsList = []; let emailCount = 0; for await (const email of client.fetch(searchObject, fetchQuery)) { emailsList.push(email); emailCount++; if (emailCount >= maxResults) { (_g = context.logger) === null || _g === void 0 ? void 0 : _g.info(`Reached maximum results limit of ${maxResults}, stopping fetch`); break; } } (_h = context.logger) === null || _h === void 0 ? void 0 : _h.info(`Found ${emailsList.length} emails (limited to ${maxResults})`); for (const email of emailsList) { (_j = context.logger) === null || _j === void 0 ? void 0 : _j.info(` ${email.uid}`); const item_json = JSON.parse(JSON.stringify(email)); item_json.mailboxPath = mailboxPath; if (includeParts.includes(EmailParts_1.EmailParts.Headers)) { if (email.headers) { try { const headersString = email.headers.toString(); const parsed = await (0, mailparser_1.simpleParser)(headersString); item_json.headers = {}; parsed.headers.forEach((value, key, map) => { item_json.headers[key] = value; }); } catch (error) { (_k = context.logger) === null || _k === void 0 ? void 0 : _k.error(` Error parsing headers: ${error}`); } } } const analyzeBodyStructure = includeAttachmentsInfo || includeTextContent || includeHtmlContent; let textPartId = null; let htmlPartId = null; const attachmentsInfo = []; if (analyzeBodyStructure) { const bodyStructure = email.bodyStructure; if (bodyStructure) { if (bodyStructure.childNodes) { const partsInfo = (0, EmailParts_2.getEmailPartsInfoRecursive)(context, bodyStructure); for (const partInfo of partsInfo) { if (partInfo.disposition === 'attachment') { attachmentsInfo.push({ partId: partInfo.partId, filename: partInfo.filename, type: partInfo.type, encoding: partInfo.encoding, size: partInfo.size, }); } else { if (partInfo.type === 'text/plain') { textPartId = partInfo.partId; } if (partInfo.type === 'text/html') { htmlPartId = partInfo.partId; } } } } else { if (bodyStructure.type === 'text/plain') { textPartId = 'TEXT'; } if (bodyStructure.type === 'text/html') { htmlPartId = 'TEXT'; } } } } if (includeAttachmentsInfo) { item_json.attachmentsInfo = attachmentsInfo; } if (includeTextContent || includeHtmlContent) { if (includeTextContent) { item_json.textContent = null; if (textPartId) { const textContent = await client.download(email.uid.toString(), textPartId, { uid: true, }); if (textContent.content) { item_json.textContent = await (0, StreamHelpers_1.streamToString)(textContent.content); } } } if (includeHtmlContent) { item_json.htmlContent = null; if (htmlPartId) { const htmlContent = await client.download(email.uid.toString(), htmlPartId, { uid: true, }); if (htmlContent.content) { item_json.htmlContent = await (0, StreamHelpers_1.streamToString)(htmlContent.content); } } } } returnData.push({ json: item_json, }); } return returnData; }, }; //# sourceMappingURL=EmailGetList.js.map