AI prompts
base on Mail-Archiver is a web application for archiving, searching, and exporting emails from multiple accounts. Featuring folder sync, attachment support, mailbox migration and a dashboard. # π§ Mail-Archiver - Email Archiving System
**A comprehensive solution for archiving, searching, and exporting emails**
<div style="display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px;">
<a href="#"><img src="https://img.shields.io/badge/Docker-2CA5E0?style=for-the-badge&logo=docker&logoColor=white" alt="Docker"></a>
<a href="#"><img src="https://img.shields.io/badge/.NET-512BD4?style=for-the-badge&logo=dotnet&logoColor=white" alt=".NET"></a>
<a href="#"><img src="https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white" alt="PostgreSQL"></a>
<a href="#"><img src="https://img.shields.io/badge/Bootstrap-563D7C?style=for-the-badge&logo=bootstrap&logoColor=white" alt="Bootstrap"></a>
<a href="https://github.com/s1t5/mail-archiver"><img src="https://img.shields.io/github/stars/s1t5/mail-archiver?style=for-the-badge&logo=github" alt="GitHub Stars"></a>
<a href="https://www.buymeacoffee.com/s1t5" target="_blank"><img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-s1t5-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me a Coffee"></a>
</div>
## β¨ Key Features
### π General
- Automated archiving of incoming and outgoing emails
- Support for multiple accounts
- Storage of email content and attachments
- Scheduled synchronization at configurable intervals
- Mobile and desktop optimized, multilingual responsive UI
- Dark mode
### π Advanced Search
- Search across all archived emails
- Filter by date range, sender, recipient, and more
- Preview emails with attachment list
### π₯ Multi User
- Create multiple user accounts
- Assignment of different mail accounts to users
### π Dashboard & Statistics
- Account-specific statistics and overview
- Storage usage monitoring
- Top senders analysis
### π§© Supported Email Providers
- **IMAP**: Traditional IMAP accounts with full synchronization capabilities
- **M365**: Microsoft 365 mail accounts via Microsoft Graph API ([setup guide](doc/AZURE_APP_REGISTRATION_M365.md))
- **IMPORT**: Import-only accounts for migrating existing email archives without active synchronization
### π€ Export Functions
- Export entire mail accounts as mbox files or zipped EML archives
- Export selected individual emails or email batches
- Download attachments with original filenames preserved
### π₯ Import Functions
- MBox Import
- EML Import (ZIP files with folder structure support)
### π Restore Function
- Restore a selection of emails or an entire mailbox to a destination mailbox
### ποΈ Retention Policies
- Configure automatic deletion of archived emails from the mailserver after a specified number of days
- Set retention period per email account (e.g., delete emails after 30, 90, or 365 days)
- Emails are only deleted from the server after they have been successfully archived
- Helps manage storage space on the mailserver while maintaining a complete archive
> π¨ **Important note for retention policies**
> - Requires IMAP Expunge support from the mail server to permanently delete emails
> - For Gmail accounts, Auto-Expunge must be disabled in Gmail settings under the "Forwarding and POP/IMAP" tab!
## πΌοΈ Screenshots
### Dashboard

### Archive

### Email Details

## π Quick Start
### Prerequisites
- [Docker](https://www.docker.com/products/docker-desktop)
- [Docker Compose](https://docs.docker.com/compose/install/)
- email account credentials
### π οΈ Installation
1. Install the prerequisites on your system
2. Create a `docker-compose.yml` file
```yaml
services:
mailarchive-app:
image: s1t5/mailarchiver:latest
restart: always
environment:
# Database Connection
- ConnectionStrings__DefaultConnection=Host=postgres;Database=MailArchiver;Username=mailuser;Password=masterkey;
# Authentication Settings
- Authentication__Enabled=true
- Authentication__Username=admin
- Authentication__Password=secure123!
- Authentication__SessionTimeoutMinutes=60
- Authentication__CookieName=MailArchiverAuth
# MailSync Settings
- MailSync__IntervalMinutes=15
- MailSync__TimeoutMinutes=60
- MailSync__ConnectionTimeoutSeconds=180
- MailSync__CommandTimeoutSeconds=300
- MailSync__AlwaysForceFullSync=false
- MailSync__IgnoreSelfSignedCert=false
# BatchRestore Settings
- BatchRestore__AsyncThreshold=50
- BatchRestore__MaxSyncEmails=150
- BatchRestore__MaxAsyncEmails=50000
- BatchRestore__SessionTimeoutMinutes=30
- BatchRestore__DefaultBatchSize=50
# BatchOperation Settings
- BatchOperation__BatchSize=50
- BatchOperation__PauseBetweenEmailsMs=50
- BatchOperation__PauseBetweenBatchesMs=250
# Selection Settings
- Selection__MaxSelectableEmails=250
# Npgsql Settings
- Npgsql__CommandTimeout=900
# Upload Settings for MBox files
- Upload__MaxFileSizeGB=10
- Upload__KeepAliveTimeoutHours=4
- Upload__RequestHeadersTimeoutHours=2
ports:
- "5000:5000"
networks:
- postgres
volumes:
- ./data-protection-keys:/app/DataProtection-Keys
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:17-alpine
restart: always
environment:
POSTGRES_DB: MailArchiver
POSTGRES_USER: mailuser
POSTGRES_PASSWORD: masterkey
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready -U mailuser -d MailArchiver"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
networks:
postgres:
```
3. Edit the database configuration in the `docker-compose.yml` and set a secure password in the `POSTGRES_PASSWORD` variable and the `ConnectionString`.
4. If you want to use authentication (which i'd strongly recommend) definie a `Authentication__Username` and `Authentication__Password` which is used for the admin user.
4. Configure a reverse proxy of your choice with https and authentification to secure access to the application.
> β οΈ **Attention**
>
> The application itself does not provide encrypted access via https! It must be set up via a reverse proxy! Moreover the application is not build for public internet access!
4. Initial start of the containers:
```bash
docker compose up -d
```
5. Restart containers:
```bash
docker compose restart
```
6. Access the application
7. Login with your defined credentials and add your first email account:
- Navigate to "Email Accounts" section
- Click "New Account"
- Enter your server details and credentials
- Save and start archiving!
- If you want, create other users and assign accounts.
## π Security Note
- Use strong passwords and change default credentials
- Consider implementing HTTPS with a reverse proxy in production
- Regular backups of the PostgreSQL database recommended
## π How To - Mailbox migration
It is also possible to migrate a mailbox to another target mailbox, for example when changing mail provider.
The following steps are planned for this
1. add the source account under the accounts
2. synchronisation of the source account
3. adding the target account
4. synchronisation of the possibly still empty target account
5. select βCopy All Emails to Another Mailboxβ in the details under the accounts for the source account
6. select the target account and the target folder in this account and start the migration. If there is a large amount of emails to be moved, this is carried out as a background task. The status and progress of this can be viewed in the Jobs tab.
7. after the successful transfer, set the source account to βDisabledβ under the accounts so that it is no longer archived in future.
## π Technical Details
### Architecture
- ASP.NET Core 8 MVC application
- PostgreSQL database for email storage
- MailKit library for IMAP communication
- Background service for email synchronization
- Bootstrap 5 and Chart.js for frontend
## π€ Contributing
Contributions welcome! Please open an Issue or Pull Request.
## π Support the Project
If you find this project useful and would like to support its continued development, you can buy me a coffee! Your support helps me dedicate more time and resources to improving the application and adding new features. While financial support is not required, it is greatly appreciated and helps ensure the project's ongoing maintenance and enhancement.
<a href="https://www.buymeacoffee.com/s1t5" target="_blank"><img src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-s1t5-FFDD00?style=for-the-badge&logo=buy-me-a-coffee&logoColor=black" alt="Buy Me a Coffee"></a>
---
π *License: GNU GENERAL PUBLIC LICENSE Version 3 (see LICENSE file)*
", Assign "at most 3 tags" to the expected json: {"id":"14902","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"