n8n-nodes-imap-ai
Version:
Simplified IMAP node for n8n with AI-agent support. Clean and modular email and mailbox management for automation workflows.
296 lines • 11.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SearchEmailsOperation = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const helpers_1 = require("../utils/helpers");
class SearchEmailsOperation {
async execute(executeFunctions, client, itemIndex) {
const mailboxParam = executeFunctions.getNodeParameter('mailbox', itemIndex);
const mailbox = helpers_1.ParameterValidator.extractMailboxName(mailboxParam);
const limit = executeFunctions.getNodeParameter('limit', itemIndex);
const searchMode = executeFunctions.getNodeParameter('searchMode', itemIndex);
helpers_1.ParameterValidator.validateMailbox(mailboxParam);
const validatedLimit = Math.max(1, Math.min(limit, 1000));
try {
await client.mailboxOpen(mailbox);
}
catch (error) {
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
message: `Failed to open mailbox ${mailbox}: ${error.message}`,
});
}
let searchCriteria = {};
let searchDisplayText = '';
if (searchMode === 'simple') {
const quickFilter = executeFunctions.getNodeParameter('quickFilter', itemIndex);
const simpleSearchText = executeFunctions.getNodeParameter('simpleSearchText', itemIndex);
searchCriteria = this.buildSimpleSearchCriteria(quickFilter, simpleSearchText);
searchDisplayText = this.buildSimpleSearchDisplay(quickFilter, simpleSearchText);
}
else {
const advancedCriteria = executeFunctions.getNodeParameter('advancedCriteria', itemIndex);
const result = this.buildAdvancedSearchCriteria(advancedCriteria);
searchCriteria = result.criteria;
searchDisplayText = result.display;
}
console.log('Search criteria:', JSON.stringify(searchCriteria, null, 2));
console.log('Search display:', searchDisplayText);
let searchResults = [];
try {
searchResults = await client.search(searchCriteria, { uid: true });
}
catch (error) {
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
message: `Server-side search failed: ${error.message}. Query: ${searchDisplayText}`,
});
}
console.log(`Server-side search completed. Found ${searchResults.length} UIDs matching criteria`);
if (searchResults.length === 0) {
return [
{
json: {
searchSummary: {
totalFound: 0,
returned: 0,
query: searchDisplayText,
criteria: searchCriteria,
folder: mailbox,
},
uids: [],
firstUID: null,
},
},
];
}
const sortedResults = searchResults.sort((a, b) => b - a);
const limitedResults = sortedResults.slice(0, validatedLimit);
console.log(`Validating ${limitedResults.length} UIDs from server-side search...`);
let validUIDs = [];
try {
for (const uid of limitedResults) {
const exists = await client.search({ uid: uid.toString() });
if (exists.length > 0) {
validUIDs.push(uid);
console.log(`UID ${uid} exists and is valid`);
}
else {
console.log(`UID ${uid} no longer exists, skipping`);
}
if (validUIDs.length >= validatedLimit)
break;
}
console.log(`Found ${validUIDs.length} valid UIDs from ${limitedResults.length} search results`);
}
catch (error) {
console.error('UID validation failed:', error);
throw new n8n_workflow_1.NodeApiError(executeFunctions.getNode(), {
message: `Failed to validate email UIDs: ${error.message}`,
});
}
if (validUIDs.length === 0) {
return [
{
json: {
searchSummary: {
totalFound: searchResults.length,
returned: 0,
query: searchDisplayText,
criteria: searchCriteria,
folder: mailbox,
note: "Search found emails but none exist in current mailbox state",
},
uids: [],
firstUID: null,
},
},
];
}
const result = {
json: {
searchSummary: {
totalFound: searchResults.length,
returned: validUIDs.length,
query: searchDisplayText,
criteria: searchCriteria,
folder: mailbox,
},
uids: validUIDs,
firstUID: validUIDs.length > 0 ? validUIDs[0] : null,
},
};
return [result];
}
buildSimpleSearchCriteria(quickFilter, searchText) {
const criteria = {};
switch (quickFilter) {
case 'unseen':
criteria.unseen = true;
break;
case 'seen':
criteria.seen = true;
break;
case 'today':
criteria.since = new Date(new Date().setHours(0, 0, 0, 0));
break;
case 'thisWeek':
const weekStart = new Date();
weekStart.setDate(weekStart.getDate() - weekStart.getDay());
weekStart.setHours(0, 0, 0, 0);
criteria.since = weekStart;
break;
case 'thisMonth':
const monthStart = new Date();
monthStart.setDate(1);
monthStart.setHours(0, 0, 0, 0);
criteria.since = monthStart;
break;
case 'flagged':
criteria.flagged = true;
break;
case 'all':
default:
break;
}
if (searchText && searchText.trim()) {
const text = searchText.trim();
if (text.includes('@')) {
criteria.or = [
{ from: text },
{ to: text },
{ cc: text },
];
}
else {
criteria.or = [
{ subject: text },
{ from: text },
{ body: text },
];
}
}
return criteria;
}
buildSimpleSearchDisplay(quickFilter, searchText) {
const parts = [];
switch (quickFilter) {
case 'unseen':
parts.push('unread emails');
break;
case 'seen':
parts.push('read emails');
break;
case 'today':
parts.push('emails from today');
break;
case 'thisWeek':
parts.push('emails from this week');
break;
case 'thisMonth':
parts.push('emails from this month');
break;
case 'flagged':
parts.push('flagged emails');
break;
case 'all':
default:
parts.push('all emails');
break;
}
if (searchText && searchText.trim()) {
if (searchText.includes('@')) {
parts.push(`from/to: ${searchText}`);
}
else {
parts.push(`containing: ${searchText}`);
}
}
return parts.join(' ');
}
buildAdvancedSearchCriteria(advancedCriteria) {
const criteria = {};
const displayParts = [];
if (advancedCriteria.subject) {
criteria.subject = advancedCriteria.subject;
displayParts.push(`subject: ${advancedCriteria.subject}`);
}
if (advancedCriteria.from) {
criteria.from = advancedCriteria.from;
displayParts.push(`from: ${advancedCriteria.from}`);
}
if (advancedCriteria.to) {
criteria.to = advancedCriteria.to;
displayParts.push(`to: ${advancedCriteria.to}`);
}
if (advancedCriteria.body) {
criteria.body = advancedCriteria.body;
displayParts.push(`body: ${advancedCriteria.body}`);
}
if (advancedCriteria.seen !== undefined) {
if (advancedCriteria.seen) {
criteria.seen = true;
displayParts.push('read');
}
else {
criteria.unseen = true;
displayParts.push('unread');
}
}
if (advancedCriteria.flagged) {
criteria.flagged = true;
displayParts.push('flagged');
}
this.applyDateFilters(criteria, advancedCriteria, displayParts);
return {
criteria,
display: displayParts.length > 0 ? displayParts.join(', ') : 'all emails',
};
}
applyDateFilters(criteria, advancedCriteria, displayParts) {
if (advancedCriteria.quickDate && advancedCriteria.quickDate !== 'none') {
const dateRange = this.getQuickDateRange(advancedCriteria.quickDate);
Object.assign(criteria, dateRange);
displayParts.push(`date: ${advancedCriteria.quickDate}`);
}
if (advancedCriteria.dateFrom) {
criteria.since = new Date(advancedCriteria.dateFrom);
displayParts.push(`since: ${advancedCriteria.dateFrom}`);
}
if (advancedCriteria.dateTo) {
criteria.before = new Date(advancedCriteria.dateTo);
displayParts.push(`before: ${advancedCriteria.dateTo}`);
}
}
getQuickDateRange(quickDate) {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
switch (quickDate) {
case 'today':
return { since: today };
case 'yesterday':
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
return { since: yesterday, before: today };
case 'thisWeek':
const weekStart = new Date(today);
weekStart.setDate(today.getDate() - today.getDay());
return { since: weekStart };
case 'lastWeek':
const lastWeekEnd = new Date(today);
lastWeekEnd.setDate(today.getDate() - today.getDay());
const lastWeekStart = new Date(lastWeekEnd);
lastWeekStart.setDate(lastWeekEnd.getDate() - 7);
return { since: lastWeekStart, before: lastWeekEnd };
case 'thisMonth':
const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);
return { since: monthStart };
case 'lastMonth':
const lastMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1);
const lastMonthEnd = new Date(today.getFullYear(), today.getMonth(), 1);
return { since: lastMonthStart, before: lastMonthEnd };
default:
return {};
}
}
}
exports.SearchEmailsOperation = SearchEmailsOperation;
//# sourceMappingURL=searchEmails.js.map