feat: auto-move imported emails to IMAP folder and add 90-day cleanup
Build and Push Multi-Platform Images / build-and-push (push) Successful in 41s
Build and Push Multi-Platform Images / build-and-push (push) Successful in 41s
- New ImapFolderService moves emails to configurable "importiert" folder after successful import, creating the folder if it doesn't exist - Daily cron at 03:00 moves emails older than 90 days to trash and empties it - Extract createImapClient() helper in EmailDownloadService - Add ensurePageCache() with in-flight deduplication to BarcodeScannerService - InboxService regenerates page cache on-demand when image file is missing - IMAP_IMPORTED_FOLDER and IMAP_TRASH_FOLDER added to .env.example and docker-compose Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { ImapFlow } from 'imapflow';
|
||||
|
||||
@Injectable()
|
||||
export class ImapFolderService {
|
||||
private readonly logger = new Logger(ImapFolderService.name);
|
||||
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
private createClient(): ImapFlow {
|
||||
return new ImapFlow({
|
||||
host: this.configService.get<string>('IMAP_HOST', ''),
|
||||
port: this.configService.get<number>('IMAP_PORT', 993),
|
||||
secure: this.configService.get<string>('IMAP_USE_SSL', 'true') === 'true',
|
||||
auth: {
|
||||
user: this.configService.get<string>('IMAP_USERNAME', ''),
|
||||
pass: this.configService.get<string>('IMAP_PASSWORD', ''),
|
||||
},
|
||||
logger: false,
|
||||
});
|
||||
}
|
||||
|
||||
async moveToImportiert(messageId: string): Promise<void> {
|
||||
if (!this.configService.get<string>('IMAP_HOST')) return;
|
||||
|
||||
const importedFolder = this.configService.get<string>('IMAP_IMPORTED_FOLDER', 'importiert');
|
||||
const client = this.createClient();
|
||||
try {
|
||||
await client.connect();
|
||||
|
||||
const mailboxes = await client.list();
|
||||
if (!mailboxes.some(m => m.path === importedFolder)) {
|
||||
await client.mailboxCreate(importedFolder);
|
||||
this.logger.log(`IMAP-Ordner "${importedFolder}" erstellt.`);
|
||||
}
|
||||
|
||||
await client.mailboxOpen('INBOX');
|
||||
const uids = await client.search({ header: { 'message-id': messageId } }, { uid: true });
|
||||
if (Array.isArray(uids) && uids.length > 0) {
|
||||
await client.messageMove(uids, importedFolder, { uid: true });
|
||||
this.logger.log(`E-Mail ${messageId} → "${importedFolder}" verschoben.`);
|
||||
} else {
|
||||
this.logger.warn(`E-Mail ${messageId} nicht in INBOX gefunden (bereits verschoben?).`);
|
||||
}
|
||||
} catch (err: any) {
|
||||
this.logger.error(`IMAP moveToImportiert fehlgeschlagen: ${err.message}`);
|
||||
} finally {
|
||||
await client.logout().catch(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user