diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d31825..348b230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/nylas/resources/messages.py b/nylas/resources/messages.py index a61f037..d544cee 100644 --- a/nylas/resources/messages.py +++ b/nylas/resources/messages.py @@ -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( diff --git a/tests/resources/test_messages.py b/tests/resources/test_messages.py index bdf6760..1efe0aa 100644 --- a/tests/resources/test_messages.py +++ b/tests/resources/test_messages.py @@ -949,4 +949,124 @@ def test_send_message_without_is_plaintext_backwards_compatibility(self, http_cl request_body=request_body, data=None, overrides=None, - ) \ No newline at end of file + ) + + 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, + ) \ No newline at end of file