Example #1
0
    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, 'template_id'):
            mail.set_template_id(email.template_id)
            if hasattr(email, 'substitutions'):
                for k, v in email.substitutions.items():
                    personalization.add_substitution(Substitution(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.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 send_email(self, to_email: EmailStr, subject: str, body: str):
     message = Mail(from_email=self.sender_email,
                    to_emails=to_email, subject=subject, html_content=body)
     message.add_header(
         Header('X-Entity-Ref-ID', str(random.randint(1, 15000000))))
     sg = SendGridAPIClient(self.api_key)
     response = sg.send(message)
Example #3
0
    def _sendgrid_mail_from_email_message(message, to_address):
        """
        Create a Mail object from an instance of email.message.EmailMessage.

        This is a copy and tweak of Mail.from_EmailMessage from the SendGrid SDK
        to get around a bug where it creates an Email object and later requires
        that object to be an instance of a To, Cc, or Bcc object.

        It also strips out any reserved key headers on the message object.
        """

        mail = Mail(
            from_email=Email(message.get('From')),
            subject=message.get('Subject'),

            # Create a To object instead of an Email object
            to_emails=To(to_address),
        )
        try:
            body = message.get_content()
        except AttributeError:
            # Python2
            body = message.get_payload(decode=True).decode('utf-8')
        mail.add_content(Content(message.get_content_type(), body.strip()))

        # These headers are not allowed on the message object
        # https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/errors.html#message.headers
        skip_headers = [
            'x-sg-id', 'x-sg-eid', 'received', 'dkim-signature',
            'Content-Type', 'Content-Transfer-Encoding', 'To', 'From',
            'Subject', 'Reply-To', 'CC', 'BCC'
        ]

        for k, v in message.items():
            if k not in skip_headers:
                mail.add_header(Header(k, v))
        return mail
Example #4
0
    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
Example #5
0
    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))
Example #6
0
    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, '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 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)
        )
Example #8
0
    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()
Example #9
0
    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()
Example #11
-12
def send_email_task(*args, **kwargs):
    from_email = settings.DEFAULT_FROM_EMAIL
    message = Mail(from_email=from_email, **kwargs)
    message.add_header(Header('reply_to', '*****@*****.**'))

    try:
        sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
        sg.send(message)
    except Exception as e:
        print(e.args)