Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
nylas-python Changelog
======================

Unreleased
----------
* Fixed from field handling in messages.send() to properly map "from_" field to "from field

v6.12.0
----------
* Added Yahoo, Zoom, EWS as providers to models/auth.py
Expand Down
6 changes: 5 additions & 1 deletion nylas/resources/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,11 @@ def send(
json_body = None

# From is a reserved keyword in Python, so we need to pull the data from 'from_' instead
request_body["from"] = request_body.get("from_", None)
# Handle both dictionary-style "from" and typed "from_" field
if "from_" in request_body and "from" not in request_body:
request_body["from"] = request_body["from_"]
del request_body["from_"]
# If "from" already exists, leave it unchanged

# Use form data only if the attachment size is greater than 3mb
attachment_size = sum(
Expand Down
122 changes: 121 additions & 1 deletion tests/resources/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,4 +949,124 @@ def test_send_message_without_is_plaintext_backwards_compatibility(self, http_cl
request_body=request_body,
data=None,
overrides=None,
)
)

def test_send_message_with_from_field_mapping(self, http_client_response):
"""Test that from_ field is properly mapped to from field in request body."""
messages = Messages(http_client_response)
request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from_": [
{"name": "Daenerys Targaryen", "email": "daenerys.t@example.com"}
],
}

messages.send(identifier="abc-123", request_body=request_body)

# Verify that from_ was mapped to from and from_ was removed
expected_request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from": [{"name": "Daenerys Targaryen", "email": "daenerys.t@example.com"}],
}

http_client_response._execute.assert_called_once_with(
method="POST",
path="/v3/grants/abc-123/messages/send",
request_body=expected_request_body,
data=None,
overrides=None,
)

def test_send_message_with_existing_from_field_unchanged(
self, http_client_response
):
"""Test that existing from field is left unchanged when both from and from_ are present."""
messages = Messages(http_client_response)
request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from": [{"name": "Existing Sender", "email": "existing@example.com"}],
"from_": [
{"name": "Daenerys Targaryen", "email": "daenerys.t@example.com"}
],
}

messages.send(identifier="abc-123", request_body=request_body)

# Verify that the original from field is preserved and from_ is not processed
expected_request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from": [{"name": "Existing Sender", "email": "existing@example.com"}],
"from_": [
{"name": "Daenerys Targaryen", "email": "daenerys.t@example.com"}
],
}

http_client_response._execute.assert_called_once_with(
method="POST",
path="/v3/grants/abc-123/messages/send",
request_body=expected_request_body,
data=None,
overrides=None,
)

def test_send_message_with_only_from_field_unchanged(self, http_client_response):
"""Test that when only from field is present, it remains unchanged."""
messages = Messages(http_client_response)
request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from": [{"name": "Direct Sender", "email": "direct@example.com"}],
}

messages.send(identifier="abc-123", request_body=request_body)

# Verify that the from field remains unchanged
expected_request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
"from": [{"name": "Direct Sender", "email": "direct@example.com"}],
}

http_client_response._execute.assert_called_once_with(
method="POST",
path="/v3/grants/abc-123/messages/send",
request_body=expected_request_body,
data=None,
overrides=None,
)

def test_send_message_without_from_fields_unchanged(self, http_client_response):
"""Test that request body without from or from_ fields remains unchanged."""
messages = Messages(http_client_response)
request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
}

messages.send(identifier="abc-123", request_body=request_body)

# Verify that the request body remains unchanged
expected_request_body = {
"subject": "Hello from Nylas!",
"to": [{"name": "Jon Snow", "email": "jsnow@gmail.com"}],
"body": "This is the body of my message.",
}

http_client_response._execute.assert_called_once_with(
method="POST",
path="/v3/grants/abc-123/messages/send",
request_body=expected_request_body,
data=None,
overrides=None,
)