feat: ✨ addes x-priority option to email header and the frappe.sendmail function (#31966)
creating the option to give the email an importance. 1 = Highest, 3 = Normal, 5 = Lowest commonly used to flag the importance of emails Co-authored-by: Jan Lukas Liesen <=>
This commit is contained in:
parent
34e1d58973
commit
89ed7c90a7
3 changed files with 34 additions and 2 deletions
|
|
@ -507,6 +507,7 @@ def sendmail(
|
|||
print_letterhead=False,
|
||||
with_container=False,
|
||||
email_read_tracker_url=None,
|
||||
x_priority: Literal[1, 3, 5] = 3,
|
||||
) -> Optional["EmailQueue"]:
|
||||
"""Send email using user's default **Email Account** or global default **Email Account**.
|
||||
|
||||
|
|
@ -534,6 +535,7 @@ def sendmail(
|
|||
:param args: Arguments for rendering the template
|
||||
:param header: Append header in email
|
||||
:param with_container: Wraps email inside a styled container
|
||||
:param x_priority: 1 = HIGHEST, 3 = NORMAL, 5 = LOWEST
|
||||
"""
|
||||
|
||||
if recipients is None:
|
||||
|
|
@ -589,6 +591,7 @@ def sendmail(
|
|||
print_letterhead=print_letterhead,
|
||||
with_container=with_container,
|
||||
email_read_tracker_url=email_read_tracker_url,
|
||||
x_priority=x_priority,
|
||||
)
|
||||
|
||||
# build email queue and send the email if send_now is True.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
# Copyright (c) 2015, Frappe Technologies and contributors
|
||||
# License: MIT. See LICENSE
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import quopri
|
||||
import traceback
|
||||
from contextlib import suppress
|
||||
from email.parser import Parser
|
||||
from email.policy import SMTP
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import frappe
|
||||
from frappe import _, safe_encode, task
|
||||
|
|
@ -34,6 +37,9 @@ from frappe.utils import (
|
|||
)
|
||||
from frappe.utils.verified_command import get_signed_params
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Literal
|
||||
|
||||
|
||||
class EmailQueue(Document):
|
||||
# begin: auto-generated types
|
||||
|
|
@ -88,7 +94,7 @@ class EmailQueue(Document):
|
|||
return duplicate
|
||||
|
||||
@classmethod
|
||||
def new(cls, doc_data, ignore_permissions=False) -> "EmailQueue":
|
||||
def new(cls, doc_data, ignore_permissions=False) -> EmailQueue:
|
||||
data = doc_data.copy()
|
||||
if not data.get("recipients"):
|
||||
return
|
||||
|
|
@ -104,7 +110,7 @@ class EmailQueue(Document):
|
|||
return doc
|
||||
|
||||
@classmethod
|
||||
def find(cls, name) -> "EmailQueue":
|
||||
def find(cls, name) -> EmailQueue:
|
||||
return frappe.get_doc(cls.DOCTYPE, name)
|
||||
|
||||
@classmethod
|
||||
|
|
@ -502,6 +508,7 @@ class QueueBuilder:
|
|||
print_letterhead=False,
|
||||
with_container=False,
|
||||
email_read_tracker_url=None,
|
||||
x_priority: Literal[1, 3, 5] = 3,
|
||||
):
|
||||
"""Add email to sending queue (Email Queue)
|
||||
|
||||
|
|
@ -527,6 +534,7 @@ class QueueBuilder:
|
|||
:param header: Append header in email (boolean)
|
||||
:param with_container: Wraps email inside styled container
|
||||
:param email_read_tracker_url: A URL for tracking whether an email is read by the recipient.
|
||||
:param x_priority: 1 = HIGHEST, 3 = NORMAL, 5 = LOWEST
|
||||
"""
|
||||
|
||||
self._unsubscribe_method = unsubscribe_method
|
||||
|
|
@ -537,6 +545,7 @@ class QueueBuilder:
|
|||
self._sender = sender
|
||||
self._text_content = text_content
|
||||
self._message = message
|
||||
self._x_priority: Literal[1, 3, 5] = x_priority
|
||||
self._add_unsubscribe_link = add_unsubscribe_link
|
||||
self._unsubscribe_message = unsubscribe_message
|
||||
self._attachments = attachments
|
||||
|
|
@ -710,6 +719,7 @@ class QueueBuilder:
|
|||
expose_recipients=self.expose_recipients,
|
||||
inline_images=self.inline_images,
|
||||
header=self.header,
|
||||
x_priority=self._x_priority,
|
||||
)
|
||||
|
||||
mail.set_message_id(self.message_id, self.is_notification)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: MIT. See LICENSE
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import email.utils
|
||||
import os
|
||||
import re
|
||||
from email import policy
|
||||
from email.header import Header
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import frappe
|
||||
from frappe.email.doctype.email_account.email_account import EmailAccount
|
||||
|
|
@ -23,6 +27,9 @@ from frappe.utils import (
|
|||
)
|
||||
from frappe.utils.pdf import get_pdf
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Literal
|
||||
|
||||
EMBED_PATTERN = re.compile("""embed=["'](.*?)["']""")
|
||||
|
||||
|
||||
|
|
@ -44,6 +51,7 @@ def get_email(
|
|||
expose_recipients=None,
|
||||
inline_images=None,
|
||||
header=None,
|
||||
x_priority: Literal[1, 3, 5] = 3,
|
||||
):
|
||||
"""Prepare an email with the following format:
|
||||
- multipart/mixed
|
||||
|
|
@ -72,6 +80,7 @@ def get_email(
|
|||
bcc=bcc,
|
||||
email_account=email_account,
|
||||
expose_recipients=expose_recipients,
|
||||
x_priority=x_priority,
|
||||
)
|
||||
|
||||
if not content.strip().startswith("<"):
|
||||
|
|
@ -117,6 +126,7 @@ class EMail:
|
|||
bcc=(),
|
||||
email_account=None,
|
||||
expose_recipients=None,
|
||||
x_priority: Literal[1, 3, 5] = 3,
|
||||
):
|
||||
from email import charset as Charset
|
||||
|
||||
|
|
@ -142,6 +152,8 @@ class EMail:
|
|||
self.bcc = bcc or []
|
||||
self.html_set = False
|
||||
|
||||
self.x_priority: Literal[1, 3, 5] = x_priority
|
||||
|
||||
self.email_account = email_account or EmailAccount.find_outgoing(
|
||||
match_by_email=sender, _raise_error=True
|
||||
)
|
||||
|
|
@ -315,6 +327,13 @@ class EMail:
|
|||
"X-Frappe-Site": get_url(),
|
||||
}
|
||||
|
||||
if self.x_priority != 3:
|
||||
headers.update(
|
||||
{
|
||||
"X-Priority": str(self.x_priority),
|
||||
}
|
||||
)
|
||||
|
||||
# reset headers as values may be changed.
|
||||
for key, val in headers.items():
|
||||
if val:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue