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
JavaScript
"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