Skip to content

Commit 55102de

Browse files
Rename to EmailAttachmentV2
1 parent d9b03d9 commit 55102de

5 files changed

Lines changed: 16 additions & 22 deletions

File tree

app/backend/proto/internal/jobs.proto

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@ message SendEmailPayload {
1414
string list_unsubscribe_header = 7;
1515
// source data as to where this email came from
1616
string source_data = 8;
17-
repeated EmailAttachment attachments = 9;
17+
reserved 9; // Previous "attachments" field, which had mime_type+filename subfields.
18+
repeated EmailAttachmentV2 attachments = 10;
1819
}
1920

20-
message EmailAttachment {
21-
reserved 1, 2;
22-
reserved "filename", "mime_type";
23-
bytes data = 3;
24-
string content_disposition = 4; // The Content-Disposition header, including parameters
25-
string content_type = 5; // The Content-Type header, including parameters
21+
message EmailAttachmentV2 {
22+
bytes data = 1;
23+
string content_disposition = 2; // The Content-Disposition header, including parameters
24+
string content_type = 3; // The Content-Type header, including parameters
2625
}
2726

2827
message HandleNotificationPayload {

app/backend/src/couchers/email/calendar_events.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
from couchers.config import config
88
from couchers.email.rendering import get_emails_i18next
99
from couchers.i18n import LocalizationContext
10-
from couchers.proto.internal.jobs_pb2 import EmailAttachment
10+
from couchers.proto.internal.jobs_pb2 import EmailAttachmentV2
1111
from couchers.proto.requests_pb2 import HostRequest
1212

1313
HOST_REQUEST_ICS_FILENAME = "host_request.ics"
1414

1515

1616
def create_host_request_attachment(
1717
host_request: HostRequest, other_name: str, hosting: bool, loc_context: LocalizationContext
18-
) -> EmailAttachment:
18+
) -> EmailAttachmentV2:
1919
calendar = create_host_request_calendar(host_request, other_name, hosting, loc_context)
2020
return calendar_to_attachment(calendar, HOST_REQUEST_ICS_FILENAME)
2121

@@ -67,7 +67,7 @@ def create_host_request_event(
6767

6868
def create_host_request_cancellation_attachment(
6969
host_request: HostRequest, other_name: str, hosting: bool, loc_context: LocalizationContext
70-
) -> EmailAttachment:
70+
) -> EmailAttachmentV2:
7171
calendar = create_host_request_cancellation_calendar(host_request, other_name, hosting, loc_context)
7272
return calendar_to_attachment(calendar, HOST_REQUEST_ICS_FILENAME)
7373

@@ -96,7 +96,7 @@ def event_to_calendar(event: Event, method: str | None, loc_context: Localizatio
9696
return calendar
9797

9898

99-
def calendar_to_attachment(calendar: Calendar, filename: str) -> EmailAttachment:
99+
def calendar_to_attachment(calendar: Calendar, filename: str) -> EmailAttachmentV2:
100100
data = calendar.serialize().encode("utf-8")
101101
content_disposition = f'attachment; filename="{filename}"'
102102
content_type = 'text/calendar; charset="utf-8"'
@@ -105,7 +105,7 @@ def calendar_to_attachment(calendar: Calendar, filename: str) -> EmailAttachment
105105
# AI recommends avoiding quotes on this parameter for backwards compatibility with old email clients.
106106
content_type += f"; method={calendar.method}"
107107

108-
return EmailAttachment(data=data, content_disposition=content_disposition, content_type=content_type)
108+
return EmailAttachmentV2(data=data, content_disposition=content_disposition, content_type=content_type)
109109

110110

111111
def get_host_request_event_uid(host_request_id: int) -> str:

app/backend/src/couchers/email/smtp.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,6 @@ def email_proto_to_message(payload: jobs_pb2.SendEmailPayload, couchers_id: str)
5757

5858
if payload.attachments:
5959
for attachment in payload.attachments:
60-
# Versioning (2026-05): ignore older SendEmailPayload that did not specify headers.
61-
# They were used for incorrectly formatted ics attachments.
62-
if not attachment.content_type or not attachment.content_disposition:
63-
continue
64-
6560
# Create with generic Content-Type/Content-Disposition headers,
6661
# then overwrite them with the headers specified by the caller.
6762
msg.add_attachment(

app/backend/src/couchers/notifications/render_email.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
generate_unsub_topic_key,
1818
)
1919
from couchers.proto import api_pb2, notification_data_pb2
20-
from couchers.proto.internal.jobs_pb2 import EmailAttachment
20+
from couchers.proto.internal.jobs_pb2 import EmailAttachmentV2
2121
from couchers.templating import Jinja2Template, template_folder
2222
from couchers.utils import now, to_aware_datetime
2323

@@ -31,7 +31,7 @@ class RenderedEmailNotification:
3131
body_html: str | None
3232
source_data: str | None
3333
list_unsubscribe_header: str | None
34-
attachments: list[EmailAttachment] = field(default_factory=list)
34+
attachments: list[EmailAttachmentV2] = field(default_factory=list)
3535

3636

3737
def render_email_notification(
@@ -770,7 +770,7 @@ def _get_custom_templated_email(notification: Notification, loc_context: Localiz
770770
raise NotImplementedError(f"Unknown topic-action: {notification.topic}:{notification.action}")
771771

772772

773-
def get_ics_attachment(notification: Notification, loc_context: LocalizationContext) -> EmailAttachment | None:
773+
def get_ics_attachment(notification: Notification, loc_context: LocalizationContext) -> EmailAttachmentV2 | None:
774774
data = notification.topic_action.data_type.FromString(notification.data) # type: ignore[attr-defined]
775775
if notification.topic_action == NotificationTopicAction.host_request__accept:
776776
# Caveat: The surfer technically still hasn't confirmed, but when they do they don't receive an email,

app/backend/src/tests/test_smtp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from couchers.email.smtp import email_proto_to_message
2-
from couchers.proto.internal.jobs_pb2 import EmailAttachment, SendEmailPayload
2+
from couchers.proto.internal.jobs_pb2 import EmailAttachmentV2, SendEmailPayload
33

44

55
def test_verbatim_attachment_headers():
@@ -15,7 +15,7 @@ def test_verbatim_attachment_headers():
1515
subject="greeting",
1616
plain="hello",
1717
attachments=[
18-
EmailAttachment(
18+
EmailAttachmentV2(
1919
data=bytes([0, 255]), # Force base64 encoding
2020
content_type='maintype/subtype; quoted-header="value"; unquoted-header=value',
2121
content_disposition="attachment",

0 commit comments

Comments
 (0)