From 786adfd3417136c78529f81775fe38eda9ae9e7d Mon Sep 17 00:00:00 2001 From: s-aga-r Date: Mon, 9 Feb 2026 10:42:19 +0530 Subject: [PATCH] fix(Communication): set `In-Reply-To` (#36746) --- frappe/core/doctype/communication/email.py | 5 +++++ frappe/core/doctype/communication/mixins.py | 1 + frappe/email/doctype/email_queue/email_queue.py | 3 ++- frappe/public/js/frappe/views/communication.js | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index acbc27b2be..a3929a5860 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -52,6 +52,7 @@ def make( now=False, raw_html=False, add_css=True, + in_reply_to=None, **kwargs, ) -> dict[str, str]: """Make a new communication. Checks for email permissions for specified Document. @@ -73,6 +74,7 @@ def make( :param send_after: Send after the given datetime. :param raw_html: Whether to use html version of email template :param add_css: Add default CSS from hooks/email_css to the email template (default **True**) + :param in_reply_to: Name of the Communication document to which this communication is a reply. """ from frappe.utils.commands import warn @@ -127,6 +129,7 @@ def make( now=now, raw_html=raw_html, add_css=add_css, + in_reply_to=in_reply_to, ) @@ -157,6 +160,7 @@ def _make( now=False, raw_html=False, add_css=True, + in_reply_to=None, ) -> dict[str, str]: """Internal method to make a new communication that ignores Permission checks.""" @@ -185,6 +189,7 @@ def _make( "has_attachment": 1 if attachments else 0, "communication_type": communication_type, "send_after": send_after, + "in_reply_to": in_reply_to, } ) comm.flags.skip_add_signature = not add_signature or ( diff --git a/frappe/core/doctype/communication/mixins.py b/frappe/core/doctype/communication/mixins.py index edf14baca5..b2aaeb3979 100644 --- a/frappe/core/doctype/communication/mixins.py +++ b/frappe/core/doctype/communication/mixins.py @@ -311,6 +311,7 @@ class CommunicationEmailMixin: "send_after": self.send_after, "raw_html": raw_html, "add_css": add_css, + "in_reply_to": self.in_reply_to, } def send_email( diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py index 3ce20a0d12..738125799c 100644 --- a/frappe/email/doctype/email_queue/email_queue.py +++ b/frappe/email/doctype/email_queue/email_queue.py @@ -755,7 +755,8 @@ class QueueBuilder: mail.msg_root["Disposition-Notification-To"] = self.sender if self.in_reply_to: if message_id := frappe.db.get_value("Communication", self.in_reply_to, "message_id"): - mail.set_in_reply_to(get_string_between("<", message_id, ">")) + message_id = message_id.strip("<> \t\n") + mail.set_in_reply_to(f"<{message_id}>") return mail def process(self, send_now=False) -> EmailQueue | None: diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index bd6c0b7865..34871f275b 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -870,6 +870,7 @@ frappe.views.CommunicationComposer = class { print_language: form_values.print_language, raw_html: form_values.use_html, add_css: form_values.add_css, + in_reply_to: (this.is_a_reply && this.last_email?.name) || null, }, btn, callback(r) {