feat: "Email sent" column and per-event copy-to-organizer BCC
Organizers had no way to see whether a ticket email went out short of
reading the Postfix journal, and no copy of what the attendee received —
LNbits submits over SMTP, so nothing lands in a Sent folder.
- Admin ticket table gains an "Email sent" column derived from
`extra.email_notification_sent` ("✓ sent" / "not sent" / "unpaid" /
"no email").
- `extra.copy_to_organizer`: BCC every ticket email to the event's
reply-to address (explicit, else the owner's account email) on the SMTP
envelope only — no Bcc/To header, and skipped when the buyer *is* that
address. Toggle sits with the other delivery switches in the admin form.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
This commit is contained in:
parent
72b9c540f7
commit
a44de1aa3f
5 changed files with 73 additions and 1 deletions
15
services.py
15
services.py
|
|
@ -255,6 +255,13 @@ async def _deliver_ticket_notifications(
|
|||
if result.email.attempted:
|
||||
try:
|
||||
assert ticket.email
|
||||
bcc = (
|
||||
[reply_to]
|
||||
if event.extra.copy_to_organizer
|
||||
and reply_to
|
||||
and reply_to.lower() != ticket.email.lower()
|
||||
else []
|
||||
)
|
||||
card = render_ticket_card(
|
||||
ticket,
|
||||
event,
|
||||
|
|
@ -271,6 +278,7 @@ async def _deliver_ticket_notifications(
|
|||
],
|
||||
reply_to=reply_to,
|
||||
sender_name=organizer_sender_name(event),
|
||||
bcc=bcc,
|
||||
)
|
||||
ticket.extra.email_notification_sent = True
|
||||
result.email.sent = True
|
||||
|
|
@ -304,6 +312,7 @@ async def _send_ticket_email_notification(
|
|||
attachments: list[tuple[str, bytes]] | None = None,
|
||||
reply_to: str | None = None,
|
||||
sender_name: str | None = None,
|
||||
bcc: list[str] | None = None,
|
||||
) -> None:
|
||||
"""Multipart (text + HTML) ticket email through the instance SMTP
|
||||
settings. Core's `send_email_notification` is plain-text only, which is
|
||||
|
|
@ -320,6 +329,10 @@ async def _send_ticket_email_notification(
|
|||
for address in to_emails:
|
||||
if not is_valid_email_address(address):
|
||||
raise ValueError(f"Invalid email address: {address}")
|
||||
# BCC recipients ride only on the SMTP envelope, never in a header.
|
||||
envelope_recipients = list(to_emails) + [
|
||||
b for b in (bcc or []) if is_valid_email_address(b)
|
||||
]
|
||||
|
||||
msg = build_ticket_email(
|
||||
from_email,
|
||||
|
|
@ -339,7 +352,7 @@ async def _send_ticket_email_notification(
|
|||
username,
|
||||
settings.lnbits_email_notifications_password,
|
||||
from_email,
|
||||
to_emails,
|
||||
envelope_recipients,
|
||||
msg.as_string(),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue