Skip to content

Commit d226ff1

Browse files
Investigate and fix email subject encoding issue (#442)
Co-authored-by: Cursor Agent <[email protected]>
1 parent 0a65ea2 commit d226ff1

File tree

9 files changed

+771
-38
lines changed

9 files changed

+771
-38
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ v6.13.0
55
----------
66
* Fixed from field handling in messages.send() to properly map "from_" field to "from field
77
* Fixed content_id handling for large inline attachments to use content_id as field name instead of generic file{index}
8+
* Fixed UTF-8 character encoding for all API requests to preserve special characters (accented letters, emoji, etc.) instead of escaping them as unicode sequences
89

910
v6.12.0
1011
----------
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Special Characters Encoding Example
2+
3+
This example demonstrates how the Nylas Python SDK correctly handles special characters (accented letters, unicode characters) in email subjects and message bodies.
4+
5+
## The Problem
6+
7+
Previously, when sending emails with large attachments (>3MB), special characters in the subject line would be incorrectly encoded. For example:
8+
9+
- **Intended Subject:** "De l'idée à la post-prod, sans friction"
10+
- **What Recipients Saw:** "De l’idée à la post-prod, sans friction"
11+
12+
This issue occurred because the SDK was using `json.dumps()` with the default `ensure_ascii=True` parameter when creating multipart/form-data requests for large attachments.
13+
14+
## The Solution
15+
16+
The SDK now uses `json.dumps(request_body, ensure_ascii=False)` to preserve UTF-8 characters correctly in the JSON payload, ensuring that special characters are displayed properly in recipient inboxes.
17+
18+
## What This Example Demonstrates
19+
20+
1. **Small Messages** - Sending messages with special characters (no attachments)
21+
2. **Large Messages** - Sending messages with special characters AND large attachments (>3MB)
22+
3. **Drafts** - Creating drafts with special characters
23+
4. **International Support** - Handling various international character sets
24+
25+
## Usage
26+
27+
### Prerequisites
28+
29+
1. Install the SDK in development mode:
30+
```bash
31+
cd /path/to/nylas-python
32+
pip install -e .
33+
```
34+
35+
2. Set up environment variables:
36+
```bash
37+
export NYLAS_API_KEY="your_api_key"
38+
export NYLAS_GRANT_ID="your_grant_id"
39+
export RECIPIENT_EMAIL="[email protected]"
40+
```
41+
42+
### Run the Example
43+
44+
```bash
45+
python examples/special_characters_demo/special_characters_example.py
46+
```
47+
48+
## Test Coverage
49+
50+
This fix is covered by comprehensive tests:
51+
52+
```bash
53+
# Test the core fix in file_utils
54+
pytest tests/utils/test_file_utils.py::TestFileUtils::test_build_form_request_with_special_characters
55+
56+
# Test message sending with special characters
57+
pytest tests/resources/test_messages.py::TestMessage::test_send_message_with_special_characters_in_subject
58+
pytest tests/resources/test_messages.py::TestMessage::test_send_message_with_special_characters_large_attachment
59+
60+
# Test draft creation with special characters
61+
pytest tests/resources/test_drafts.py::TestDraft::test_create_draft_with_special_characters_in_subject
62+
pytest tests/resources/test_drafts.py::TestDraft::test_create_draft_with_special_characters_large_attachment
63+
```
64+
65+
## Supported Character Sets
66+
67+
The SDK correctly handles:
68+
69+
- **French:** é, è, ê, à, ù, ç, œ
70+
- **Spanish:** ñ, á, í, ó, ú, ¿, ¡
71+
- **German:** ä, ö, ü, ß
72+
- **Portuguese:** ã, õ, â, ê
73+
- **Italian:** à, è, é, ì, ò, ù
74+
- **Russian:** Cyrillic characters
75+
- **Japanese:** Hiragana, Katakana, Kanji
76+
- **Chinese:** Simplified and Traditional characters
77+
- **Emoji:** 🎉 🎊 🥳 and many more
78+
- **Special symbols:** €, £, ¥, ©, ®, ™
79+
80+
## Technical Details
81+
82+
### The Bug
83+
84+
When using multipart/form-data encoding (for large attachments), the message payload was serialized as:
85+
86+
```python
87+
message_payload = json.dumps(request_body) # Default: ensure_ascii=True
88+
```
89+
90+
This caused special characters to be escaped as unicode sequences:
91+
```json
92+
{"subject": "De l\u2019id\u00e9e"}
93+
```
94+
95+
### The Fix
96+
97+
The payload is now serialized as:
98+
99+
```python
100+
message_payload = json.dumps(request_body, ensure_ascii=False)
101+
```
102+
103+
This preserves the actual UTF-8 characters:
104+
```json
105+
{"subject": "De l'idée"}
106+
```
107+
108+
The multipart/form-data Content-Type header correctly specifies UTF-8 encoding, ensuring email clients display the characters properly.
109+
110+
## Related Files
111+
112+
- **Core Fix:** `nylas/utils/file_utils.py` - Line 70
113+
- **Tests:** `tests/utils/test_file_utils.py`, `tests/resources/test_messages.py`, `tests/resources/test_drafts.py`
114+
- **Example:** `examples/special_characters_demo/special_characters_example.py`
115+
116+
## Impact
117+
118+
**Before Fix:** Special characters in subjects were garbled when sending emails with large attachments
119+
**After Fix:** All special characters are correctly preserved and displayed
120+
121+
The fix ensures backwards compatibility - all existing code continues to work without changes.

0 commit comments

Comments
 (0)