Skip to content

Commit

Permalink
feat: Add reply_to_list functionality (#1062)
Browse files Browse the repository at this point in the history
  • Loading branch information
thepuzzlemaster committed Mar 21, 2023
1 parent c8076fa commit 4b5c605
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
28 changes: 28 additions & 0 deletions sendgrid/helpers/mail/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def __init__(
self._ip_pool_name = None
self._mail_settings = None
self._reply_to = None
self._reply_to_list = None
self._send_at = None
self._subject = None
self._template_id = None
Expand Down Expand Up @@ -695,6 +696,32 @@ def reply_to(self, value):
value = ReplyTo(value[0], value[1])
self._reply_to = value

@property
def reply_to_list(self):
"""A list of ReplyTo email addresses
:rtype: list(ReplyTo), tuple
"""
return self._reply_to_list

@reply_to_list.setter
def reply_to_list(self, value):
"""A list of ReplyTo email addresses
:param value: A list of ReplyTo email addresses
:type value: list(ReplyTo), tuple
"""
if isinstance(value, list):
for reply in value:
if isinstance(reply, ReplyTo):
if not isinstance(reply.email, str):
raise ValueError('You must provide an email for each entry in a reply_to_list')
else:
raise ValueError(
'Please use a list of ReplyTos for a reply_to_list.'
)
self._reply_to_list = value

@property
def contents(self):
"""The contents of the email
Expand Down Expand Up @@ -981,6 +1008,7 @@ def get(self):
'mail_settings': self._get_or_none(self.mail_settings),
'tracking_settings': self._get_or_none(self.tracking_settings),
'reply_to': self._get_or_none(self.reply_to),
'reply_to_list': [r.get() for r in self.reply_to_list or []],
}

return {key: value for key, value in mail.items()
Expand Down
90 changes: 90 additions & 0 deletions test/unit/test_mail_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,58 @@ def test_send_a_single_email_to_multiple_recipients(self):
}''')
)

def test_send_a_single_email_with_multiple_reply_to_addresses(self):
from sendgrid.helpers.mail import (Mail, From, ReplyTo, To, Subject,
PlainTextContent, HtmlContent)
self.maxDiff = None
message = Mail(
from_email=From('[email protected]', 'Example From Name'),
to_emails=To('[email protected]', 'Example To Name'),
subject=Subject('Sending with SendGrid is Fun'),
plain_text_content=PlainTextContent('and easy to do anywhere, even with Python'),
html_content=HtmlContent('<strong>and easy to do anywhere, even with Python</strong>'))

message.reply_to_list = [ReplyTo(email = '[email protected]'), ReplyTo(email = '[email protected]')]

self.assertEqual(
message.get(),
json.loads(r'''{
"content": [
{
"type": "text/plain",
"value": "and easy to do anywhere, even with Python"
},
{
"type": "text/html",
"value": "<strong>and easy to do anywhere, even with Python</strong>"
}
],
"from": {
"email": "[email protected]",
"name": "Example From Name"
},
"personalizations": [
{
"to": [
{
"email": "[email protected]",
"name": "Example To Name"
}
]
}
],
"reply_to_list": [
{
"email": "[email protected]"
},
{
"email": "[email protected]"
}
],
"subject": "Sending with SendGrid is Fun"
}''')
)

def test_multiple_emails_to_multiple_recipients(self):
from sendgrid.helpers.mail import (Mail, From, To, Subject,
PlainTextContent, HtmlContent,
Expand Down Expand Up @@ -568,6 +620,44 @@ def test_value_error_is_raised_on_to_emails_set_to_list_of_lists(self):
'and easy to do anywhere, even with Python'),
html_content=HtmlContent(
'<strong>and easy to do anywhere, even with Python</strong>'))

def test_value_error_is_raised_on_to_emails_set_to_reply_to_list_of_strs(self):
from sendgrid.helpers.mail import (PlainTextContent, HtmlContent)
self.maxDiff = None
to_emails = [
('[email protected]', 'Example To Name 0'),
('[email protected]', 'Example To Name 1')
]

mail = Mail(
from_email=From('[email protected]', 'Example From Name'),
to_emails=to_emails,
subject=Subject('Sending with SendGrid is Fun'),
plain_text_content=PlainTextContent(
'and easy to do anywhere, even with Python'),
html_content=HtmlContent(
'<strong>and easy to do anywhere, even with Python</strong>'))
with self.assertRaises(ValueError):
mail.reply_to_list = ['[email protected]', '[email protected]']

def test_value_error_is_raised_on_to_emails_set_to_reply_to_list_of_tuples(self):
from sendgrid.helpers.mail import (PlainTextContent, HtmlContent)
self.maxDiff = None
to_emails = [
('[email protected]', 'Example To Name 0'),
('[email protected]', 'Example To Name 1')
]

mail = Mail(
from_email=From('[email protected]', 'Example From Name'),
to_emails=to_emails,
subject=Subject('Sending with SendGrid is Fun'),
plain_text_content=PlainTextContent(
'and easy to do anywhere, even with Python'),
html_content=HtmlContent(
'<strong>and easy to do anywhere, even with Python</strong>'))
with self.assertRaises(ValueError):
mail.reply_to_list = [('[email protected]', 'Test Name')]

def test_error_is_not_raised_on_to_emails_set_to_list_of_tuples(self):
from sendgrid.helpers.mail import (PlainTextContent, HtmlContent)
Expand Down
29 changes: 29 additions & 0 deletions use_cases/send_a_single_email_with_multiple_reply_to_addresses.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
```python
import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

message = Mail(
from_email='[email protected]',
to_emails='[email protected]',
subject='Sending with Twilio SendGrid is Fun',
html_content='<strong>and easy to do anywhere, even with Python</strong>')
message.reply_to_list = [
ReplyTo(
email='[email protected]',
name="Reply To Name 1",
),
ReplyTo(
email='[email protected]',
name="Reply To Name 2",
)
]
try:
sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
response = sendgrid_client.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
print(e)
```

0 comments on commit 4b5c605

Please sign in to comment.