Skip to content

Commit a97e83a

Browse files
author
Bilal Boussayoud
authored
feat: allow personalization of the From name and email for each recipient (sendgrid#1020)
* feat: allow personalization of the From name and email for each recipient
1 parent 2e12f1c commit a97e83a

File tree

6 files changed

+126
-14
lines changed

6 files changed

+126
-14
lines changed

examples/helpers/README.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,16 @@ For more information on parameters and usage, see [here](../mail/mail.py)
2828

2929
### Creating Personalizations
3030

31-
To create personalizations, you need a dictionary to store all your email components. See example [here](https://github.com/sendgrid/sendgrid-python/blob/0b683169b08d3a7c204107cd333be33053297e74/examples/helpers/mail_example.py#L47)
32-
After creating a dictionary, you can go ahead and create a `Personalization` object.
31+
The personalization helper can be used to create personalizations and customize various aspects of an email. See example [here](mail_example.py) in `build_multiple_emails_personalized()`, and refer [here](https://docs.sendgrid.com/for-developers/sending-email/personalizations) for more documentation.
3332
```
3433
mock_personalization = Personalization()
35-
for to_addr in personalization['to_list']:
36-
mock_personalization.add_to(to_addr)
34+
35+
for to_addr in personalization['to_list']:
36+
mock_personalization.add_to(to_addr)
37+
38+
mock_personalization.set_from(from_addr)
39+
mock_personalization.add_cc(cc_addr)
40+
# etc...
3741
```
3842

3943
### Creating Attachments

examples/helpers/mail_example.py

+56-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def build_hello_email():
1313
from sendgrid import SendGridAPIClient
1414
from sendgrid.helpers.mail import Mail, From, To, Subject, PlainTextContent, HtmlContent, SendGridException
1515

16-
message = Mail(from_email=From('[email protected].com', 'Example From Name'),
16+
message = Mail(from_email=From('[email protected]', 'Example From Name'),
1717
to_emails=To('[email protected]', 'Example To Name'),
1818
subject=Subject('Sending with SendGrid is Fun'),
1919
plain_text_content=PlainTextContent('and easy to do anywhere, even with Python'),
@@ -26,25 +26,30 @@ def build_hello_email():
2626
except SendGridException as e:
2727
print(e.message)
2828

29-
for cc_addr in personalization['cc_list']:
29+
mock_personalization = Personalization()
30+
personalization_dict = get_mock_personalization_dict()
31+
32+
for cc_addr in personalization_dict['cc_list']:
3033
mock_personalization.add_to(cc_addr)
3134

32-
for bcc_addr in personalization['bcc_list']:
35+
for bcc_addr in personalization_dict['bcc_list']:
3336
mock_personalization.add_bcc(bcc_addr)
3437

35-
for header in personalization['headers']:
38+
for header in personalization_dict['headers']:
3639
mock_personalization.add_header(header)
3740

38-
for substitution in personalization['substitutions']:
41+
for substitution in personalization_dict['substitutions']:
3942
mock_personalization.add_substitution(substitution)
4043

41-
for arg in personalization['custom_args']:
44+
for arg in personalization_dict['custom_args']:
4245
mock_personalization.add_custom_arg(arg)
4346

44-
mock_personalization.subject = personalization['subject']
45-
mock_personalization.send_at = personalization['send_at']
46-
return mock_personalization
47+
mock_personalization.subject = personalization_dict['subject']
48+
mock_personalization.send_at = personalization_dict['send_at']
49+
50+
message.add_personalization(mock_personalization)
4751

52+
return message
4853

4954
def get_mock_personalization_dict():
5055
"""Get a dict of personalization mock."""
@@ -78,6 +83,36 @@ def get_mock_personalization_dict():
7883
mock_pers['send_at'] = 1443636843
7984
return mock_pers
8085

86+
def build_multiple_emails_personalized():
87+
import json
88+
from sendgrid.helpers.mail import Mail, From, To, Cc, Bcc, Subject, PlainTextContent, \
89+
HtmlContent, SendGridException, Personalization
90+
91+
# Note that the domain for all From email addresses must match
92+
message = Mail(from_email=From('[email protected]', 'Example From Name'),
93+
subject=Subject('Sending with SendGrid is Fun'),
94+
plain_text_content=PlainTextContent('and easy to do anywhere, even with Python'),
95+
html_content=HtmlContent('<strong>and easy to do anywhere, even with Python</strong>'))
96+
97+
mock_personalization = Personalization()
98+
mock_personalization.add_to(To('[email protected]', 'Example User 1'))
99+
mock_personalization.add_cc(Cc('[email protected]', 'Example User 2'))
100+
message.add_personalization(mock_personalization)
101+
102+
mock_personalization_2 = Personalization()
103+
mock_personalization_2.add_to(To('[email protected]', 'Example User 3'))
104+
mock_personalization_2.set_from(From('[email protected]', 'Example From Name 2'))
105+
mock_personalization_2.add_bcc(Bcc('[email protected]', 'Example User 4'))
106+
message.add_personalization(mock_personalization_2)
107+
108+
try:
109+
print(json.dumps(message.get(), sort_keys=True, indent=4))
110+
return message.get()
111+
112+
except SendGridException as e:
113+
print(e.message)
114+
115+
return message
81116

82117
def build_attachment1():
83118
"""Build attachment mock. Make sure your content is base64 encoded before passing into attachment.content.
@@ -308,6 +343,15 @@ def build_kitchen_sink():
308343

309344
return message
310345

346+
def send_multiple_emails_personalized():
347+
# Assumes you set your environment variable:
348+
# https://github.com/sendgrid/sendgrid-python/blob/HEAD/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key
349+
message = build_multiple_emails_personalized()
350+
sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
351+
response = sendgrid_client.send(message=message)
352+
print(response.status_code)
353+
print(response.body)
354+
print(response.headers)
311355

312356
def send_hello_email():
313357
# Assumes you set your environment variable:
@@ -334,5 +378,8 @@ def send_kitchen_sink():
334378
## this will actually send an email
335379
# send_hello_email()
336380

381+
## this will send multiple emails
382+
# send_multiple_emails_personalized()
383+
337384
## this will only send an email if you set SandBox Mode to False
338385
# send_kitchen_sink()

sendgrid/helpers/mail/personalization.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Personalization(object):
66
def __init__(self):
77
"""Create an empty Personalization and initialize member variables."""
88
self._tos = []
9+
self._from_email = None
910
self._ccs = []
1011
self._bccs = []
1112
self._subject = None
@@ -26,7 +27,10 @@ def add_email(self, email):
2627
if email_type.__name__ == 'Bcc':
2728
self.add_bcc(email)
2829
return
29-
raise ValueError('Please use a To, Cc or Bcc object.')
30+
if email_type.__name__ == 'From':
31+
self.from_email = email
32+
return
33+
raise ValueError('Please use a To, From, Cc or Bcc object.')
3034

3135
def _get_unique_recipients(self, recipients):
3236
unique_recipients = []
@@ -77,6 +81,17 @@ def add_to(self, email):
7781

7882
self._tos.append(email.get())
7983

84+
@property
85+
def from_email(self):
86+
return self._from_email
87+
88+
@from_email.setter
89+
def from_email(self, value):
90+
self._from_email = value
91+
92+
def set_from(self, email):
93+
self._from_email = email.get()
94+
8095
@property
8196
def ccs(self):
8297
"""A list of recipients who will receive copies of this email.
@@ -236,6 +251,10 @@ def get(self):
236251
if value:
237252
personalization[key[:-1]] = value
238253

254+
from_value = getattr(self, 'from_email')
255+
if from_value:
256+
personalization['from'] = from_value
257+
239258
for key in ['subject', 'send_at', 'dynamic_template_data']:
240259
value = getattr(self, key)
241260
if value:

test/test_mail_helpers.py

+9
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,15 @@ def test_personalization_add_email_filters_out_duplicate_to_emails_ignoring_case
667667

668668
self.assertEqual([to_email.get()], p.tos)
669669

670+
def test_personalization_set_from_email(self):
671+
self.maxDiff = None
672+
673+
p = Personalization()
674+
from_email = From('[email protected]', 'Example From')
675+
p.set_from(from_email)
676+
677+
self.assertEqual(from_email.get(), p.from_email)
678+
670679
def test_personalization_filters_out_duplicate_cc_emails(self):
671680
self.maxDiff = None
672681

use_cases/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This directory provides examples for specific use cases of this library. Please
88
* [Send a Single Email to a Single Recipient](send_a_single_email_to_a_single_recipient.md)
99
* [Send a Single Email to Multiple Recipients](send_a_single_email_to_multiple_recipients.md)
1010
* [Send Multiple Emails to Multiple Recipients](send_multiple_emails_to_multiple_recipients.md)
11+
* [Send Multiple Emails with Personalizations](send_multiple_emails_personalizations.md)
1112
* [Kitchen Sink - an example with all settings used](kitchen_sink.md)
1213
* [Transactional Templates](transactional_templates.md)
1314
* [Attachments](attachment.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
```python
2+
import os
3+
import json
4+
from sendgrid import SendGridAPIClient
5+
from sendgrid.helpers.mail import Mail, Personalization, From, To, Cc, Bcc
6+
7+
# Note that the domain for all From email addresses must match
8+
message = Mail(
9+
from_email=('[email protected]', 'Example From Name'),
10+
subject='Sending with Twilio SendGrid is Fun',
11+
html_content='<strong>and easy to do anywhere, even with Python</strong>')
12+
13+
personalization1 = Personalization()
14+
personalization1.add_email(To('[email protected]', 'Example Name 0'))
15+
personalization1.add_email(Cc('[email protected]', 'Example Name 1'))
16+
message.add_personalization(personalization1)
17+
18+
personalization2 = Personalization()
19+
personalization2.add_email(To('[email protected]', 'Example Name 2'))
20+
personalization2.add_email(Bcc('[email protected]', 'Example Name 3'))
21+
personalization2.add_email(From('[email protected]', 'Example From Name 2'))
22+
message.add_personalization(personalization2)
23+
24+
try:
25+
sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
26+
response = sendgrid_client.send(message)
27+
print(response.status_code)
28+
print(response.body)
29+
print(response.headers)
30+
except Exception as e:
31+
print(e.message)
32+
```

0 commit comments

Comments
 (0)