kua-money-trace/src/mailDownloader.js

88 lines
2.7 KiB
JavaScript

import { ImapFlow } from 'imapflow';
import { archiveRawEmail } from './mailArchive.js';
import { requireAccountPassword } from './mailConfig.js';
export async function dryRunAccount(account) {
const password = requireAccountPassword(account);
const client = makeClient(account, password);
await client.connect();
try {
const mailboxes = await client.list();
const selected = [];
for (const mailbox of mailboxes) {
if (mailbox.flags?.has?.('\\Noselect')) continue;
if (account.mailboxes?.length && !account.mailboxes.includes(mailbox.path)) continue;
const status = await client.status(mailbox.path, { messages: true, unseen: true, uidNext: true });
selected.push({
path: mailbox.path,
messages: status.messages,
unseen: status.unseen,
uidNext: status.uidNext,
});
}
return { accountId: account.id, email: account.email, mailboxes: selected };
} finally {
await client.logout().catch(() => {});
}
}
export async function downloadAccount(account, options = {}) {
const password = requireAccountPassword(account);
const client = makeClient(account, password);
const limit = Number(options.limit || 25);
const since = options.since || account.defaultSince || null;
const archiveRoot = options.archiveRoot || account.archive?.root || `data/mail-archive/${account.id}`;
const results = [];
await client.connect();
try {
const mailboxes = account.mailboxes?.length ? account.mailboxes : ['INBOX'];
for (const mailbox of mailboxes) {
const lock = await client.getMailboxLock(mailbox);
try {
const criteria = since ? { since: new Date(since) } : { all: true };
const uids = await client.search(criteria, { uid: true });
const selectedUids = uids.slice(Math.max(0, uids.length - limit));
for await (const msg of client.fetch(selectedUids, { uid: true, source: true }, { uid: true })) {
const record = await archiveRawEmail({
account,
mailbox,
uid: msg.uid,
source: msg.source,
archiveRoot,
});
results.push(record);
}
} finally {
lock.release();
}
}
} finally {
await client.logout().catch(() => {});
}
return {
accountId: account.id,
archiveRoot,
downloaded: results.length,
records: results,
};
}
function makeClient(account, password) {
return new ImapFlow({
host: account.host,
port: account.port || 993,
secure: account.secure !== false,
auth: {
user: account.auth?.user || account.email,
pass: password,
},
logger: false,
tls: {
rejectUnauthorized: true,
},
});
}