def _prepare_sendgrid_data(self): self.ensure_one() s_mail = Mail() s_mail.set_from(Email(self.email_from)) if self.reply_to: s_mail.set_reply_to(Email(self.reply_to)) s_mail.add_custom_arg(CustomArg('odoo_id', self.message_id)) html = self.body_html or ' ' p = re.compile(r'<.*?>') # Remove HTML markers text_only = self.body_text or p.sub('', html.replace('<br/>', '\n')) s_mail.add_content(Content("text/plain", text_only)) s_mail.add_content(Content("text/html", html)) test_address = config.get('sendgrid_test_address') # We use only one personalization for transactional e-mail personalization = Personalization() personalization.set_subject(self.subject or ' ') addresses = list() if not test_address: if self.email_to and self.email_to not in addresses: personalization.add_to(Email(self.email_to)) addresses.append(self.email_to) for recipient in self.recipient_ids: if recipient.email not in addresses: personalization.add_to(Email(recipient.email)) addresses.append(recipient.email) if self.email_cc and self.email_cc not in addresses: personalization.add_cc(Email(self.email_cc)) else: _logger.info('Sending email to test address {}'.format( test_address)) personalization.add_to(Email(test_address)) self.email_to = test_address if self.sendgrid_template_id: s_mail.set_template_id(self.sendgrid_template_id.remote_id) for substitution in self.substitution_ids: personalization.add_substitution(Substitution( substitution.key, substitution.value)) s_mail.add_personalization(personalization) for attachment in self.attachment_ids: s_attachment = Attachment() # Datas are not encoded properly for sendgrid s_attachment.set_content(base64.b64encode(base64.b64decode( attachment.datas))) s_attachment.set_filename(attachment.name) s_mail.add_attachment(s_attachment) return s_mail.get()
def _prepare_sendgrid_data(self): self.ensure_one() s_mail = Mail() s_mail.set_from(Email(self.email_from)) s_mail.set_reply_to(Email(self.reply_to)) s_mail.add_custom_arg(CustomArg('odoo_id', self.message_id)) html = self.body_html or ' ' p = re.compile(r'<.*?>') # Remove HTML markers text_only = self.body_text or p.sub('', html.replace('<br/>', '\n')) s_mail.add_content(Content("text/plain", text_only)) s_mail.add_content(Content("text/html", html)) test_address = config.get('sendgrid_test_address') # TODO For now only one personalization (transactional e-mail) personalization = Personalization() personalization.set_subject(self.subject or ' ') if not test_address: if self.email_to: personalization.add_to(Email(self.email_to)) for recipient in self.recipient_ids: personalization.add_to(Email(recipient.email)) if self.email_cc: personalization.add_cc(Email(self.email_cc)) else: _logger.info('Sending email to test address {}'.format( test_address)) personalization.add_to(Email(test_address)) self.email_to = test_address if self.sendgrid_template_id: s_mail.set_template_id(self.sendgrid_template_id.remote_id) for substitution in self.substitution_ids: personalization.add_substitution(Substitution( substitution.key, substitution.value)) s_mail.add_personalization(personalization) for attachment in self.attachment_ids: s_attachment = Attachment() # Datas are not encoded properly for sendgrid s_attachment.set_content(base64.b64encode(base64.b64decode( attachment.datas))) s_attachment.set_filename(attachment.name) s_mail.add_attachment(s_attachment) return s_mail.get()
def _prepare_sendgrid_data(self): """ Prepare and creates the Sendgrid Email object :return: sendgrid.helpers.mail.Email object """ self.ensure_one() s_mail = Mail() s_mail.from_email = Email(self.email_from) if self.reply_to: s_mail.reply_to = Email(self.reply_to) # Add custom fields to match the tracking s_mail.add_custom_arg(CustomArg('odoo_id', self.message_id)) s_mail.add_custom_arg(CustomArg('odoo_db', self.env.cr.dbname)) headers = {'Message-Id': self.message_id} if self.headers: try: headers.update(safe_eval(self.headers)) except Exception: pass for h_name, h_val in headers.iteritems(): s_mail.add_header(Header(h_name, h_val)) html = self.body_html or ' ' p = re.compile(r'<.*?>') # Remove HTML markers text_only = self.body_text or p.sub('', html.replace('<br/>', '\n')) s_mail.add_content(Content("text/plain", text_only or ' ')) s_mail.add_content(Content("text/html", html)) test_address = config.get('sendgrid_test_address') # We use only one personalization for transactional e-mail personalization = Personalization() subject = self.subject and self.subject.encode( "utf_8") or "(No subject)" personalization.subject = subject addresses = set() if not test_address: if self.email_to: addresses = set(self.email_to.split(',')) for address in addresses: personalization.add_to(Email(address)) for recipient in self.recipient_ids: if recipient.email not in addresses: personalization.add_to(Email(recipient.email)) addresses.add(recipient.email) if self.email_cc and self.email_cc not in addresses: personalization.add_cc(Email(self.email_cc)) else: _logger.info( 'Sending email to test address {}'.format(test_address)) personalization.add_to(Email(test_address)) self.email_to = test_address if self.sendgrid_template_id: s_mail.template_id = self.sendgrid_template_id.remote_id for substitution in self.substitution_ids: personalization.add_substitution( Substitution(substitution.key, substitution.value.encode('utf-8'))) s_mail.add_personalization(personalization) for attachment in self.attachment_ids: s_attachment = Attachment() # Datas are not encoded properly for sendgrid s_attachment.content = base64.b64encode( base64.b64decode(attachment.datas)) s_attachment.filename = attachment.name s_mail.add_attachment(s_attachment) return s_mail
def test_kitchenSink(self): self.maxDiff = None """All settings set""" mail = Mail() mail.from_email = Email("*****@*****.**", "Example User") mail.subject = "Hello World from the SendGrid Python Library" personalization = Personalization() personalization.add_to(Email("*****@*****.**", "Example User")) personalization.add_to(Email("*****@*****.**", "Example User")) personalization.add_cc(Email("*****@*****.**", "Example User")) personalization.add_cc(Email("*****@*****.**", "Example User")) personalization.add_bcc(Email("*****@*****.**")) personalization.add_bcc(Email("*****@*****.**")) personalization.subject = "Hello World from the Personalized SendGrid Python Library" personalization.add_header(Header("X-Test", "test")) personalization.add_header(Header("X-Mock", "true")) personalization.add_substitution(Substitution("%name%", "Example User")) personalization.add_substitution(Substitution("%city%", "Denver")) personalization.add_custom_arg(CustomArg("user_id", "343")) personalization.add_custom_arg(CustomArg("type", "marketing")) personalization.send_at = 1443636843 mail.add_personalization(personalization) personalization2 = Personalization() personalization2.add_to(Email("*****@*****.**", "Example User")) personalization2.add_to(Email("*****@*****.**", "Example User")) personalization2.add_cc(Email("*****@*****.**", "Example User")) personalization2.add_cc(Email("*****@*****.**", "Example User")) personalization2.add_bcc(Email("*****@*****.**")) personalization2.add_bcc(Email("*****@*****.**")) personalization2.subject = "Hello World from the Personalized SendGrid Python Library" personalization2.add_header(Header("X-Test", "test")) personalization2.add_header(Header("X-Mock", "true")) personalization2.add_substitution( Substitution("%name%", "Example User")) personalization2.add_substitution(Substitution("%city%", "Denver")) personalization2.add_custom_arg(CustomArg("user_id", "343")) personalization2.add_custom_arg(CustomArg("type", "marketing")) personalization2.send_at = 1443636843 mail.add_personalization(personalization2) mail.add_content(Content("text/plain", "some text here")) mail.add_content( Content("text/html", "<html><body>some text here</body></html>")) attachment = Attachment() attachment.content = "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12" attachment.type = "application/pdf" attachment.filename = "balance_001.pdf" attachment.disposition = "attachment" attachment.content_id = "Balance Sheet" mail.add_attachment(attachment) attachment2 = Attachment() attachment2.content = "BwdW" attachment2.type = "image/png" attachment2.filename = "banner.png" attachment2.disposition = "inline" attachment2.content_id = "Banner" mail.add_attachment(attachment2) mail.template_id = "13b8f94f-bcae-4ec6-b752-70d6cb59f932" mail.add_section( Section("%section1%", "Substitution Text for Section 1")) mail.add_section( Section("%section2%", "Substitution Text for Section 2")) mail.add_header(Header("X-Test1", "test1")) mail.add_header(Header("X-Test3", "test2")) mail.add_header({"X-Test4": "test4"}) mail.add_category(Category("May")) mail.add_category(Category("2016")) mail.add_custom_arg(CustomArg("campaign", "welcome")) mail.add_custom_arg(CustomArg("weekday", "morning")) mail.send_at = 1443636842 mail.batch_id = "sendgrid_batch_id" mail.asm = ASM(99, [4, 5, 6, 7, 8]) mail.ip_pool_name = "24" mail_settings = MailSettings() mail_settings.bcc_settings = BCCSettings(True, Email("*****@*****.**")) mail_settings.bypass_list_management = BypassListManagement(True) mail_settings.footer_settings = FooterSettings( True, "Footer Text", "<html><body>Footer Text</body></html>") mail_settings.sandbox_mode = SandBoxMode(True) mail_settings.spam_check = SpamCheck( True, 1, "https://spamcatcher.sendgrid.com") mail.mail_settings = mail_settings tracking_settings = TrackingSettings() tracking_settings.click_tracking = ClickTracking(True, True) tracking_settings.open_tracking = OpenTracking( True, "Optional tag to replace with the open image in the body of the message" ) tracking_settings.subscription_tracking = SubscriptionTracking( True, "text to insert into the text/plain portion of the message", "<html><body>html to insert into the text/html portion of the message</body></html>", "Optional tag to replace with the open image in the body of the message" ) tracking_settings.ganalytics = Ganalytics(True, "some source", "some medium", "some term", "some content", "some campaign") mail.tracking_settings = tracking_settings mail.reply_to = Email("*****@*****.**") expected_result = { "asm": { "group_id": 99, "groups_to_display": [4, 5, 6, 7, 8] }, "attachments": [{ "content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3" "RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12", "content_id": "Balance Sheet", "disposition": "attachment", "filename": "balance_001.pdf", "type": "application/pdf" }, { "content": "BwdW", "content_id": "Banner", "disposition": "inline", "filename": "banner.png", "type": "image/png" }], "batch_id": "sendgrid_batch_id", "categories": ["May", "2016"], "content": [{ "type": "text/plain", "value": "some text here" }, { "type": "text/html", "value": "<html><body>some text here</body></html>" }], "custom_args": { "campaign": "welcome", "weekday": "morning" }, "from": { "email": "*****@*****.**", "name": "Example User" }, "headers": { "X-Test1": "test1", "X-Test3": "test2", "X-Test4": "test4" }, "ip_pool_name": "24", "mail_settings": { "bcc": { "email": "*****@*****.**", "enable": True }, "bypass_list_management": { "enable": True }, "footer": { "enable": True, "html": "<html><body>Footer Text</body></html>", "text": "Footer Text" }, "sandbox_mode": { "enable": True }, "spam_check": { "enable": True, "post_to_url": "https://spamcatcher.sendgrid.com", "threshold": 1 } }, "personalizations": [{ "bcc": [{ "email": "*****@*****.**" }, { "email": "*****@*****.**" }], "cc": [{ "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" }], "custom_args": { "type": "marketing", "user_id": "343" }, "headers": { "X-Mock": "true", "X-Test": "test" }, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid " "Python Library", "substitutions": { "%city%": "Denver", "%name%": "Example User" }, "to": [{ "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" }] }, { "bcc": [{ "email": "*****@*****.**" }, { "email": "*****@*****.**" }], "cc": [{ "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" }], "custom_args": { "type": "marketing", "user_id": "343" }, "headers": { "X-Mock": "true", "X-Test": "test" }, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid " "Python Library", "substitutions": { "%city%": "Denver", "%name%": "Example User" }, "to": [{ "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" }] }], "reply_to": { "email": "*****@*****.**" }, "sections": { "%section1%": "Substitution Text for Section 1", "%section2%": "Substitution Text for Section 2" }, "send_at": 1443636842, "subject": "Hello World from the SendGrid Python Library", "template_id": "13b8f94f-bcae-4ec6-b752-70d6cb59f932", "tracking_settings": { "click_tracking": { "enable": True, "enable_text": True }, "ganalytics": { "enable": True, "utm_campaign": "some campaign", "utm_content": "some content", "utm_medium": "some medium", "utm_source": "some source", "utm_term": "some term" }, "open_tracking": { "enable": True, "substitution_tag": "Optional tag to replace with the " "open image in the body of the message" }, "subscription_tracking": { "enable": True, "html": "<html><body>html to insert into the text/html " "portion of the message</body></html>", "substitution_tag": "Optional tag to replace with the open" " image in the body of the message", "text": "text to insert into the text/plain portion of" " the message" } } } self.assertEqual(json.dumps(mail.get(), sort_keys=True), json.dumps(expected_result, sort_keys=True))
def test_kitchenSink(self): self.maxDiff = None """All settings set""" mail = Mail() mail.from_email = Email("*****@*****.**", "Example User") mail.subject = "Hello World from the SendGrid Python Library" personalization = Personalization() personalization.add_to(Email("*****@*****.**", "Example User")) personalization.add_to(Email("*****@*****.**", "Example User")) personalization.add_cc(Email("*****@*****.**", "Example User")) personalization.add_cc(Email("*****@*****.**", "Example User")) personalization.add_bcc(Email("*****@*****.**")) personalization.add_bcc(Email("*****@*****.**")) personalization.subject = "Hello World from the Personalized SendGrid Python Library" personalization.add_header(Header("X-Test", "test")) personalization.add_header(Header("X-Mock", "true")) personalization.add_substitution( Substitution("%name%", "Example User")) personalization.add_substitution(Substitution("%city%", "Denver")) personalization.add_custom_arg(CustomArg("user_id", "343")) personalization.add_custom_arg(CustomArg("type", "marketing")) personalization.send_at = 1443636843 mail.add_personalization(personalization) personalization2 = Personalization() personalization2.add_to(Email("*****@*****.**", "Example User")) personalization2.add_to(Email("*****@*****.**", "Example User")) personalization2.add_cc(Email("*****@*****.**", "Example User")) personalization2.add_cc(Email("*****@*****.**", "Example User")) personalization2.add_bcc(Email("*****@*****.**")) personalization2.add_bcc(Email("*****@*****.**")) personalization2.subject = "Hello World from the Personalized SendGrid Python Library" personalization2.add_header(Header("X-Test", "test")) personalization2.add_header(Header("X-Mock", "true")) personalization2.add_substitution( Substitution("%name%", "Example User")) personalization2.add_substitution(Substitution("%city%", "Denver")) personalization2.add_custom_arg(CustomArg("user_id", "343")) personalization2.add_custom_arg(CustomArg("type", "marketing")) personalization2.send_at = 1443636843 mail.add_personalization(personalization2) mail.add_content(Content("text/plain", "some text here")) mail.add_content( Content( "text/html", "<html><body>some text here</body></html>")) attachment = Attachment() attachment.content = "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12" attachment.type = "application/pdf" attachment.filename = "balance_001.pdf" attachment.disposition = "attachment" attachment.content_id = "Balance Sheet" mail.add_attachment(attachment) attachment2 = Attachment() attachment2.content = "BwdW" attachment2.type = "image/png" attachment2.filename = "banner.png" attachment2.disposition = "inline" attachment2.content_id = "Banner" mail.add_attachment(attachment2) mail.template_id = "13b8f94f-bcae-4ec6-b752-70d6cb59f932" mail.add_section( Section( "%section1%", "Substitution Text for Section 1")) mail.add_section( Section( "%section2%", "Substitution Text for Section 2")) mail.add_header(Header("X-Test1", "test1")) mail.add_header(Header("X-Test3", "test2")) mail.add_header({"X-Test4": "test4"}) mail.add_category(Category("May")) mail.add_category(Category("2016")) mail.add_custom_arg(CustomArg("campaign", "welcome")) mail.add_custom_arg(CustomArg("weekday", "morning")) mail.send_at = 1443636842 mail.batch_id = "sendgrid_batch_id" mail.asm = ASM(99, [4, 5, 6, 7, 8]) mail.ip_pool_name = "24" mail_settings = MailSettings() mail_settings.bcc_settings = BCCSettings( True, Email("*****@*****.**")) mail_settings.bypass_list_management = BypassListManagement(True) mail_settings.footer_settings = FooterSettings( True, "Footer Text", "<html><body>Footer Text</body></html>") mail_settings.sandbox_mode = SandBoxMode(True) mail_settings.spam_check = SpamCheck( True, 1, "https://spamcatcher.sendgrid.com") mail.mail_settings = mail_settings tracking_settings = TrackingSettings() tracking_settings.click_tracking = ClickTracking( True, True) tracking_settings.open_tracking = OpenTracking( True, "Optional tag to replace with the open image in the body of the message") tracking_settings.subscription_tracking = SubscriptionTracking( True, "text to insert into the text/plain portion of the message", "<html><body>html to insert into the text/html portion of the message</body></html>", "Optional tag to replace with the open image in the body of the message") tracking_settings.ganalytics = Ganalytics( True, "some source", "some medium", "some term", "some content", "some campaign") mail.tracking_settings = tracking_settings mail.reply_to = Email("*****@*****.**") expected_result = { "asm": { "group_id": 99, "groups_to_display": [4, 5, 6, 7, 8] }, "attachments": [ { "content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3" "RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12", "content_id": "Balance Sheet", "disposition": "attachment", "filename": "balance_001.pdf", "type": "application/pdf" }, { "content": "BwdW", "content_id": "Banner", "disposition": "inline", "filename": "banner.png", "type": "image/png" } ], "batch_id": "sendgrid_batch_id", "categories": [ "May", "2016" ], "content": [ { "type": "text/plain", "value": "some text here" }, { "type": "text/html", "value": "<html><body>some text here</body></html>" } ], "custom_args": { "campaign": "welcome", "weekday": "morning" }, "from": { "email": "*****@*****.**", "name": "Example User" }, "headers": { "X-Test1": "test1", "X-Test3": "test2", "X-Test4": "test4" }, "ip_pool_name": "24", "mail_settings": { "bcc": { "email": "*****@*****.**", "enable": True }, "bypass_list_management": { "enable": True }, "footer": { "enable": True, "html": "<html><body>Footer Text</body></html>", "text": "Footer Text" }, "sandbox_mode": { "enable": True }, "spam_check": { "enable": True, "post_to_url": "https://spamcatcher.sendgrid.com", "threshold": 1 } }, "personalizations": [ { "bcc": [ { "email": "*****@*****.**" }, { "email": "*****@*****.**" } ], "cc": [ { "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" } ], "custom_args": { "type": "marketing", "user_id": "343" }, "headers": { "X-Mock": "true", "X-Test": "test" }, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid " "Python Library", "substitutions": { "%city%": "Denver", "%name%": "Example User" }, "to": [ { "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" } ] }, { "bcc": [ { "email": "*****@*****.**" }, { "email": "*****@*****.**" } ], "cc": [ { "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" } ], "custom_args": { "type": "marketing", "user_id": "343" }, "headers": { "X-Mock": "true", "X-Test": "test" }, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid " "Python Library", "substitutions": { "%city%": "Denver", "%name%": "Example User" }, "to": [ { "email": "*****@*****.**", "name": "Example User" }, { "email": "*****@*****.**", "name": "Example User" } ] } ], "reply_to": { "email": "*****@*****.**" }, "sections": { "%section1%": "Substitution Text for Section 1", "%section2%": "Substitution Text for Section 2" }, "send_at": 1443636842, "subject": "Hello World from the SendGrid Python Library", "template_id": "13b8f94f-bcae-4ec6-b752-70d6cb59f932", "tracking_settings": { "click_tracking": { "enable": True, "enable_text": True }, "ganalytics": { "enable": True, "utm_campaign": "some campaign", "utm_content": "some content", "utm_medium": "some medium", "utm_source": "some source", "utm_term": "some term" }, "open_tracking": { "enable": True, "substitution_tag": "Optional tag to replace with the " "open image in the body of the message" }, "subscription_tracking": { "enable": True, "html": "<html><body>html to insert into the text/html " "portion of the message</body></html>", "substitution_tag": "Optional tag to replace with the open" " image in the body of the message", "text": "text to insert into the text/plain portion of" " the message" } } } self.assertEqual( json.dumps(mail.get(), sort_keys=True), json.dumps(expected_result, sort_keys=True) )
def _build_sg_mail(self, email): mail = Mail() mail.set_from(self._process_email_addr(email.from_email)) mail.set_subject(email.subject) personalization = Personalization() for e in email.to: personalization.add_to(self._process_email_addr(e)) for e in email.cc: personalization.add_cc(self._process_email_addr(e)) for e in email.bcc: personalization.add_bcc(self._process_email_addr(e)) personalization.set_subject(email.subject) mail.add_content(Content("text/plain", email.body)) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif email.content_subtype == "html": mail.contents = [] mail.add_content(Content("text/plain", ' ')) mail.add_content(Content("text/html", email.body)) if hasattr(email, 'categories'): for c in email.categories: mail.add_category(Category(c)) if hasattr(email, 'custom_args'): for k, v in email.custom_args.items(): mail.add_custom_arg(CustomArg(k, v)) if hasattr(email, 'template_id'): mail.set_template_id(email.template_id) if hasattr(email, 'substitutions'): for key, value in email.substitutions.items(): personalization.add_substitution(Substitution(key, value)) # SendGrid does not support adding Reply-To as an extra # header, so it needs to be manually removed if it exists. reply_to_string = "" for key, value in email.extra_headers.items(): if key.lower() == "reply-to": reply_to_string = value else: mail.add_header({key: value}) # Note that if you set a "Reply-To" header *and* the reply_to # attribute, the header's value will be used. if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to: # SendGrid only supports setting Reply-To to a single address. # See https://github.com/sendgrid/sendgrid-csharp/issues/339. reply_to_string = email.reply_to[0] # Determine whether reply_to contains a name and email address, or # just an email address. if reply_to_string: reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string) if reply_to_name and reply_to_email: mail.set_reply_to(Email(reply_to_email, reply_to_name)) elif reply_to_email: mail.set_reply_to(Email(reply_to_email)) for attachment in email.attachments: if isinstance(attachment, MIMEBase): attach = Attachment() attach.set_filename(attachment.get_filename()) attach.set_content(base64.b64encode(attachment.get_payload())) mail.add_attachment(attach) elif isinstance(attachment, tuple): attach = Attachment() attach.set_filename(attachment[0]) base64_attachment = base64.b64encode(attachment[1]) if sys.version_info >= (3, ): attach.set_content(str(base64_attachment, 'utf-8')) else: attach.set_content(base64_attachment) attach.set_type(attachment[2]) mail.add_attachment(attach) mail.add_personalization(personalization) return mail.get()
def _build_sg_mail(self, email): mail = Mail() from_name, from_email = rfc822.parseaddr(email.from_email) # Python sendgrid client should improve # sendgrid/helpers/mail/mail.py:164 if not from_name: from_name = None mail.from_email = Email(from_email, from_name) mail.subject = email.subject personalization = Personalization() for e in email.to: personalization.add_to(Email(e)) for e in email.cc: personalization.add_cc(Email(e)) for e in email.bcc: personalization.add_bcc(Email(e)) personalization.subject = email.subject mail.add_content(Content("text/plain", email.body)) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif email.content_subtype == "html": mail.contents = [] mail.add_content(Content("text/plain", ' ')) mail.add_content(Content("text/html", email.body)) if hasattr(email, 'categories'): for c in email.categories: mail.add_category(Category(c)) if hasattr(email, 'template_id'): mail.template_id = email.template_id if hasattr(email, 'substitutions'): for k, v in email.substitutions.items(): personalization.add_substitution(Substitution(k, v)) if hasattr(email, 'custom_args'): for item in email.custom_args: for k, v in item.items(): mail.add_custom_arg(CustomArg(k, v)) for k, v in email.extra_headers.items(): mail.add_header({k: v}) for attachment in email.attachments: if isinstance(attachment, MIMEBase): attach = Attachment() attach.filename = attachment.get_filename() attach.content = base64.b64encode(attachment.get_payload()) mail.add_attachment(attach) elif isinstance(attachment, tuple): attach = Attachment() attach.filename = attachment[0] base64_attachment = base64.b64encode(attachment[1]) if sys.version_info >= (3,): attach.content = str(base64_attachment, 'utf-8') else: attach.content = base64_attachment attach.type = attachment[2] mail.add_attachment(attach) mail.add_personalization(personalization) return mail.get()
def _build_sg_mail(self, email): mail = Mail() from_name, from_email = rfc822.parseaddr(email.from_email) # Python sendgrid client should improve # sendgrid/helpers/mail/mail.py:164 if not from_name: from_name = None mail.from_email = Email(from_email, from_name) mail.subject = email.subject mail_settings = MailSettings() personalization = Personalization() for e in email.to: personalization.add_to(Email(e)) for e in email.cc: personalization.add_cc(Email(e)) for e in email.bcc: personalization.add_bcc(Email(e)) personalization.subject = email.subject if email.content_subtype == "html": mail.add_content(Content("text/html", email.body)) else: mail.add_content(Content("text/plain", email.body)) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif email.content_subtype == "html": mail.contents = [] mail.add_content(Content("text/plain", ' ')) if hasattr(email, 'categories'): for c in email.categories: mail.add_category(Category(c)) if hasattr(email, 'custom_args'): for k, v in email.custom_args.items(): mail.add_custom_arg(CustomArg(k, v)) # Used to override the list management (password reset etc) if hasattr(email, 'bypass_list_management'): mail_settings.bypass_list_management = BypassListManagement( email.bypass_list_management) #Check for sandbox mode sandbox_mode = getattr(settings, "SENDGRID_SANDBOX", False) if sandbox_mode: sandbox_whitelist_domains = getattr( settings, "SENDGRID_SANDBOX_WHITELIST_DOMAINS", []) sandbox_whitelist = False for e in email.to: domain = e.split('@')[1] if domain in sandbox_whitelist_domains: sandbox_whitelist = True if not sandbox_whitelist: mail_settings.sandbox_mode = SandBoxMode(sandbox_mode) if hasattr(email, 'template_id'): mail.template_id = email.template_id # Version 3 dynamic data handle bars {{name}} if hasattr(email, 'dynamic_data'): personalization.dynamic_template_data = email.dynamic_data # Version 3 substitutions if hasattr(email, 'substitutions'): for key, value in email.substitutions.items(): personalization.add_substitution(Substitution(key, value)) # SendGrid does not support adding Reply-To as an extra # header, so it needs to be manually removed if it exists. reply_to_string = "" for key, value in email.extra_headers.items(): if key.lower() == "reply-to": reply_to_string = value else: mail.add_header({key: value}) # Note that if you set a "Reply-To" header *and* the reply_to # attribute, the header's value will be used. if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to: # SendGrid only supports setting Reply-To to a single address. # See https://github.com/sendgrid/sendgrid-csharp/issues/339. reply_to_string = email.reply_to[0] # Determine whether reply_to contains a name and email address, or # just an email address. if reply_to_string: reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string) if reply_to_name and reply_to_email: mail.reply_to = Email(reply_to_email, reply_to_name) elif reply_to_email: mail.reply_to = Email(reply_to_email) for attachment in email.attachments: if isinstance(attachment, MIMEBase): attach = Attachment() attach.filename = attachment.get_filename() attach.content = base64.b64encode(attachment.get_payload()) mail.add_attachment(attach) elif isinstance(attachment, tuple): attach = Attachment() attach.filename = attachment[0] base64_attachment = base64.b64encode(attachment[1]) if sys.version_info >= (3, ): attach.content = str(base64_attachment, 'utf-8') else: attach.content = base64_attachment attach.type = attachment[2] mail.add_attachment(attach) mail.add_personalization(personalization) mail.mail_settings = mail_settings return mail.get()
def send_number_email(): logger.info({ 'resource': 'numberemailer-sender', 'operation': 'send_number_email' }) data = request.get_json() num = data["number"] to_emails = data["to_emails"].split('\n') submission_id = None try: url = os.environ['SUBMISSION_URL'] api_key = os.environ['SUBMISSION_APIKEY'] resp = requests.post(url, json={'recipient_count': len(to_emails)}, headers={'X-API-Key': api_key}) if resp.status_code == 201: resp_data = resp.json() submission_id = resp_data['submission_id'] logger.info({ 'resource': 'numberemailer-sender', 'operation': 'send_number_email', 'details': { 'action': 'Fetched submission_id', 'submission_id': submission_id, 'api-key': api_key } }) except Exception as e: logger.error({ 'message': 'Error fetching submission_id', 'error': str(e), 'details': { 'recipient_count': len(to_emails) } }) return jsonify('failed to fetch submission_id'), 404 # fetch email template from S3 # - maybe figure this out later as its unneeded for this demo # render email template with number email_body = render_template_string( "<html><h1>Hello Friend,</h1><p>Your randomly generated number was {{ num }}.</p><p>Enjoy!</p></html>", num=num) mail = Mail( from_email=os.environ["FROM_EMAIL"], to_emails=to_emails, subject="SendGrid Demo / Random Number Generating Emailer", html_content=email_body, ) mail.add_custom_arg( CustomArg(key="submission_id", value=int(submission_id))) # send email to SendGrid API passing it the template sg.client.mail.send.post(request_body=mail.get()) # return status response return jsonify({ "message": "Successful email push to SendGrid", "submission_id": submission_id })
def _build_sg_mail(self, email): mail = Mail() from_name, from_email = rfc822.parseaddr(email.from_email) # Python sendgrid client should improve # sendgrid/helpers/mail/mail.py:164 if not from_name: from_name = None mail.set_from(Email(from_email, from_name)) mail.set_subject(email.subject) personalization = Personalization() for e in email.to: personalization.add_to(Email(e)) for e in email.cc: personalization.add_cc(Email(e)) for e in email.bcc: personalization.add_bcc(Email(e)) personalization.set_subject(email.subject) mail.add_content(Content("text/plain", email.body)) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif email.content_subtype == "html": mail.contents = [] mail.add_content(Content("text/plain", ' ')) mail.add_content(Content("text/html", email.body)) if hasattr(email, 'categories'): for c in email.categories: mail.add_category(Category(c)) if hasattr(email, 'custom_args'): for k, v in email.custom_args.items(): mail.add_custom_arg(CustomArg(k, v)) if hasattr(email, 'template_id'): mail.set_template_id(email.template_id) if hasattr(email, 'substitutions'): for key, value in email.substitutions.items(): personalization.add_substitution(Substitution(key, value)) # SendGrid does not support adding Reply-To as an extra # header, so it needs to be manually removed if it exists. reply_to_string = "" for key, value in email.extra_headers.items(): if key.lower() == "reply-to": reply_to_string = value else: mail.add_header({key: value}) # Note that if you set a "Reply-To" header *and* the reply_to # attribute, the header's value will be used. if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to: # SendGrid only supports setting Reply-To to a single address. # See https://github.com/sendgrid/sendgrid-csharp/issues/339. reply_to_string = email.reply_to[0] # Determine whether reply_to contains a name and email address, or # just an email address. if reply_to_string: reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string) if reply_to_name and reply_to_email: mail.set_reply_to(Email(reply_to_email, reply_to_name)) elif reply_to_email: mail.set_reply_to(Email(reply_to_email)) for attachment in email.attachments: if isinstance(attachment, MIMEBase): attach = Attachment() attach.set_filename(attachment.get_filename()) attach.set_content(base64.b64encode(attachment.get_payload())) mail.add_attachment(attach) elif isinstance(attachment, tuple): attach = Attachment() attach.set_filename(attachment[0]) base64_attachment = base64.b64encode(attachment[1]) if sys.version_info >= (3,): attach.set_content(str(base64_attachment, 'utf-8')) else: attach.set_content(base64_attachment) attach.set_type(attachment[2]) mail.add_attachment(attach) mail.add_personalization(personalization) return mail.get()
def _build_sg_mail(self, email): """Custom SG email builder that handles image attachment correctly to allow inline images. """ ############# FROM SendGridBackend._build_sg_mail: ############################################################ mail = Mail() from_name, from_email = rfc822.parseaddr(email.from_email) # Python sendgrid client should improve # sendgrid/helpers/mail/mail.py:164 if not from_name: from_name = None mail.set_from(Email(from_email, from_name)) mail.set_subject(email.subject) personalization = Personalization() for e in email.to: personalization.add_to(Email(e)) for e in email.cc: personalization.add_cc(Email(e)) for e in email.bcc: personalization.add_bcc(Email(e)) personalization.set_subject(email.subject) mail.add_content(Content("text/plain", email.body)) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif email.content_subtype == "html": mail.contents = [] mail.add_content(Content("text/plain", " ")) mail.add_content(Content("text/html", email.body)) if hasattr(email, "categories"): for c in email.categories: mail.add_category(Category(c)) if hasattr(email, "custom_args"): for k, v in email.custom_args.items(): mail.add_custom_arg(CustomArg(k, v)) if hasattr(email, "template_id"): mail.set_template_id(email.template_id) if hasattr(email, "substitutions"): for key, value in email.substitutions.items(): personalization.add_substitution(Substitution(key, value)) # SendGrid does not support adding Reply-To as an extra # header, so it needs to be manually removed if it exists. reply_to_string = "" for key, value in email.extra_headers.items(): if key.lower() == "reply-to": reply_to_string = value else: mail.add_header({key: value}) # Note that if you set a "Reply-To" header *and* the reply_to # attribute, the header's value will be used. if not mail.reply_to and hasattr(email, "reply_to") and email.reply_to: # SendGrid only supports setting Reply-To to a single address. # See https://github.com/sendgrid/sendgrid-csharp/issues/339. reply_to_string = email.reply_to[0] # Determine whether reply_to contains a name and email address, or # just an email address. if reply_to_string: reply_to_name, reply_to_email = rfc822.parseaddr(reply_to_string) if reply_to_name and reply_to_email: mail.set_reply_to(Email(reply_to_email, reply_to_name)) elif reply_to_email: mail.set_reply_to(Email(reply_to_email)) ########################### CUSTOM HANDLING OF ATTACHMENTS #################################################### for (index, attachment) in enumerate(email.attachments): if isinstance(attachment, MIMEBase): attach = Attachment() # Re-encode into base64 to avoid newlines; then send JSON-serializable utf-8 format. attach.set_content( str(base64.b64encode(attachment.get_payload(decode=True)), "utf-8") ) # Add Content-ID header to allow use of images via src="cid:..." content_id_values = attachment.get_all("Content-ID") if not content_id_values: content_id = "attachment-%05d" % (index + 1) else: content_id = content_id_values[0] attach.set_content_id(content_id) # Add filename, which is required by SendGrid for all attachments filename_values = attachment.get_all("Filename") if filename_values: attach.set_filename(filename_values[0]) else: attach.set_filename(content_id) # Add Content-Disposition so we can use 'inline' to show images within body of email disposition_values = attachment.get_all("Content-Disposition") if disposition_values: attach.set_disposition(disposition_values[0]) mail.add_attachment(attach) elif isinstance(attachment, tuple): # Leave as is except assume we're using version 3+ of sgbackend attach = Attachment() attach.set_filename(attachment[0]) base64_attachment = base64.b64encode(attachment[1]) attach.set_content(str(base64_attachment, "utf-8")) attach.set_type(attachment[2]) mail.add_attachment(attach) ############# FROM SendGridBackend._build_sg_mail: ############################################################# mail.add_personalization(personalization) return mail.get()