diff --git a/.github/frappe-mail-architecture-dark.png b/.github/frappe-mail-architecture-dark.png deleted file mode 100644 index e0f3dcd6..00000000 Binary files a/.github/frappe-mail-architecture-dark.png and /dev/null differ diff --git a/.github/frappe-mail-architecture.png b/.github/frappe-mail-architecture.png deleted file mode 100644 index c0f52859..00000000 Binary files a/.github/frappe-mail-architecture.png and /dev/null differ diff --git a/README.md b/README.md index 14e1d189..30e4b52b 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,24 @@

Frappe Mail

-Frappe Mail is an open-source email tool built on the [Frappe Framework](https://github.com/frappe/frappe). It offers a complete infrastructure for sending and receiving emails, managing domains, mailboxes, aliases, and email signing. It provides APIs for users to easily integrate email functionality into their applications. Frappe Mail leverages [RabbitMQ](https://github.com/rabbitmq/rabbitmq-server) for efficient email queuing and [Haraka MTA](https://github.com/haraka/haraka) for SMTP email delivery. [Mail Agent](https://github.com/frappe/mail_agent) consume the queued messages and handle email delivery via Haraka, enabling reliable and scalable email processing. +Frappe Mail is an open-source email platform built on the [Frappe Framework](https://github.com/frappe/frappe), designed to streamline end-to-end email management. It’s organized into three core components [Client](https://github.com/frappe/mail), [Server](https://github.com/frappe/mail_server), and [Agent](https://github.com/frappe/mail_agent). The Client generates email messages and passes them to the Server for processing. The Server handles essential validations, such as checking user quotas, enforcing limits, and running spam checks. If all checks are cleared, the email is pushed to [RabbitMQ](https://github.com/rabbitmq/rabbitmq-server). The Agent then takes over, with multiple agents available to consume emails from the queue and deliver them through a locally connected Haraka MTA instance. With simple APIs, Frappe Mail makes it easy to integrate reliable email functionality into your applications. + +> Note: Frappe Mail Client is designed to work exclusively with the Frappe Mail Server and is not compatible with traditional email servers. ## Table of Contents - [Installation](#installation) -- [Mail System Architecture](#mail-system-architecture) -- [Email Sending Process](#email-sending-process) - - [Email Composition and DKIM Signing](#1-email-composition-and-dkim-signing) - - [Pushing Emails to RabbitMQ](#2-pushing-emails-to-rabbitmq) - - [Consuming Emails from RabbitMQ](#3-mail-agent-consuming-emails-from-rabbitmq) - - [Sending the Email](#4-haraka-sending-the-email) - - [Custom Plugins in Haraka](#5-custom-plugins-in-haraka-for-delivery-status) - - [Syncing Delivery Status](#6-syncing-delivery-status) -- [Email Receiving Process](#email-receiving-process) - - [IP Blacklist Check](#1-ip-blacklist-check) - - [PTR/RDNS Check](#2-ptrrdns-check) - - [SPF, DKIM, and DMARC Checks](#3-spf-dkim-and-dmarc-checks) - - [Queue Handling](#4-queue-handling) - - [Asynchronous Recipient Handling](#5-asynchronous-recipient-handling) - - [SpamAssassin Scoring](#6-spamassassin-scoring) +- [Connecting to the Mail Server](#connecting-to-the-mail-server) +- [Adding a Mail Domain](#adding-a-mail-domain) +- [Adding a Mailbox](#adding-a-mailbox) +- [Sending Your First Email](#sending-your-first-email) +- [Outbound Reports](#outbound-reports) +- [Receiving Emails](#receiving-emails) +- [Mail Aliases](#mail-aliases) +- [APIs](#apis) + - [Auth](#1-auth-api) + - [Outbound](#2-outbound-api) + - [Inbound](#3-inbound-api) - [Contributing](#contributing) - [License](#license) @@ -48,197 +46,343 @@ You can install this app using the [bench](https://github.com/frappe/bench) CLI: bench browse sitename.localhost --user Administrator ``` -## Mail System Architecture +## Connecting to the Mail Server -Frappe Mail is designed with a Master-Slave architecture to efficiently handle high volumes of email traffic while decoupling key email processing tasks. This architecture ensures scalability, reliability, and performance. +1. **Open Mail Settings:** In the Frappe Mail Client, navigate to **Mail Settings** to configure the connection to your Mail Server. -
-
- - - - -
-
-
+2. **Add Mail Server Details:** Enter the following details: + + - **Mail Server:** Specify the URL or IP address of the Frappe Mail Server. + - **API Key and API Secret:** Provide the API credentials generated on the Mail Server. These are used to authenticate and secure the connection between the Client and Server. + +3. **Save and Validate:** After entering the details, click Save. The credentials will be automatically validated. If there are any issues, an error message will appear to help you troubleshoot the configuration. + +![mail-settings-details](docs/screenshots/mail-settings-details.png) + +## Adding a Mail Domain + +To send and receive emails with your Frappe Mail Client, you'll need to add a Mail Domain. Here are the steps to do that: + +1. **Navigate to Mail Domains:** Go to the Mail Domain in your Frappe Mail Client to add a Mail Domain. + +2. **Enter Domain Name:** In the field provided, input your desired domain name (e.g., frappemail.com). + ![mail-domain-new](docs/screenshots/mail-domain-new.png) + +3. **Save the Domain:** Click Save to register the domain. After saving, you will see the necessary DNS records that need to be added to your domain registrar (like Namecheap, GoDaddy, or Cloudflare). + ![mail-domain-dns-records](docs/screenshots/mail-domain-dns-records.png) + +4. **Add DNS Records:** Go to your domain registrar’s DNS management panel and add the provided DNS records. These typically include SPF, DMARC and MX records for proper email delivery. + +5. **Verify the Mail Domain:** Once you’ve added the DNS records, return to the Mail Domain. Click on Actions and then select Verify DNS Records. + + ![mail-domain-verify-dns-records](docs/screenshots/mail-domain-verify-dns-records.png) + + A notification will appear showing the verification results. If all the DNS records match, the verified checkbox will automatically be checked, indicating that your domain is set up correctly. + + > **Note:** Please note that DNS verification may take some time to complete because of the TTL (Time to Live) settings on your DNS records. Changes to DNS records may not propagate immediately due to caching by DNS servers. + +6. **Repeat:** To add additional domains, simply repeat the process for each new domain you want to add. + +By following these steps, your mail domain will be successfully added and verified, enabling you to send and receive emails through your Frappe Mail setup. + +## Adding a Mailbox -### Mail App (Master) +To set up a new mailbox for your users, follow these steps: -The Mail App serves as the master or producer of outbound emails. When an email is composed and signed, it is not immediately sent. Instead, the email is pushed to a RabbitMQ broker, which manages queuing and asynchronous delivery. This keeps the Mail App responsive and allows it to handle large numbers of emails without being slowed down by the delivery process. +1. **Navigate to Mailboxes:** Go to the Mailbox in your Frappe Mail Client to add a new Mailbox. -### RabbitMQ (Broker) +2. **Select Domain Name:** From the dropdown, choose the domain name under which you want to create the mailbox. -RabbitMQ serves as the core message broker in the architecture. It queues emails, ensuring they are processed asynchronously. This decouples the Mail App from the email delivery system, allowing the Mail Agent to consume and deliver the queued emails at its own pace. +3. **Select User:** Choose the user who will be assigned this mailbox. Ensure that the user has the **Mailbox User** role assigned. -### Mail Agent (Slave) +4. **Enter Email Address:** In the provided field, enter the email address that belongs to your selected domain (e.g., sagar.s@frappemail.com). -The Mail Agent is responsible for consuming queued messages from RabbitMQ and handling email delivery via Haraka MTA. It plays a critical role in processing both outbound and inbound emails: +5. **Save the Mailbox:** Click Save to create the mailbox. -- **Haraka MTA:** The Mail Agent forwards the queued messages to Haraka, which handles the actual SMTP-based email delivery. Haraka efficiently sends the emails to their respective recipient mail servers. -- **SpamAssassin Integration:** The Mail Agent includes SpamAssassin, which works alongside Haraka to evaluate incoming emails. SpamAssassin assigns a spam score to each email, which helps in determining the appropriate folder for the message (Inbox, Spam, etc.). SpamAssassin is automatically installed with the Inbound Mail Agent to ensure robust spam detection on inbound emails. + ![mailbox](docs/screenshots/mailbox.png) -This master-slave architecture makes Frappe Mail modular, scalable, and highly efficient for handling both outbound and inbound email traffic. By relying on RabbitMQ for message queuing, the system decouples email composition from delivery, ensuring robust performance and reliability even under high-volume scenarios. +6. **Repeat:** To add additional mailboxes, simply repeat the process for each new mailbox you want to create. -## Email Sending Process +By following these steps, you will successfully add a mailbox for the specified user, enabling them to send and receive emails through your Frappe Mail setup. -Frappe Mail is designed to handle email delivery in a modular, scalable way using a combination of RabbitMQ for message queuing, a Mail Agent for email processing, and Haraka for final SMTP delivery. Here's a deeper look at each step of the email-sending process. +## Sending Your First Email -### 1. Email Composition and DKIM Signing +To send your first email, follow these steps: -When a user sends an email through the Mail App, several actions happen before it is delivered: +1. **Access Outgoing Mail:** Navigate to the Outgoing Mail in the Frappe Mail Client and create a new outgoing email. -- **Email Composition:** +2. **Select Sender Mailbox:** If you’re associated with multiple mailboxes, choose the mailbox you want to send the email from. - - The Mail App collects key information such as the sender's address, recipients (To, CC, BCC), subject, body, and any attachments. - - The email is structured according to the MIME (Multipurpose Internet Mail Extensions) standard, which allows the email to include rich text, attachments, and other media. +3. **Compose Your Email:** Enter the subject, recipients, and body of your email. -- **DKIM Signing:** +4. **Save and Submit:** Click Save to store your email, then submit it. The status will change to Pending, indicating that the outgoing email is awaiting processing. - - **DomainKeys Identified Mail (DKIM)** is a method for email authentication that ensures the message has not been altered in transit. - - A **DKIM signature** is generated by hashing key parts of the email (headers and body) and signing it with the sender’s unique **private key**. This private key is associated with the sender’s domain (e.g., frappe.school). - - The resulting signature is then embedded in the email headers as a **DKIM-Signature** field. When the email reaches the recipient’s server, this signature can be verified using the sender’s **public key** (published via DNS records) to ensure the email has not been tampered with. - - The DKIM signing process guarantees the **integrity** of the email during transit and reduces the likelihood of being marked as spam. +5. **Transfer the Email:** The email will be picked up by a scheduled job to transfer it to the Mail Server. Alternatively, you can use the **Actions > Transfer Now** option to prioritize sending the email immediately. - **Example DKIM header:** + ![outgoing-mail-transfer-now](docs/screenshots/outgoing-mail-transfer-now.png) - ```plaintext - DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=frappemail.com; i=@frappemail.com; q=dns/txt; s=frappe-school-cb2000ae3f; - t=1725623282; h=to : cc : from : date : subject : reply-to : message-id : in-reply-to; - bh=36NiEgOw7wBe1ybSgQrTNMwH4CVW397O3gYl4I4Ex9c=; - b=D694Lhp/Li25ufrneaVUcddrbYq848mAyY0VvKlCkakDEUxiqOX44HxommAkr2eNWSAtB HbkiXq0/jO3F89rpfDRuLCe3AZ8fwuClDniMwYTslZYIO8tlSpAoC7kCfBADArlQFUwVihw FtUaKuSpfJeUaKhmeYQg1CT63BiGOy+gal57ARWVJdMJatod2REguGqRYXu4cAZemaOd0Uz x7VbwW3x0Egn9QfFIcl3uCHZMCQTE4krfWX9ad0h5XK8WkXcGDF/LjSUnrYCb2WiJxqof2/ Jnpm2HfEKYPTm8gAYmSR1uMw17EbYvtGmoD83hc1ZQWaaKB1mFSyqkVBOIfA== - ``` +6. **Email Processing:** Once transferred to the Mail Server, the status changes to Queued. The Mail Server will then process your email, performing a spam check. If flagged as spam, the email will be blocked. Otherwise, it will be sent to the recipients, and the status will be updated accordingly. -### 2. Pushing Emails to RabbitMQ + ![outgoing-mail-sent](docs/screenshots/outgoing-mail-sent.png) -Once the email is fully composed and signed, the Mail App does not directly send the email to an SMTP server. Instead, it uses RabbitMQ as a queue for asynchronous processing: +7. **View SMTP Response:** After the email has been sent, you can find the response received from the SMTP server for each recipient in the recipient row. This information will provide insights into the delivery status and any issues encountered during the sending process. -- **Why RabbitMQ?** + ![outgoing-mail-smtp-response](docs/screenshots/outgoing-mail-smtp-response.png) - - RabbitMQ allows the system to handle large volumes of email asynchronously. This means that emails are not sent immediately, but instead queued, making the system more scalable and preventing performance bottlenecks. - - By decoupling the email sending from the composition, the Mail App can remain responsive, even when handling high traffic. +8. **Track Open Status:** If tracking is enabled for the mailbox, you can also view the open status and count of the email. This feature allows you to monitor whether the recipients have opened the email, providing valuable insights into engagement. -- **Message Queuing:** + ![outgoing-mail-tracking](docs/screenshots/outgoing-mail-tracking.png) - - The composed email is formatted into a message payload that includes: - - **Metadata:** Information like the recipients and a unique **UUID** of the email, which is used later to track and update the delivery status. - - **Message Body:** The MIME message (with DKIM signature). - - This message is pushed into a **RabbitMQ queue** where it awaits further processing. The Mail App does not wait for the email to be sent, allowing it to move on to other tasks. +## Outbound Reports -- **RabbitMQ Benefits:** - - **Scalability:** Multiple emails can be queued without overwhelming the system. - - **Reliability:** RabbitMQ ensures that no email is lost during transit. - - **Decoupling:** The Mail App doesn't need to handle email delivery directly, as that responsibility is handed off to the **Mail Agent**. +Frappe Mail provides three insightful reports to help you analyze email performance: -### 3. Mail Agent: Consuming Emails from RabbitMQ +1. **Outgoing Mail Summary:** This report displays the total number of sent, bounced, and deferred emails. You can apply various filters to tailor the view to your needs. Additionally, it includes the SMTP responses for all emails, making it a valuable tool for assessing email volume and identifying reasons for any undelivered messages. -The **Mail Agent** is a core Python application responsible for consuming emails from the RabbitMQ queue and forwarding them to the **Haraka MTA** for delivery. + ![report-outgoing-mail-summary](docs/screenshots/report-outgoing-mail-summary.png) -- **Mail Agent's Role:** +2. **Mail Tracker:** Use this report to monitor emails that have tracking pixels attached. It provides information on how many times these emails have been opened, along with details such as open counts, timestamps, and IP addresses of the recipients. - - The Mail Agent constantly listens to the RabbitMQ queue. When a new message is available, the Mail Agent picks it up for processing. - - The Mail Agent is responsible for transforming the email message into a format that can be sent to the SMTP server. + ![report-mail-tracker](docs/screenshots/report-mail-tracker.png) -- **Processing Pipeline:** +3. **Outbound Delay:** This report tracks the time taken for outgoing emails at different stages, including submission and transfer. It helps you understand where delays may occur in the email sending process. - - **Queue Consumption:** - - Once the email has been queued in RabbitMQ, the Mail Agent consumes emails one by one from the queue. - - The agent extracts the metadata (recipients, UUID) and the MIME message (including the DKIM signature) from the message payload. - - **SMTP Forwarding:** - - After consuming an email, the Mail Agent sends it to the Haraka MTA via SMTP. - - Haraka is configured as the outbound email server and is responsible for delivering the email to the recipient’s mail server using the SMTP protocol. - - Haraka also performs retries if delivery fails temporarily. - - **Logging and Monitoring:** - - The Mail Agent logs each delivery attempt, including the response from Haraka or any errors that may occur. - - Delivery responses are pushed into RabbitMQ, where the Mail App can retrieve the status and update the corresponding email's state. - - This ensures robust tracking, allowing any failed emails to be monitored and retried if necessary, while also enabling troubleshooting for debugging purposes. + ![report-outbound-delay](docs/screenshots/report-outbound-delay.png) -### 4. Haraka: Sending the Email +## Receiving Emails -The **Haraka MTA** is responsible for sending the email to the recipient’s mail server. Haraka is a highly extensible, high-performance mail transfer agent (MTA) used for both inbound and outbound email. +When an email is sent to your registered domains, the Mail Server processes it and transfers it to your Frappe Mail Client after conducting a spam check. The email will be parsed and accepted if the recipient is valid; otherwise, it will be rejected. If the **Send Notification on Reject** option is enabled in the Mail Settings, a notification email will be sent to the sender when their email is rejected. Additionally, rejected emails are automatically deleted to conserve storage space, in accordance with the **Rejected Mail Retention** setting. -- **Step-by-Step Process:** +![mail-settings-incoming](docs/screenshots/mail-settings-incoming.png) - - **Email Receipt:** The email is received by Haraka from the Mail Agent via an SMTP connection. - - **SMTP Transaction:** Haraka processes the email through its pipeline of plugins (some custom to Frappe Mail), and attempts to deliver the email to the recipient’s mail server. - - **DKIM Header:** The DKIM header added by the Mail App is passed along with the email, ensuring that the recipient’s server can verify the authenticity of the email. - - **SPF and DMARC Compliance:** Haraka also ensures that emails comply with SPF (Sender Policy Framework) and DMARC (Domain-based Message Authentication, Reporting, and Conformance) protocols. This reduces the likelihood that emails are marked as spam by recipient servers. +You can view received emails in the **Incoming Mail**, where you will find details about the sender's SMTP server and the time taken at different stages of the email lifecycle. The results of authentication checks such as SPF, DKIM, and DMARC will also be displayed, along with their respective descriptions. -- **Custom Haraka Plugins:** +![incoming-mail-accepted](docs/screenshots/incoming-mail-accepted.png) - - **Tracking and Response Handling:** Haraka is extended with custom plugins that capture responses from recipient mail servers. These responses can indicate whether the email was delivered successfully, bounced, or rejected. - - **Push to RabbitMQ:** Once Haraka receives a response from the recipient server, the plugin pushes this information back to the RabbitMQ queue for later processing by the Mail App. +![incoming-mail-more-info](docs/screenshots/incoming-mail-more-info.png) -### 5. Custom Plugins in Haraka for Delivery Status +![incoming-mail-auth-checks](docs/screenshots/incoming-mail-auth-checks.png) -The custom plugins developed for Haraka serve a crucial role in tracking email delivery status and integrating with RabbitMQ: +## Mail Aliases -- **Response Types:** +You can create an alias or group to deliver emails to multiple mailboxes. To set up a mail alias, follow these steps: - - **Queued:** The email is successfully queued for delivery by Haraka. - - **Sent:** The recipient's mail server has accepted the email and returned a success message (e.g., "250 OK"). - - **Deferred:** Delivery was delayed due to temporary issues (e.g., the recipient server is temporarily unavailable). - - **Bounced:** The email was rejected by the recipient server, possibly due to reasons such as an invalid address, blacklisting, or other errors (e.g., "550 No Such User"). +1. **Go to Mail Alias:** Navigate to the Mail Alias and click on **Add Mail Alias**. -- **Pushing Status to RabbitMQ:** - - After Haraka receives the response, the plugin generates a structured message indicating the delivery status and pushes this back to the RabbitMQ queue. - - This message includes the email ID (UUID), recipient address, status code (Queued, Sent, Deferred, or Bounced), and any additional error messages or details provided by the recipient server. +2. **Select Domain Name:** Choose the appropriate domain from the dropdown list. -### 6. Syncing Delivery Status +3. **Set the Alias:** Enter the alias, such as team@frappemail.com. -The Mail App includes a scheduled job that periodically consumes messages from the RabbitMQ queue to update the status of previously sent emails: +4. **Select Mailboxes:** Choose the mailbox(es) that you want to receive emails sent to this alias. Ensure that the selected mailboxes have incoming enabled. -- **How Syncing Works:** +5. **Save the Alias:** Click **Save**. - - The Mail App’s scheduled job listens for delivery status updates in RabbitMQ. When a new status message is available, the app processes it and updates the corresponding email record. - - If the email was sent successfully, the app marks the email as "Sent." If the email bounced or was rejected, the status is updated accordingly based on the response from Haraka or the recipient server. +![mail-alias](docs/screenshots/mail-alias.png) -- **User Visibility:** - - Users can view the delivery status of each email within the app, allowing them to track whether their messages were successfully delivered or if any issues occurred (e.g., bounces, rejections). - - For large-scale email campaigns, the app provides an overview of key metrics, including delivery rates, bounce rates, and other performance insights. This helps users monitor the success of their email campaigns and address potential issues. +Now, all emails sent to team@frappemail.com will be delivered to the selected mailboxes. -## Email Receiving Process +## APIs -Emails are received by the **Inbound Mail Agent**, which follows a multi-step process to ensure the email is legitimate and can be safely processed: +### 1. Auth API -### 1. IP Blacklist Check +#### 1.1 Validate -- When a connection is made, the agent first checks the **IP blacklist** published by the **Mail App**. -- If the connecting IP is found to be blacklisted, the connection is **immediately rejected** to prevent handling emails from known malicious or untrusted sources. -- If the IP is not blacklisted, the process continues. +**Endpoint:** `POST /auth/validate` or `/api/method/mail.api.auth.validate` -### 2. PTR/RDNS Check +**Description:** Validates whether a specific mailbox has permissions for inbound (receiving) or outbound (sending) email functions. Useful for checking mailbox configuration and ensuring that email workflows are properly authorized. -- The agent performs a **PTR (Pointer) or RDNS (Reverse DNS) check** on the connecting IP address. -- If the IP does not have a valid PTR record or the PTR check fails, the connection is rejected. -- If the PTR record is valid, the mail is accepted, and the process moves forward. +**Parameters:** -### 3. SPF, DKIM, and DMARC Checks +- `mailbox` (str | None = None): The mailbox to validate. +- `for_inbound` (bool = False): Set to `True` to validate if the mailbox is configured for inbound emails. +- `for_outbound` (bool = False): Set to `True` to validate if the mailbox is configured for outbound emails. -- Haraka is configured to perform **SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail),** and **DMARC** validation checks on the incoming email. -- These checks help verify that the email is from a trusted source: - - **SPF** ensures the sending server is authorized to send on behalf of the domain. - - **DKIM** verifies the email's integrity using cryptographic signatures. - - **DMARC** combines SPF and DKIM results to prevent spoofing and phishing attacks. -- The results of these checks are added as **message headers** and extracted/parsed by the Mail App for further processing. +**Response:** Returns nothing if validation is successful. Throws an exception with the reason if the mailbox cannot be validated. -### 4. Queue Handling +### 2. Outbound API + +These endpoints facilitate sending emails from the Frappe Mail Client. + +#### 2.1 Send + +**Endpoint:** `POST /outbound/send` or `/api/method/mail.api.outbound.send` + +**Description:** Sends an email message with options for attachments, carbon copies (cc), and blind carbon copies (bcc). + +**Parameters:** + +- `from_` (str): The sender's email address. +- `to` (str | list[str]): Recipient email(s). +- `subject` (str): Subject of the email. +- `cc` (str | list[str] | None): Optional carbon copy recipients. +- `bcc` (str | list[str] | None): Optional blind carbon copy recipients. +- `html` (str | None): Optional HTML body of the email. +- `reply_to` (str | list[str] | None): Optional reply-to email(s). +- `in_reply_to_mail_type` (str | None): Optional reference type for the email being replied to. +- `in_reply_to_mail_name` (str | None): Optional reference ID for the email being replied to. +- `custom_headers` (dict | None): Optional custom headers. +- `attachments` (list[dict] | None): List of attachments. + +**Response:** Returns a UUID (name) of the created Outgoing Mail. + +**Example Response:** + +```json +{ "message": "019300a4-91fc-741f-9fe5-9ade8976637f" } +``` + +#### 2.2 Send Raw + +**Endpoint:** `POST /outbound/send-raw` or `/api/method/mail.api.outbound.send_raw` + +**Description:** Sends a raw MIME message. This can be useful for users who want to send a preformatted email. + +**Parameters:** + +- `from_` (str): Sender's email address. +- `to` (str | list[str]): Recipient email(s). +- `raw_message` (str): The complete raw MIME message. + +**Response:** Returns the UUID (name) of the created Outgoing Mail. + +**Example Response:** + +```json +{ "message": "019300a4-91fc-741f-9fe5-9ade8976637f" } +``` -- Once accepted, the email is pushed to a **RabbitMQ queue** for processing. -- The Mail App later pulls this email from RabbitMQ via a scheduled job, ensuring asynchronous processing. +#### 2.3 Send Batch -### 5. Asynchronous Recipient Handling +**Endpoint:** `POST /outbound/send-batch` or `/api/method/mail.api.outbound.send_batch` -- The system includes **asynchronous recipient handling**. This means that if an email is sent to an invalid recipient or alias (e.g., the user doesn't exist or is inactive), the email is marked as **rejected**. -- Depending on the configuration, a **notification** is sent back to the original sender, informing them that their message could not be delivered. +**Description:** Sends multiple email messages in a batch. -### 6. SpamAssassin Scoring +**Parameters:** JSON array of email details. Each entry contains `from_`, `to`, `subject`, etc., similar to `/outbound/send`. -- During the mail acceptance process, the **SpamAssassin** plugin runs a scan on the incoming email, assigning it a **spam score**. -- This spam score is then used to determine which folder the email should be placed in: - - **Inbox:** If the spam score is low, indicating a legitimate email. - - **Spam:** If the spam score is high, indicating the email might be unwanted or malicious. +**Response:** Returns a list of UUIDs (names) for the created Outgoing Mails. -This structured process ensures that only legitimate and trusted emails are processed while filtering out spam and unwanted connections effectively. +**Example Response:** + +```json +{ + "message": [ + "019300a4-91fc-741f-9fe5-9ade8976637f", + "019300a5-2062-7267-8966-603606f9b41b", + "01930081-3b5b-7ad4-a837-ff27f55bcbac" + ] +} +``` + +#### 2.4 Send Raw Batch + +**Endpoint:** `POST /outbound/send-raw-batch` or `/api/method/mail.api.outbound.send_raw_batch` + +**Description:** Sends multiple raw MIME messages in a batch. + +**Parameters:** JSON array of `from_`, `to`, `raw_message`, similar to `/outbound/send-raw`. + +**Response:** Returns a list of UUIDs (names) for the created Outgoing Mails. + +**Example Response:** + +```json +{ + "message": [ + "019300a4-91fc-741f-9fe5-9ade8976637f", + "019300a5-2062-7267-8966-603606f9b41b", + "01930081-3b5b-7ad4-a837-ff27f55bcbac" + ] +} +``` + +#### 2.5 Send Newsletter + +**Endpoint:** `POST /outbound/send-newsletter` or `/api/method/mail.api.outbound.send_newsletter` + +**Description:** Sends low-priority newsletters. Works the same as batch email sending but with a priority setting. + +**Parameters:** JSON array of newsletter details similar to `/outbound/send-batch` or `/outbound/send-raw-batch`. + +**Response:** Returns a list of UUIDs (names) for the created newsletter Outgoing Mails. + +**Example Response:** + +```json +{ + "message": [ + "019300a4-91fc-741f-9fe5-9ade8976637f", + "019300a5-2062-7267-8966-603606f9b41b", + "01930081-3b5b-7ad4-a837-ff27f55bcbac" + ] +} +``` + +### 3. Inbound API + +These endpoints are for retrieving received emails. + +#### 3.1 Pull + +**Endpoint:** `GET /inbound/pull` or `/api/method/mail.api.inbound.pull` + +**Description:** Fetches a list of received emails for a specified mailbox. + +**Parameters:** + +- `mailbox` (str): The mailbox from which to pull emails. +- `limit` (int = 50): Maximum number of emails to retrieve. +- `last_synced_at` (str | None): Optional timestamp to fetch emails received after this time. + +**Response:** Returns a dictionary with a list of received email details. + +**Example Response:** + +```json +{ + "message": { + "mails": [ + { + "id": "019300b2-c261-71d1-bc8d-bc321cc9ebaf", + "folder": "Inbox", + "created_at": "2024-11-06 08:57:26+00:00", + "subject": "Test Email", + "html": "

Test Email

", + "text": "Test Email", + "reply_to": null, + "from": "Sagar Sharma ", + "to": ["Sagar S "], + "cc": [] + } + ], + "last_synced_at": "2024-11-06 08:58:55.528916+00:00", + "last_synced_mail": "019300b2-c261-71d1-bc8d-bc321cc9ebaf" + } +} +``` + +#### 3.2 Pull Raw + +**Endpoint:** `GET /inbound/pull-raw` or `/api/method/mail.api.inbound.pull_raw` + +**Description:** Fetches raw MIME messages for received emails. + +**Parameters:** Same as `/inbound/pull`. + +**Response:** Returns raw MIME messages. + +**Example Response:** + +```json +{ + "message": { + "mails": [ + "Delivered-To: me@s-aga-r.dev\r\nReceived-At: 2024-11-06T08:58:30.063Z\r\nAuthentication-Results: mail.s-aga-r.dev;\r\n\tspf=pass (mail.s-aga-r.dev: domain of sagar.s@frappemail.com designates 64.227.189.58 as permitted sender) smtp.mailfrom=sagar.s@frappemail.com smtp.helo=o1-blr.frappemail.com;\r\n\tdkim=pass header.i=@frappemail.com header.s=frappemail-com-d8852addda header.a=rsa-sha256 header.b=qJlPddwY;\r\n\tdmarc=pass (p=REJECT arc=none) header.from=frappemail.com header.d=frappemail.com;\r\n\tbimi=none\r\nReceived-SPF: pass (mail.s-aga-r.dev: domain of sagar.s@frappemail.com designates 64.227.189.58 as permitted sender) client-ip=64.227.189.58;\r\nReceived: from o1-blr.frappemail.com (o1-blr.frappemail.com [64.227.189.58])\r\n\tby mail.s-aga-r.dev (Haraka/3.0.3) with ESMTPS id EA28E71F-ED28-44DE-86E3-A783E1B759E0.1\r\n\tenvelope-from \r\n\ttls TLS_AES_256_GCM_SHA384;\r\n\tWed, 06 Nov 2024 08:58:29 +0000\r\nReceived: (Frappe Mail Agent); Wed, 06 Nov 2024 08:58:29 +0000\r\nReceived: from o1-blr.frappemail.com (ip6-localhost [::1])\r\n\tby o1-blr.frappemail.com (Haraka/3.0.3) with ESMTPSA id BF84C129-A129-4818-88F2-2A216D4D040D.1\r\n\tenvelope-from \r\n\ttls TLS_AES_256_GCM_SHA384 (authenticated bits=0);\r\n\tWed, 06 Nov 2024 08:58:29 +0000\r\nContent-Type: multipart/alternative;\r\n boundary=\"===============0863045983596233963==\"\r\nMIME-Version: 1.0\r\nFrom: Sagar Sharma \r\nTo: Sagar S \r\nSubject: Test Email\r\nDate: Wed, 06 Nov 2024 08:57:26 +0000\r\nMessage-ID: <173088344652.222.8316241415157629603@frappemail.com>\r\nX-Priority: 1\r\nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=frappemail.com;\r\n i=@frappemail.com; q=dns/txt; s=frappemail-com-d8852addda; t=1730883446; h=to\r\n : cc : from : date : subject : reply-to : message-id : in-reply-to;\r\n bh=k/MZq04SX5ovIG3cljRzVc8RLJpPS8/IC/KDyuOdV3I=;\r\n b=qJlPddwYBSyHtM/n34p3t3GLjmiHkbANF1m+9m/H4PgHC4LVwtgpS8Yo62uC4T84PoRqZ\r\n h5r+9Vcs/mgXcH2BeMyoqMO4H1Vk6iC6NvEYiHs+iQFjdwgKodpvLuSEls111e6U9+NCybq\r\n OwuDiQ28SiwvmdbVWOrxOACvl4LuJorWdIJ6i5iXelz/f52QMm1tlP2Wh2dXT7Mu6nTGO7g\r\n KpuieIHnDMTurQplxp2dOSnpwsw7I1sr3aHFDyP6oFONzMvTiK+/X2iCMg/W+nMjE4nz+2B\r\n DO7MTGFmB4RsUDyf+HtYVGFe/HggFK6XROWtUJR0CcmWVt9SeK3S5X+OT+tA==\r\nX-FM-OML: 019300b1-f29c-7868-af63-3513911e6801\r\nOriginal-Authentication-Results: o1-blr.frappemail.com;\r\n\tauth=pass (plain)\r\n\r\n--===============0863045983596233963==\r\nContent-Type: text/plain; charset=\"utf-8\"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: base64\r\n\r\nVGVzdCBFbWFpbA==\r\n\r\n--===============0863045983596233963==\r\nContent-Type: text/html; charset=\"utf-8\"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: base64\r\n\r\nPGh0bWw+PGJvZHk+PGltZyBzcmM9Imh0dHBzOi8vY2xpZW50LmZyYXBwZW1haWwuY29tL2FwaS9t\r\nZXRob2QvbWFpbC5hcGkudHJhY2sub3Blbj9pZD0wMTkzMDBiMTY3MjI3MGVjYWE0YWI5OTlmOTBm\r\nMmQ5MCI+PHA+VGVzdCBFbWFpbDwvcD48L2JvZHk+PC9odG1sPg==\r\n\r\n--===============0863045983596233963==--\r\n" + ], + "last_synced_at": "2024-11-06 08:58:55.528916+00:00", + "last_synced_mail": "019300b2-c261-71d1-bc8d-bc321cc9ebaf" + } +} +``` ## Contributing diff --git a/docs/screenshots/incoming-mail-accepted.png b/docs/screenshots/incoming-mail-accepted.png new file mode 100755 index 00000000..897b054e Binary files /dev/null and b/docs/screenshots/incoming-mail-accepted.png differ diff --git a/docs/screenshots/incoming-mail-auth-checks.png b/docs/screenshots/incoming-mail-auth-checks.png new file mode 100755 index 00000000..e114f592 Binary files /dev/null and b/docs/screenshots/incoming-mail-auth-checks.png differ diff --git a/docs/screenshots/incoming-mail-more-info.png b/docs/screenshots/incoming-mail-more-info.png new file mode 100755 index 00000000..3686f19f Binary files /dev/null and b/docs/screenshots/incoming-mail-more-info.png differ diff --git a/docs/screenshots/mail-alias.png b/docs/screenshots/mail-alias.png new file mode 100755 index 00000000..d2a37587 Binary files /dev/null and b/docs/screenshots/mail-alias.png differ diff --git a/docs/screenshots/mail-domain-dns-records.png b/docs/screenshots/mail-domain-dns-records.png new file mode 100755 index 00000000..f5b6b3ce Binary files /dev/null and b/docs/screenshots/mail-domain-dns-records.png differ diff --git a/docs/screenshots/mail-domain-new.png b/docs/screenshots/mail-domain-new.png new file mode 100755 index 00000000..3c36288a Binary files /dev/null and b/docs/screenshots/mail-domain-new.png differ diff --git a/docs/screenshots/mail-domain-verify-dns-records.png b/docs/screenshots/mail-domain-verify-dns-records.png new file mode 100755 index 00000000..d8eb919e Binary files /dev/null and b/docs/screenshots/mail-domain-verify-dns-records.png differ diff --git a/docs/screenshots/mail-settings-details.png b/docs/screenshots/mail-settings-details.png new file mode 100755 index 00000000..07a25711 Binary files /dev/null and b/docs/screenshots/mail-settings-details.png differ diff --git a/docs/screenshots/mail-settings-incoming.png b/docs/screenshots/mail-settings-incoming.png new file mode 100755 index 00000000..7b8994b2 Binary files /dev/null and b/docs/screenshots/mail-settings-incoming.png differ diff --git a/docs/screenshots/mailbox.png b/docs/screenshots/mailbox.png new file mode 100755 index 00000000..9b79eae6 Binary files /dev/null and b/docs/screenshots/mailbox.png differ diff --git a/docs/screenshots/outgoing-mail-sent.png b/docs/screenshots/outgoing-mail-sent.png new file mode 100755 index 00000000..acaeae41 Binary files /dev/null and b/docs/screenshots/outgoing-mail-sent.png differ diff --git a/docs/screenshots/outgoing-mail-smtp-response.png b/docs/screenshots/outgoing-mail-smtp-response.png new file mode 100755 index 00000000..05d0cdfb Binary files /dev/null and b/docs/screenshots/outgoing-mail-smtp-response.png differ diff --git a/docs/screenshots/outgoing-mail-tracking.png b/docs/screenshots/outgoing-mail-tracking.png new file mode 100755 index 00000000..b7d092c9 Binary files /dev/null and b/docs/screenshots/outgoing-mail-tracking.png differ diff --git a/docs/screenshots/outgoing-mail-transfer-now.png b/docs/screenshots/outgoing-mail-transfer-now.png new file mode 100755 index 00000000..54b2a429 Binary files /dev/null and b/docs/screenshots/outgoing-mail-transfer-now.png differ diff --git a/docs/screenshots/report-mail-tracker.png b/docs/screenshots/report-mail-tracker.png new file mode 100755 index 00000000..7b508b2c Binary files /dev/null and b/docs/screenshots/report-mail-tracker.png differ diff --git a/docs/screenshots/report-outbound-delay.png b/docs/screenshots/report-outbound-delay.png new file mode 100755 index 00000000..3271001b Binary files /dev/null and b/docs/screenshots/report-outbound-delay.png differ diff --git a/docs/screenshots/report-outgoing-mail-summary.png b/docs/screenshots/report-outgoing-mail-summary.png new file mode 100755 index 00000000..3e59e5f7 Binary files /dev/null and b/docs/screenshots/report-outgoing-mail-summary.png differ