diff --git a/homeassistant/components/smtp/config_flow.py b/homeassistant/components/smtp/config_flow.py index e902be6c4dc8..7792cada1136 100644 --- a/homeassistant/components/smtp/config_flow.py +++ b/homeassistant/components/smtp/config_flow.py @@ -49,6 +49,8 @@ from . import SmtpConfigEntry from .const import ( CONF_ENCRYPTION, CONF_OLD_RECIPIENT, + CONF_REPLY_TO, + CONF_REPLY_TO_NAME, CONF_SENDER_NAME, CONF_SERVER, DEFAULT_ENCRYPTION, @@ -76,7 +78,14 @@ OPTIONS_SCHEMA = vol.Schema( ) ), vol.Coerce(int), - ) + ), + vol.Optional(CONF_REPLY_TO): TextSelector( + TextSelectorConfig( + type=TextSelectorType.EMAIL, + autocomplete="email", + ), + ), + vol.Optional(CONF_REPLY_TO_NAME): cv.string, } ) diff --git a/homeassistant/components/smtp/const.py b/homeassistant/components/smtp/const.py index e4888fa6b13a..f9c34eb4f0fb 100644 --- a/homeassistant/components/smtp/const.py +++ b/homeassistant/components/smtp/const.py @@ -29,3 +29,6 @@ ENCRYPTION_OPTIONS: Final = ["tls", "starttls", "none"] SUBENTRY_TYPE_RECIPIENT: Final = "recipient" CONF_ENTRY = "entry" CONF_OLD_RECIPIENT: Final = "old_recipient" + +CONF_REPLY_TO: Final = "reply_to" +CONF_REPLY_TO_NAME: Final = "reply_to_name" diff --git a/homeassistant/components/smtp/notify.py b/homeassistant/components/smtp/notify.py index d0597e52fcc0..910d3c6a0172 100644 --- a/homeassistant/components/smtp/notify.py +++ b/homeassistant/components/smtp/notify.py @@ -63,6 +63,8 @@ from .const import ( ATTR_PRIORITY, CONF_ENCRYPTION, CONF_ENTRY, + CONF_REPLY_TO, + CONF_REPLY_TO_NAME, CONF_SENDER_NAME, CONF_SERVER, DEFAULT_DEBUG, @@ -301,6 +303,15 @@ class MailNotifyEntity(NotifyEntity): "To", email.utils.formataddr((self._subentry.title, self._subentry.unique_id)), ) + + if reply_to := self._entry.options.get(CONF_REPLY_TO): + msg.add_header( + "Reply-To", + email.utils.formataddr( + (self._entry.options.get(CONF_REPLY_TO_NAME), reply_to) + ), + ) + msg.add_header("X-Mailer", "Home Assistant") msg.add_header("User-Agent", f"{APPLICATION_NAME}/{__version__}") msg.add_header("Date", email.utils.format_datetime(dt_util.now())) diff --git a/homeassistant/components/smtp/strings.json b/homeassistant/components/smtp/strings.json index 93d7f4b7a2fd..39e168d03878 100644 --- a/homeassistant/components/smtp/strings.json +++ b/homeassistant/components/smtp/strings.json @@ -68,9 +68,13 @@ "sections": { "options": { "data": { + "reply_to": "[%key:component::smtp::options::step::init::data::reply_to%]", + "reply_to_name": "[%key:component::smtp::options::step::init::data::reply_to_name%]", "timeout": "[%key:component::smtp::options::step::init::data::timeout%]" }, "data_description": { + "reply_to": "[%key:component::smtp::options::step::init::data_description::reply_to%]", + "reply_to_name": "[%key:component::smtp::options::step::init::data_description::reply_to_name%]", "timeout": "[%key:component::smtp::options::step::init::data_description::timeout%]" }, "name": "Additional options" @@ -149,9 +153,13 @@ "step": { "init": { "data": { + "reply_to": "Reply-To email address", + "reply_to_name": "Reply-To name", "timeout": "Connection timeout" }, "data_description": { + "reply_to": "Email address to use for recipient replies. If not specified, the sender's email address is used.", + "reply_to_name": "Display name shown as the Reply-To name.", "timeout": "Maximum time to wait for a response from the SMTP server before the connection attempt is aborted. Defaults to 60 seconds." } } diff --git a/tests/components/smtp/conftest.py b/tests/components/smtp/conftest.py index efd219472182..b6c41831aa52 100644 --- a/tests/components/smtp/conftest.py +++ b/tests/components/smtp/conftest.py @@ -7,6 +7,8 @@ import pytest from homeassistant.components.smtp.const import ( CONF_ENCRYPTION, + CONF_REPLY_TO, + CONF_REPLY_TO_NAME, CONF_SENDER_NAME, CONF_SERVER, DOMAIN, @@ -130,6 +132,8 @@ def mock_config_entry() -> MockConfigEntry: data=USER_INPUT, options={ CONF_TIMEOUT: 1312, + CONF_REPLY_TO: "replyto@example.com", + CONF_REPLY_TO_NAME: "Reply To Name", }, entry_id="123456789", subentries_data=[ diff --git a/tests/components/smtp/snapshots/test_notify.ambr b/tests/components/smtp/snapshots/test_notify.ambr index e3b67694c60f..25a0dae16e3d 100644 --- a/tests/components/smtp/snapshots/test_notify.ambr +++ b/tests/components/smtp/snapshots/test_notify.ambr @@ -58,6 +58,7 @@ Subject: Home Assistant From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 @@ -76,6 +77,7 @@ boundary="===============0000000000000000001==" From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 @@ -106,6 +108,7 @@ boundary="===============0000000000000000002==" From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 @@ -150,6 +153,7 @@ Content-Type: multipart/mixed; boundary="===============0000000000000000003==" From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 @@ -208,6 +212,7 @@ Content-Type: multipart/mixed; boundary="===============0000000000000000001==" From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 @@ -238,6 +243,7 @@ Content-Type: multipart/mixed; boundary="===============0000000000000000002==" From: Home Assistant To: Recipient + Reply-To: Reply To Name X-Mailer: Home Assistant User-Agent: HomeAssistant/2026.10.0 Date: Sat, 02 May 2026 20:09:37 -0700 diff --git a/tests/components/smtp/test_config_flow.py b/tests/components/smtp/test_config_flow.py index 491ea085583f..99812c71d5a2 100644 --- a/tests/components/smtp/test_config_flow.py +++ b/tests/components/smtp/test_config_flow.py @@ -6,6 +6,8 @@ from aiosmtplib import SMTPAuthenticationError, SMTPException, SMTPTimeoutError import pytest from homeassistant.components.smtp.const import ( + CONF_REPLY_TO, + CONF_REPLY_TO_NAME, CONF_SENDER_NAME, DOMAIN, SECTION_OPTIONS, @@ -53,7 +55,10 @@ async def test_form( result["flow_id"], { **USER_INPUT, - SECTION_OPTIONS: {}, + SECTION_OPTIONS: { + CONF_REPLY_TO: "replyto@example.com", + CONF_REPLY_TO_NAME: "Reply To Name", + }, }, ) await hass.async_block_till_done() @@ -61,7 +66,10 @@ async def test_form( assert result["type"] is FlowResultType.CREATE_ENTRY assert result["title"] == "Home Assistant" assert result["data"] == USER_INPUT - assert result["options"] == {} + assert result["options"] == { + CONF_REPLY_TO: "replyto@example.com", + CONF_REPLY_TO_NAME: "Reply To Name", + } assert len(mock_setup_entry.mock_calls) == 1 await hass.async_block_till_done(wait_background_tasks=True)