feat: importierte E-Mails automatisch in IMAP-Ordner verschieben und nach 90 Tagen löschen
Build and Push Multi-Platform Images / build-and-push (push) Successful in 31s

- Neuer ImapFolderService verschiebt E-Mails nach erfolgreichem Import in den
  konfigurierbaren Ordner "importiert" (wird bei Bedarf automatisch erstellt)
- Täglicher Cron um 03:00 Uhr verschiebt E-Mails älter als 90 Tage in den
  Papierkorb und leert ihn anschließend
- createImapClient()-Hilfsmethode im EmailDownloadService ausgelagert
- IMAP_IMPORTED_FOLDER und IMAP_TRASH_FOLDER in docker-compose ergänzt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-16 21:58:41 +02:00
parent ef7813f9f9
commit ed57477324
5 changed files with 120 additions and 12 deletions
@@ -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(() => {});
}
}
}