-
Notifications
You must be signed in to change notification settings - Fork 714
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for dynamic template data to Email class (#908)
Fixes #899 This is helpful when sending multiple emails to multiple recipients. You can now include the dynamic template data with the recipient which will then be included in the personalization.
- Loading branch information
childish-sambino
authored
Jun 17, 2020
1 parent
cb58667
commit 3415520
Showing
6 changed files
with
148 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
html_entity_decode = __html_parser__.unescape | ||
|
||
try: | ||
basestring = basestring | ||
basestring = basestring | ||
except NameError: | ||
# Define basestring when Python >= 3.0 | ||
basestring = str | ||
|
@@ -32,7 +32,8 @@ def __init__(self, | |
name=None, | ||
substitutions=None, | ||
subject=None, | ||
p=0): | ||
p=0, | ||
dynamic_template_data=None): | ||
"""Create an Email with the given address and name. | ||
Either fill the separate name and email fields, or pass all information | ||
|
@@ -41,17 +42,19 @@ def __init__(self, | |
:type email: string, optional | ||
:param name: Name for this sender or recipient. | ||
:type name: string, optional | ||
:param substitutions: String substitutions to be applied to the email. | ||
:type substitutions: list(Substitution), optional | ||
:param subject: Subject for this sender or recipient. | ||
:type subject: string, optional | ||
:param p: p is the Personalization object or Personalization object | ||
index | ||
:type p: Personalization, integer, optional | ||
:param dynamic_template_data: Data for a dynamic transactional template. | ||
:type dynamic_template_data: DynamicTemplateData, optional | ||
""" | ||
self._name = None | ||
self._email = None | ||
self._substitutions = None | ||
self._subject = None | ||
self._personalization = None | ||
self._personalization = p | ||
|
||
if email and not name: | ||
# allows passing emails as "Example Name <[email protected]>" | ||
|
@@ -64,14 +67,11 @@ def __init__(self, | |
if name is not None: | ||
self.name = name | ||
|
||
if substitutions is not None: | ||
self.substitutions = substitutions | ||
|
||
if subject is not None: | ||
self.subject = subject | ||
|
||
if p is not None: | ||
self.personalization = p | ||
# Note that these only apply to To Emails (see Personalization.add_to) | ||
# and should be moved but have not been for compatibility. | ||
self._substitutions = substitutions | ||
self._dynamic_template_data = dynamic_template_data | ||
self._subject = subject | ||
|
||
@property | ||
def name(self): | ||
|
@@ -129,7 +129,7 @@ def email(self, value): | |
@property | ||
def substitutions(self): | ||
"""A list of Substitution objects. These substitutions will apply to | ||
the text and html content of the body of your email, in addition | ||
the text and html content of the body of your email, in addition | ||
to the subject and reply-to parameters. The total collective size | ||
of your substitutions may not exceed 10,000 bytes per | ||
personalization object. | ||
|
@@ -141,20 +141,37 @@ def substitutions(self): | |
@substitutions.setter | ||
def substitutions(self, value): | ||
"""A list of Substitution objects. These substitutions will apply to | ||
the text and html content of the body of your email, in addition to | ||
the text and html content of the body of your email, in addition to | ||
the subject and reply-to parameters. The total collective size of | ||
your substitutions may not exceed 10,000 bytes per personalization | ||
object. | ||
:param value: A list of Substitution objects. These substitutions will | ||
apply to the text and html content of the body of your email, in | ||
apply to the text and html content of the body of your email, in | ||
addition to the subject and reply-to parameters. The total collective | ||
size of your substitutions may not exceed 10,000 bytes per | ||
personalization object. | ||
:type value: list(Substitution) | ||
""" | ||
self._substitutions = value | ||
|
||
@property | ||
def dynamic_template_data(self): | ||
"""Data for a dynamic transactional template. | ||
:rtype: DynamicTemplateData | ||
""" | ||
return self._dynamic_template_data | ||
|
||
@dynamic_template_data.setter | ||
def dynamic_template_data(self, value): | ||
"""Data for a dynamic transactional template. | ||
:param value: DynamicTemplateData | ||
:type value: DynamicTemplateData | ||
""" | ||
self._dynamic_template_data = value | ||
|
||
@property | ||
def subject(self): | ||
"""Subject for this sender or recipient. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,12 +10,11 @@ | |
EmailMessage = message.Message | ||
|
||
from sendgrid.helpers.mail import ( | ||
Asm, ApiKeyIncludedException, Attachment, BccSettings, | ||
BypassListManagement, Category, ClickTracking, Content, CustomArg, | ||
DynamicTemplateData, Email, FooterSettings, From, Ganalytics, Header, | ||
Mail, MailSettings, OpenTracking, Personalization, SandBoxMode, Section, | ||
SendGridException, SpamCheck, Subject, SubscriptionTracking, Substitution, | ||
TrackingSettings, To, ValidateApiKey | ||
Asm, Attachment, | ||
ClickTracking, Content, | ||
DynamicTemplateData, Email, From, | ||
Mail, Personalization, | ||
Subject, Substitution, To, TrackingSettings | ||
) | ||
|
||
|
||
|
@@ -210,18 +209,18 @@ def test_multiple_emails_to_multiple_recipients(self): | |
|
||
to_emails = [ | ||
To(email='[email protected]', | ||
name='Example Name 0', | ||
substitutions=[ | ||
Substitution('-name-', 'Example Name Substitution 0'), | ||
Substitution('-github-', 'https://example.com/test0'), | ||
], | ||
subject=Subject('Override Global Subject')), | ||
name='Example Name 0', | ||
substitutions=[ | ||
Substitution('-name-', 'Example Name Substitution 0'), | ||
Substitution('-github-', 'https://example.com/test0'), | ||
], | ||
subject=Subject('Override Global Subject')), | ||
To(email='[email protected]', | ||
name='Example Name 1', | ||
substitutions=[ | ||
Substitution('-name-', 'Example Name Substitution 1'), | ||
Substitution('-github-', 'https://example.com/test1'), | ||
]) | ||
name='Example Name 1', | ||
substitutions=[ | ||
Substitution('-name-', 'Example Name Substitution 1'), | ||
Substitution('-github-', 'https://example.com/test1'), | ||
]) | ||
] | ||
global_substitutions = Substitution('-time-', '2019-01-01 00:00:00') | ||
message = Mail( | ||
|
@@ -285,6 +284,70 @@ def test_multiple_emails_to_multiple_recipients(self): | |
}''') | ||
) | ||
|
||
def test_dynamic_template_data(self): | ||
self.maxDiff = None | ||
|
||
to_emails = [ | ||
To(email='[email protected]', | ||
name='Example To 0 Name', | ||
dynamic_template_data=DynamicTemplateData({'name': 'Example 0 Name'})), | ||
To(email='[email protected]', | ||
name='Example To 1 Name', | ||
dynamic_template_data={'name': 'Example 1 Name'}) | ||
] | ||
message = Mail( | ||
from_email=From('[email protected]', 'Example From Name'), | ||
to_emails=to_emails, | ||
subject=Subject('Hi!'), | ||
plain_text_content='Hello!', | ||
html_content='<strong>Hello!</strong>', | ||
is_multiple=True) | ||
|
||
self.assertEqual( | ||
message.get(), | ||
json.loads(r'''{ | ||
"content": [ | ||
{ | ||
"type": "text/plain", | ||
"value": "Hello!" | ||
}, | ||
{ | ||
"type": "text/html", | ||
"value": "<strong>Hello!</strong>" | ||
} | ||
], | ||
"from": { | ||
"email": "[email protected]", | ||
"name": "Example From Name" | ||
}, | ||
"personalizations": [ | ||
{ | ||
"dynamic_template_data": { | ||
"name": "Example 1 Name" | ||
}, | ||
"to": [ | ||
{ | ||
"email": "[email protected]", | ||
"name": "Example To 1 Name" | ||
} | ||
] | ||
}, | ||
{ | ||
"dynamic_template_data": { | ||
"name": "Example 0 Name" | ||
}, | ||
"to": [ | ||
{ | ||
"email": "[email protected]", | ||
"name": "Example To 0 Name" | ||
} | ||
] | ||
} | ||
], | ||
"subject": "Hi!" | ||
}''') | ||
) | ||
|
||
def test_kitchen_sink(self): | ||
from sendgrid.helpers.mail import ( | ||
Mail, From, To, Cc, Bcc, Subject, Substitution, Header, | ||
|
Oops, something went wrong.