Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow personalization of the From name and email for each recipient #1020

Merged
merged 2 commits into from
Oct 25, 2021
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
12 changes: 8 additions & 4 deletions examples/helpers/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ For more information on parameters and usage, see [here](../mail/mail.py)

### Creating Personalizations

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)
After creating a dictionary, you can go ahead and create a `Personalization` object.
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.
```
mock_personalization = Personalization()
for to_addr in personalization['to_list']:
mock_personalization.add_to(to_addr)

for to_addr in personalization['to_list']:
mock_personalization.add_to(to_addr)

mock_personalization.set_from(from_addr)
mock_personalization.add_cc(cc_addr)
# etc...
```

### Creating Attachments
Expand Down
65 changes: 56 additions & 9 deletions examples/helpers/mail_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def build_hello_email():
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, From, To, Subject, PlainTextContent, HtmlContent, SendGridException

message = Mail(from_email=From('[email protected].com', 'Example From Name'),
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'),
Expand All @@ -26,25 +26,30 @@ def build_hello_email():
except SendGridException as e:
print(e.message)

for cc_addr in personalization['cc_list']:
mock_personalization = Personalization()
personalization_dict = get_mock_personalization_dict()

for cc_addr in personalization_dict['cc_list']:
mock_personalization.add_to(cc_addr)

for bcc_addr in personalization['bcc_list']:
for bcc_addr in personalization_dict['bcc_list']:
mock_personalization.add_bcc(bcc_addr)

for header in personalization['headers']:
for header in personalization_dict['headers']:
mock_personalization.add_header(header)

for substitution in personalization['substitutions']:
for substitution in personalization_dict['substitutions']:
mock_personalization.add_substitution(substitution)

for arg in personalization['custom_args']:
for arg in personalization_dict['custom_args']:
mock_personalization.add_custom_arg(arg)

mock_personalization.subject = personalization['subject']
mock_personalization.send_at = personalization['send_at']
return mock_personalization
mock_personalization.subject = personalization_dict['subject']
mock_personalization.send_at = personalization_dict['send_at']

message.add_personalization(mock_personalization)

return message

def get_mock_personalization_dict():
"""Get a dict of personalization mock."""
Expand Down Expand Up @@ -78,6 +83,36 @@ def get_mock_personalization_dict():
mock_pers['send_at'] = 1443636843
return mock_pers

def build_multiple_emails_personalized():
import json
from sendgrid.helpers.mail import Mail, From, To, Cc, Bcc, Subject, PlainTextContent, \
HtmlContent, SendGridException, Personalization

# Note that the domain for all From email addresses must match
message = Mail(from_email=From('[email protected]', 'Example From 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>'))

mock_personalization = Personalization()
mock_personalization.add_to(To('[email protected]', 'Example User 1'))
mock_personalization.add_cc(Cc('[email protected]', 'Example User 2'))
message.add_personalization(mock_personalization)

mock_personalization_2 = Personalization()
mock_personalization_2.add_to(To('[email protected]', 'Example User 3'))
mock_personalization_2.set_from(From('[email protected]', 'Example From Name 2'))
mock_personalization_2.add_bcc(Bcc('[email protected]', 'Example User 4'))
message.add_personalization(mock_personalization_2)

try:
print(json.dumps(message.get(), sort_keys=True, indent=4))
return message.get()

except SendGridException as e:
print(e.message)

return message

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

return message

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

def send_hello_email():
# Assumes you set your environment variable:
Expand All @@ -334,5 +378,8 @@ def send_kitchen_sink():
## this will actually send an email
# send_hello_email()

## this will send multiple emails
# send_multiple_emails_personalized()

## this will only send an email if you set SandBox Mode to False
# send_kitchen_sink()
21 changes: 20 additions & 1 deletion sendgrid/helpers/mail/personalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Personalization(object):
def __init__(self):
"""Create an empty Personalization and initialize member variables."""
self._tos = []
self._from_email = None
shwetha-manvinkurke marked this conversation as resolved.
Show resolved Hide resolved
self._ccs = []
self._bccs = []
self._subject = None
Expand All @@ -26,7 +27,10 @@ def add_email(self, email):
if email_type.__name__ == 'Bcc':
self.add_bcc(email)
return
raise ValueError('Please use a To, Cc or Bcc object.')
if email_type.__name__ == 'From':
self.from_email = email
return
raise ValueError('Please use a To, From, Cc or Bcc object.')

def _get_unique_recipients(self, recipients):
unique_recipients = []
Expand Down Expand Up @@ -77,6 +81,17 @@ def add_to(self, email):

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

@property
def from_email(self):
return self._from_email

@from_email.setter
def from_email(self, value):
self._from_email = value

def set_from(self, email):
self._from_email = email.get()

@property
def ccs(self):
"""A list of recipients who will receive copies of this email.
Expand Down Expand Up @@ -236,6 +251,10 @@ def get(self):
if value:
personalization[key[:-1]] = value

from_value = getattr(self, 'from_email')
if from_value:
personalization['from'] = from_value

for key in ['subject', 'send_at', 'dynamic_template_data']:
value = getattr(self, key)
if value:
Expand Down
9 changes: 9 additions & 0 deletions test/test_mail_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,15 @@ def test_personalization_add_email_filters_out_duplicate_to_emails_ignoring_case

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

def test_personalization_set_from_email(self):
self.maxDiff = None

p = Personalization()
from_email = From('[email protected]', 'Example From')
p.set_from(from_email)

self.assertEqual(from_email.get(), p.from_email)

def test_personalization_filters_out_duplicate_cc_emails(self):
self.maxDiff = None

Expand Down
1 change: 1 addition & 0 deletions use_cases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This directory provides examples for specific use cases of this library. Please
* [Send a Single Email to a Single Recipient](send_a_single_email_to_a_single_recipient.md)
* [Send a Single Email to Multiple Recipients](send_a_single_email_to_multiple_recipients.md)
* [Send Multiple Emails to Multiple Recipients](send_multiple_emails_to_multiple_recipients.md)
* [Send Multiple Emails with Personalizations](send_multiple_emails_personalizations.md)
* [Kitchen Sink - an example with all settings used](kitchen_sink.md)
* [Transactional Templates](transactional_templates.md)
* [Attachments](attachment.md)
Expand Down
32 changes: 32 additions & 0 deletions use_cases/send_multiple_emails_personalizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
```python
import os
import json
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail, Personalization, From, To, Cc, Bcc

# Note that the domain for all From email addresses must match
message = Mail(
from_email=('[email protected]', 'Example From Name'),
subject='Sending with Twilio SendGrid is Fun',
html_content='<strong>and easy to do anywhere, even with Python</strong>')

personalization1 = Personalization()
personalization1.add_email(To('[email protected]', 'Example Name 0'))
personalization1.add_email(Cc('[email protected]', 'Example Name 1'))
message.add_personalization(personalization1)

personalization2 = Personalization()
personalization2.add_email(To('[email protected]', 'Example Name 2'))
personalization2.add_email(Bcc('[email protected]', 'Example Name 3'))
personalization2.add_email(From('[email protected]', 'Example From Name 2'))
message.add_personalization(personalization2)

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.message)
```