Skip to content

Conversation

@slavaGanzin
Copy link

@slavaGanzin slavaGanzin commented Nov 13, 2025

Reply-To header was empty if reply_to was used.

Fixed by using _reply_to for checks and reply_to for the formatted header value.

Before (broken):

From: "domain.com" <[email protected]>
To: [email protected]
Reply-To:                          ← Empty string

After (fixed):

From: "domain.com" <[email protected]>
To: [email protected]
Reply-To: [email protected]         ← Works

Tested with real SMTP server, delivered to Gmail successfully.

# cat test-fix.py 
#!/usr/bin/env python3
"""Test the Reply-To fix"""
from apprise.plugins.email import NotifyEmail
from apprise import NotifyFormat

DOMAIN = "domain.com"
MAIL_HOST = ""

to_email = "[email protected]"
subject = "Testing Reply-To Fix"
body = "This email should have proper Reply-To header from the fixed Apprise"
from_addr = "Test <[email protected]>"
reply_to = "XXX <[email protected]>"

auth_email = f"test@{DOMAIN}"
auth_password = ""

# Test with native reply_to parameter (should work now)
email_plugin = NotifyEmail(
    smtp_host=MAIL_HOST,
    user=auth_email,
    password=auth_password,
    from_addr=from_addr,
    targets=[to_email],
    reply_to=[reply_to],
    secure_mode='starttls',
    port=587
)

print("Email plugin created with native reply_to parameter")
print(f"  from_addr: {email_plugin.from_addr}")
print(f"  targets: {email_plugin.targets}")
print(f"  reply_to: {email_plugin.reply_to}")
print(f"  names: {email_plugin.names}")
print("")

# Generate the email messages to inspect them
for message in NotifyEmail.prepare_emails(
    subject=subject,
    body=body,
    from_addr=email_plugin.from_addr,
    to=email_plugin.targets,
    reply_to=email_plugin.reply_to,
    smtp_host=MAIL_HOST,
    notify_format=NotifyFormat.TEXT,
    names=email_plugin.names
):
    print("Generated email message headers:")
    print(f"  Recipient: {message.recipient}")
    print(f"  To addrs: {message.to_addrs}")
    print("")

    # Parse the body to extract headers
    lines = message.body.split('\n')
    for line in lines[:25]:
        print(line)
        if line.strip() == '' and 'Reply-To' in message.body[:500]:
            break

print("")
print("Sending email...")
email_plugin.notify(title=subject, body=body)
print("✓ Email sent")

@codecov
Copy link

codecov bot commented Nov 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.65%. Comparing base (96afd4d) to head (9ab5599).
⚠️ Report is 6 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff            @@
##           master    #1446    +/-   ##
========================================
  Coverage   99.65%   99.65%            
========================================
  Files         175      176     +1     
  Lines       22660    22853   +193     
  Branches     3603     3650    +47     
========================================
+ Hits        22582    22775   +193     
  Misses         70       70            
  Partials        8        8            
Files with missing lines Coverage Δ
apprise/plugins/bark.py 100.00% <100.00%> (ø)
apprise/plugins/dot.py 100.00% <100.00%> (ø)
apprise/plugins/email/base.py 100.00% <100.00%> (ø)
apprise/plugins/matrix.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@caronc
Copy link
Owner

caronc commented Nov 15, 2025

Looks good; try running tox -e format to fix any linting issue introduced. Your changes are pretty small so i'm not sure what it is at first glance.

@slavaGanzin
Copy link
Author

slavaGanzin commented Nov 20, 2025

Thanks @caronc it was

E501 Line too long (92 > 79)
    --> apprise/plugins/email/base.py:1030:80
     |
1028 |             _bcc = bcc - {to_addr}
1029 |
1030 |             # Strip target out of reply_to list if in To (no need to Reply-To the recipient)
     |                                                                                ^^^^^^^^^^^^^
1031 |             _reply_to = reply_to - {to_addr}
     |

Found 1 error.

@caronc
Copy link
Owner

caronc commented Nov 21, 2025

Your great PR got very distorted; there are tons of line changes now that are not applicable to your objective anymore.

You'll need to fix your branch now and rebase it. Alternatively, create a new pr and try again.

The Reply-To header was not being set due to inconsistent variable usage
between reply_to (unfiltered) and _reply_to (filtered) in prepare_emails().

Bugs fixed:
1. Line 1045: Check _reply_to instead of reply_to before formatting
2. Line 1047: Format _reply_to and assign to reply_to (formatted list)
3. Line 1178: Check _reply_to instead of reply_to before setting header

The filtering logic (_reply_to = reply_to - {to_addr}) is correct and
intentional - it removes redundant Reply-To when it matches the recipient.

Result:
- When Reply-To differs from TO: Header is set with formatted addresses
- When Reply-To equals TO: Header is omitted (no redundancy)
@slavaGanzin
Copy link
Author

@caronc yep, that rebase went wrong, thanks for catching it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants