diff --git a/examples/helpers/mail/mail_example.py b/examples/helpers/mail/mail_example.py index b2de7f0a0..42a50b028 100644 --- a/examples/helpers/mail/mail_example.py +++ b/examples/helpers/mail/mail_example.py @@ -212,6 +212,34 @@ def send_kitchen_sink(): print(response.body) +def dynamic_template_usage(): + """ + Sample usage of dynamic (handlebars) transactional templates. + To make this work, you should have dynamic template created within your + SendGrid account. + In this example the template may look like: +
Hello {{name}}! Here is {{foo}} and also {{extra}}!
+ """ + sg = SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) + from_email = Email("test@example.com") + subject = "I'm replacing the subject tag" + to_email = Email("test@example.com") + content = Content("text/html", "I'm replacing the body tag") + mail = Mail(from_email, subject, to_email, content) + + p = Personalization() + p.add_dynamic_template_data(DynamicTemplateTag("name", "Example User")) + p.add_dynamic_template_data(DynamicTemplateTag("foo", "bar")) + p.add_dynamic_template_data(DynamicTemplateTag("extra", "SG rocks!")) + mail.template_id = "13b8f94f-bcae-4ec6-b752-70d6cb59f932" + mail.add_personalization(p) + + response = sg.client.mail.send.post(request_body=mail.get()) + print(response.status_code) + print(response.body) + print(response.headers) + + # this will actually send an email send_hello_email() diff --git a/sendgrid/helpers/mail/__init__.py b/sendgrid/helpers/mail/__init__.py index 1dd769e99..2b6fdc650 100644 --- a/sendgrid/helpers/mail/__init__.py +++ b/sendgrid/helpers/mail/__init__.py @@ -22,3 +22,4 @@ from .substitution import Substitution from .tracking_settings import TrackingSettings from .validators import ValidateAPIKey +from .dynamic_template_tag import DynamicTemplateTag diff --git a/sendgrid/helpers/mail/dynamic_template_tag.py b/sendgrid/helpers/mail/dynamic_template_tag.py new file mode 100644 index 000000000..fad5baf52 --- /dev/null +++ b/sendgrid/helpers/mail/dynamic_template_tag.py @@ -0,0 +1,43 @@ +class DynamicTemplateTag(object): + """A dynamic template tag can be used to be applied to the text and HTML contents of + the body of your email, as well as in the Subject and Reply-To parameters. + """ + + def __init__(self, key=None, value=None): + """Create a DynamicTemplateTag with the given key and value. + + :param key: Text to be replaced with "value" param + :type key: string, optional + :param value: Value to substitute into email, can be any JSON serializable object + :type value: any + """ + self._key = key + self._value = value + + @property + def key(self): + return self._key + + @key.setter + def key(self, value): + self._key = value + + @property + def value(self): + return self._value + + @value.setter + def value(self, value): + self._value = value + + def get(self): + """ + Get a JSON-ready representation of this Substitution. + + :returns: This DynamicTemplateTag, ready for use in a request body. + :rtype: dict + """ + dynamic_template_tag = dict() + if self.key is not None and self.value is not None: + dynamic_template_tag[self.key] = self.value + return dynamic_template_tag diff --git a/sendgrid/helpers/mail/personalization.py b/sendgrid/helpers/mail/personalization.py index 8bb4bed0b..caea36da7 100644 --- a/sendgrid/helpers/mail/personalization.py +++ b/sendgrid/helpers/mail/personalization.py @@ -1,3 +1,5 @@ +from copy import deepcopy + class Personalization(object): """A Personalization defines who should receive an individual message and how that message should be handled. @@ -13,6 +15,7 @@ def __init__(self): self._substitutions = [] self._custom_args = [] self._send_at = None + self._dynamic_template_data = dict() @property def tos(self): @@ -158,6 +161,25 @@ def send_at(self): def send_at(self, value): self._send_at = value + @property + def dynamic_template_data(self): + """The DynamicTemplateData that will be carried along with this Personalization. + + :rtype: dict + """ + return self._dynamic_template_data + + @dynamic_template_data.setter + def dynamic_template_data(self, value): + self._dynamic_template_data = value + + def add_dynamic_template_data(self, dynamic_template_data): + """Append item to DynamicTemplateData + + :type dynamic_template_data: DynamicTemplateTag + """ + self._dynamic_template_data.update(dynamic_template_data.get()) + def get(self): """ Get a JSON-ready representation of this Personalization. @@ -198,4 +220,8 @@ def get(self): if self.send_at is not None: personalization["send_at"] = self.send_at + + if self.dynamic_template_data: + personalization['dynamic_template_data'] = deepcopy(self.dynamic_template_data) + return personalization diff --git a/test/test_mail.py b/test/test_mail.py index 7721b5205..1c18306ee 100644 --- a/test/test_mail.py +++ b/test/test_mail.py @@ -26,8 +26,8 @@ SubscriptionTracking, Substitution, TrackingSettings, - ValidateAPIKey -) + ValidateAPIKey, + DynamicTemplateTag) try: import unittest2 as unittest @@ -73,7 +73,7 @@ def test_sendgridAPIKey(self): ) #Exception should be thrown - except Exception as e: + except Exception: pass #Exception not thrown @@ -562,3 +562,45 @@ def test_disable_tracking(self): def test_directly_setting_substitutions(self): personalization = Personalization() personalization.substitutions = [{'a': 0}] + + def test_dynamic_template_data(self): + """Test for minimum requirements, redundancy and nested items""" + mail = Mail() + + mail.from_email = Email("test@example.com") + + mail.subject = "Hello World from the SendGrid Python Library" + + personalization = Personalization() + personalization.add_to(Email("test@example.com")) + personalization.add_dynamic_template_data(DynamicTemplateTag('foo', 'bar')) + personalization.add_dynamic_template_data(DynamicTemplateTag('one', 'more')) + personalization.add_dynamic_template_data(DynamicTemplateTag('foo', 'bar1')) + personalization.add_dynamic_template_data(DynamicTemplateTag('items', [{"total": "100"}, {"more": "things"}])) + mail.add_personalization(personalization) + + mail.add_content(Content("text/plain", "some text here")) + mail.add_content( + Content( + "text/html", + "
some text here")) + + self.assertEqual( + json.dumps( + mail.get(), + sort_keys=True), + '{"content": [{"type": "text/plain", "value": "some text here"}, ' + '{"type": "text/html", ' + '"value": "some text here"}], ' + '"from": {"email": "test@example.com"}, ' + '"personalizations": [{' + '"dynamic_template_data": {"foo": "bar1", "items": [{"total": "100"}, {"more": "things"}], "one": "more"}, ' + '"to": [{"email": "test@example.com"}]' + '}], ' + '"subject": "Hello World from the SendGrid Python Library"' + '}' + ) + + self.assertTrue(isinstance(str(mail), str)) + + diff --git a/use_cases/README.md b/use_cases/README.md index ea8156533..a54d92749 100644 --- a/use_cases/README.md +++ b/use_cases/README.md @@ -16,6 +16,7 @@ This directory provides examples for specific use cases of this library. Please * [Attachment](attachment.md) * [Transactional Templates](transational_templates.md) * [Integrate with Slack Events API](slack_event_api_integration.md) +* [Dynamic Transactional Templates](dynamic_transactional_templates.md) ### Library Features * [Error Handling](error_handling.md) \ No newline at end of file diff --git a/use_cases/dynamic_transactional_templates.md b/use_cases/dynamic_transactional_templates.md new file mode 100644 index 000000000..e8bf8329d --- /dev/null +++ b/use_cases/dynamic_transactional_templates.md @@ -0,0 +1,133 @@ +# Dynamic Transactional Templates + +For this example, we assume you have created a [dynamic transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/Create_and_edit_dynamic_transactional_templates.html). Following is the template content we used for testing. + +Template ID (replace with your own): + +```text +13b8f94f-bcae-4ec6-b752-70d6cb59f932 +``` + +Email Subject: + +```text +{{subject}} +``` + +Template Body: + +```html + + ++
+ Values provided+ |
+ |
{{@key}} |
+ {{this}} |
+