def send(self, config, subject, body, img, row): content = Content("text/html", body) attachment = Attachment() attachment.content = img attachment.type = "image/jpeg" attachment.filename = "qrcode.jpg" attachment.disposition = "inline" attachment.content_id = "qrcode" fromaddr = Email(config.from_email) toaddr = Email(row['email']) mail = Mail(fromaddr, subject, toaddr, content) mail.add_attachment(attachment) try: response = self.sg.client.mail.send.post(request_body=mail.get()) except urllib.HTTPError as err: print(err.read()) exit() print(response.status_code) print(response.body) print(response.headers)
def create_ticket_message(ticket): event = ticket.article.event tmpl = loader.get_template('events/email/ticket_message.md') subject = 'Entrada para {}'.format(event.name) body = tmpl.render({ 'ticket': ticket, 'article': ticket.article, 'category': ticket.article.category, 'event': event, }) mail = Mail(from_email=Email(settings.CONTACT_EMAIL, settings.ASSOCIATION_NAME), subject=subject, to_email=Email(ticket.customer_email), content=Content('text/html', as_markdown(body))) attachment = Attachment() pdf_filename = ticket.as_pdf() with open(pdf_filename, 'rb') as f: data = f.read() attachment.content = base64.b64encode(data).decode() attachment.type = 'application/pdf' attachment.filename = 'ticket.pdf' attachment.disposition = 'attachment' mail.add_attachment(attachment) return mail
def sendgrid_sendmail(self, _apikey, _from, _to, _subject, _body, attachments=[]): file_name, data = attachments[0] sg = sendgrid.SendGridAPIClient(apikey=_apikey) from_email = Email(_from) subject = _subject to_email = Email(_to) content = Content("text/plain", _body) encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.content = encoded attachment.type = "application/x-mobipocket-ebook" attachment.filename = file_name attachment.disposition = "attachment" attachment.content_id = "kindleear" mail = Mail(from_email, subject, to_email, content) mail.add_attachment(attachment) response = sg.client.mail.send.post(request_body=mail.get()) if response.status_code == 202: default_log.warn('Sendgrid succeed send mail : %s', file_name) else: default_log.warn('Sendgrid send mail failed, error code: %s', str(response.status_code)) return response.status_code
def construct_email(mailfrom: str, mailto: list, subject: str, content: str, attfilename: str, data: str): """ still intake one mailfrom and one mailto for now params: mailfrom: an email, mailto: an email, subject: str, data: csv-ready string attfilename: filename for attachment """ mail = Mail() mail.from_email = Email(mailfrom) mail.subject = subject mail.add_content(Content("text/html", content)) personalization = Personalization() for i in mailto: personalization.add_to(Email(i)) mail.add_personalization(personalization) attachment = Attachment() attachment.content = str(base64.b64encode(data.encode('utf-8')), 'utf-8') attachment.type = 'text/csv' attachment.filename = attfilename attachment.disposition = 'attachment' mail.add_attachment(attachment) return mail
def sendlog(): sg = sendgrid.SendGridAPIClient(apikey=os.environ['SENDGRID_API_KEY']) contentString = "bi-weekly refactoring roundup" attachment = Attachment() attachment.content = encodefile('log/out.txt') attachment.type = 'text/plain' attachment.filename = 'log/out.txt' attachment.disposition = 'attachment' attachment.content_id = 'log' from_email = Email('*****@*****.**') to_email = Email('*****@*****.**') subject = 'refactoring roundup' content = Content('text/plain', contentString) mail = Mail(from_email, subject, to_email, content) mail.add_attachment(attachment) mail.personalizations[0].add_cc(Email('*****@*****.**')) response = sg.client.mail.send.post(request_body=mail.get()) print(response.status_code) print(response.body) print(response.headers)
def send_email(to, subject, html_content, files=None, dryrun=False, cc=None, bcc=None, mime_subtype='mixed', **kwargs): """ Send an email with html content using sendgrid. To use this plugin: 0. include sendgrid subpackage as part of your Airflow installation, e.g., pip install airflow[sendgrid] 1. update [email] backend in airflow.cfg, i.e., [email] email_backend = airflow.contrib.utils.sendgrid.send_email 2. configure Sendgrid specific environment variables at all Airflow instances: SENDGRID_MAIL_FROM={your-mail-from} SENDGRID_API_KEY={your-sendgrid-api-key}. """ mail = Mail() mail.from_email = Email(os.environ.get('SENDGRID_MAIL_FROM')) mail.subject = subject # Add the recipient list of to emails. personalization = Personalization() to = get_email_address_list(to) for to_address in to: personalization.add_to(Email(to_address)) if cc: cc = get_email_address_list(cc) for cc_address in cc: personalization.add_cc(Email(cc_address)) if bcc: bcc = get_email_address_list(bcc) for bcc_address in bcc: personalization.add_bcc(Email(bcc_address)) # Add custom_args to personalization if present pers_custom_args = kwargs.get('personalization_custom_args', None) if isinstance(pers_custom_args, dict): for key in pers_custom_args.keys(): personalization.add_custom_arg(CustomArg(key, pers_custom_args[key])) mail.add_personalization(personalization) mail.add_content(Content('text/html', html_content)) categories = kwargs.get('categories', []) for cat in categories: mail.add_category(Category(cat)) # Add email attachment. for fname in files or []: basename = os.path.basename(fname) attachment = Attachment() with open(fname, "rb") as f: attachment.content = base64.b64encode(f.read()) attachment.type = mimetypes.guess_type(basename)[0] attachment.filename = basename attachment.disposition = "attachment" attachment.content_id = '<%s>' % basename mail.add_attachment(attachment) _post_sendgrid_mail(mail.get())
def build_attachment2(): """Build attachment mock.""" attachment = Attachment() attachment.content = "BwdW" attachment.type = "image/png" attachment.filename = "banner.png" attachment.disposition = "inline" attachment.content_id = "Banner" return attachment
def create_attachment(file_path): new_attachment = Attachment() new_attachment.content = get_content(file_path) new_attachment.type = get_mime(file_path) new_attachment.filename = get_basename(file_path) new_attachment.disposition = 'attachment' new_attachment.content_id = '{} File'.format( get_extension(file_path).upper()) return new_attachment
def build_attachment1(): """Build attachment mock. Make sure your content is base64 encoded before passing into attachment.content. Another example: https://github.com/sendgrid/sendgrid-python/blob/master/use_cases/attachment.md""" attachment = Attachment() attachment.content = ("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl" "Y3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12") attachment.type = "application/pdf" attachment.filename = "balance_001.pdf" attachment.disposition = "attachment" attachment.content_id = "Balance Sheet" return attachment
def send_email(to, subject, html_content, files=None, dryrun=False, cc=None, bcc=None, mime_subtype='mixed', **kwargs): """ Send an email with html content using sendgrid. To use this plugin: 0. include sendgrid subpackage as part of your Airflow installation, e.g., pip install airflow[sendgrid] 1. update [email] backend in airflow.cfg, i.e., [email] email_backend = airflow.contrib.utils.sendgrid.send_email 2. configure Sendgrid specific environment variables at all Airflow instances: SENDGRID_MAIL_FROM={your-mail-from} SENDGRID_API_KEY={your-sendgrid-api-key}. """ mail = Mail() mail.from_email = Email(os.environ.get('SENDGRID_MAIL_FROM')) mail.subject = subject # Add the recipient list of to emails. personalization = Personalization() to = get_email_address_list(to) for to_address in to: personalization.add_to(Email(to_address)) if cc: cc = get_email_address_list(cc) for cc_address in cc: personalization.add_cc(Email(cc_address)) if bcc: bcc = get_email_address_list(bcc) for bcc_address in bcc: personalization.add_bcc(Email(bcc_address)) mail.add_personalization(personalization) mail.add_content(Content('text/html', html_content)) # Add custom_args to personalization if present pers_custom_args = kwargs.get('personalization_custom_args', None) if isinstance(pers_custom_args, dict): for key in pers_custom_args.keys(): personalization.add_custom_arg(CustomArg(key, pers_custom_args[key])) # Add email attachment. for fname in files or []: basename = os.path.basename(fname) attachment = Attachment() with open(fname, "rb") as f: attachment.content = base64.b64encode(f.read()) attachment.type = mimetypes.guess_type(basename)[0] attachment.filename = basename attachment.disposition = "attachment" attachment.content_id = '<%s>' % basename mail.add_attachment(attachment) _post_sendgrid_mail(mail.get())
def _create_attachment(cls, attachment: dict) -> Attachment: filename = attachment.get('filename', '') content = attachment.get('content', '') mail_attachment = Attachment() mail_attachment.disposition = 'attachment' mail_attachment.filename = filename mail_attachment.content_id = filename mail_attachment.type = guess_type(filename)[0] mail_attachment.content = content return mail_attachment
def add_attachments( mail: Mail, attachments: Union[List[Dict[str, Any]], Dict[str, Any]]) -> Mail: if isinstance(attachments, dict): attachments = [attachments] for att_dict in attachments: attachment = Attachment() attachment.content = att_dict["content"] attachment.filename = att_dict["filename"] attachment.type = att_dict.get("type") attachment.disposition = att_dict.get("disposition") mail.add_attachment(attachment) return mail
def build_attachment(attachment): """ Returns a valid sendgrid attachment from typical attachment object. """ sendgridattachment = SendGridAttachment() sendgridattachment.content = base64.b64encode( attachment.binarycontent).decode() sendgridattachment.type = attachment.type sendgridattachment.filename = attachment.originalfilename sendgridattachment.disposition = "attachment" sendgridattachment.content_id = attachment.originalfilename return sendgridattachment
def attachment_build(self, filepath,type="application/pdf"): """ Returns a valid sendgrid attachment from typical attachment object. """ data = j.sal.fs.readFile(filepath,binary=False) sendgridattachment = SendGridAttachment() sendgridattachment.content = data sendgridattachment.type = type sendgridattachment.filename = filepath sendgridattachment.disposition = "attachment" sendgridattachment.content_id = filepath return sendgridattachment
def send_emails_via_sendgrid(encoded_img: "base 64 string"): attachment = Attachment() attachment.content = encoded_img attachment.type = "image/jpeg" attachment.filename = "fallen.jpeg" attachment.disposition = "inline" attachment.content_id = "fallen-picture" for to_email in to_emails: email_data = Mail(from_email, subject, to_email, content) email_data.add_attachment(attachment) response = sgclient.client.mail.send.post( request_body=email_data.get()) print("email status: {}".format(response.status_code))
def send_sendgrid_email(self): self.is_sent = True user_full_name = ' '.join( [self.created_by.first_name, self.created_by.last_name]) from_email = SendGridEmail(self.created_by.email, user_full_name) subject = self.subject content = Content('text/html', self.body) contact_full_name = ' '.join([self.first_name, self.last_name]) to_email = SendGridEmail(self.to, contact_full_name) mail = Mail(from_email, subject, to_email, content) if len(self.CC) > 0: for cc in self.CC: mail.personalizations[0].add_cc(SendGridEmail(cc)) if len(self.BCC) > 0: for bcc in self.BCC: mail.personalizations[0].add_bcc(SendGridEmail(bcc)) if self.attachments.count() > 0: attachments = self.attachments.all() for file_attachment in attachments: # Content Type must exist if file_attachment.content_type != '': body = file_attachment.file.read() base_64_body = base64.b64encode(body) attachment = Attachment() attachment.content = base_64_body attachment.type = file_attachment.content_type attachment.filename = file_attachment.original_name attachment.disposition = 'attachment' attachment.content_id = file_attachment.original_name mail.add_attachment(attachment) body = mail.get() response = sg.client.mail.send.post(request_body=body) if response._headers and 'X-Message-Id' in response._headers: sendgrid_id = response._headers['X-Message-Id'] self.method = 'sendgrid' self.delivered = True self.sendgrid_id = sendgrid_id return response
def email_html_for_development(self, html, subject, gene): #SenfGrid Key for sengding mails with debug info to me sendgrid_key = "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" sg = sendgrid.SendGridAPIClient(apikey=sendgrid_key) from_email = Email("*****@*****.**") to_email = Email("*****@*****.**") contentstr = "{0}. The gene getting was successful".format(subject) content = Content("text/plain", contentstr) mail = Mail(from_email, subject, to_email, content) att = Attachment() if isinstance(html, str): html = html.encode("UTF-8") att.content = base64.b64encode(html).decode() att.type = "text/html" att.filename = "HGMD_{0}.html".format(gene) att.disposition = "attachment" mail.add_attachment(att) response = sg.client.mail.send.post(request_body=mail.get()) time.sleep(2)
def send_email(usermail): with open('credentials.json', 'r') as f: creds = json.load(f) sendgridapikey = creds["sendgrid"]["api_key"] sg = sendgrid.SendGridAPIClient(apikey=sendgridapikey) ##usermail = sys.argv[1] from_email = Email("*****@*****.**") subject = "WeFundGov donation" ##to_email = Email("*****@*****.**") to_email = Email(usermail) email_body = "please see attached notification" content = Content("text/html", email_body) pdf_path = 'out.pdf' with open(pdf_path,'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.content = encoded attachment.type = "application/pdf" attachment.filename = "test.pdf" attachment.disposition = "attachment" attachment.content_id = "some content id" mail = Mail(from_email, subject, to_email, content) mail.add_attachment(attachment) response = sg.client.mail.send.post(request_body=mail.get()) print(response.status_code) print(response.body) print(response.headers)
def post(self): text_content = self.request.get('text-content') image = self.request.get('file') image = images.resize(image, 100, 100) attachment = Attachment() attachment.filename="image.jpg" attachment.content=base64.b64encode(image) attachment.type="image/jpg" sg = sendgrid.SendGridAPIClient(apikey=SENDGRID_API_KEY) to_email = Email(recipient) from_email = Email(SENDGRID_SENDER) subject = 'New Ticket.' content = Content('text/plain', "New ticket raised with the following issue: " + text_content) message = Mail(from_email, subject, to_email, content) message.add_attachment(attachment) response = sg.client.mail.send.post(request_body=message.get()) self.response.write("Ticket Raised!")
def log_and_email_htmls_with_error(self, htmls, error, subject): #SenfGrid Key for sengding mails with debug info to me sendgrid_key = "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" sg = sendgrid.SendGridAPIClient(apikey=sendgrid_key) from_email = Email("*****@*****.**") to_email = Email("*****@*****.**") #from_email = Email("*****@*****.**") #to_email = Email("*****@*****.**") contentstr = "{0}. During the analysis, the following error happened: {1}".format( subject, traceback.format_exc()) content = Content("text/plain", contentstr) mail = Mail(from_email, subject, to_email, content) error_log_h = open("error.log", "a") error_log_h.write("Error at {0}:\n".format(time.asctime())) error_log_h.write(contentstr) error_log_h.write("\n") print("HTML code of the web page got was dumped in the file error.log") for (htmlname, htmlcontents) in htmls.items(): att = Attachment() error_log_h.write("html {0}:\n{1}\n".format( htmlname, htmlcontents)) if isinstance(htmlcontents, str): htmlcontents = htmlcontents.encode("UTF-8") att.content = base64.b64encode(htmlcontents).decode() att.type = "text/html" att.filename = htmlname att.disposition = "attachment" mail.add_attachment(att) response = sg.client.mail.send.post(request_body=mail.get()) error_log_h.write("mail sending status: {0}\n".format(response)) error_log_h.write("mail sending status code: {0}\n".format( response.status_code)) error_log_h.write("mail sending status body: {0}\n".format( response.body)) error_log_h.write("======================\n") error_log_h.close()
def build_attachment(self, attachment): """ Returns a valid sendgrid attachment from typical attachment object. e.g ``` attachment = Attachment() attachment.content = ("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNl" "Y3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12") attachment.type = "application/pdf" attachment.filename = "balance_001.pdf" attachment.disposition = "attachment" attachment.content_id = "Balance Sheet" return attachment ``` """ sendgridattachment = SendGridAttachment() sendgridattachment.content = base64.b64encode( attachment.binarycontent).decode() sendgridattachment.type = attachment.type sendgridattachment.filename = attachment.originalfilename sendgridattachment.disposition = "attachment" sendgridattachment.content_id = attachment.originalfilename return sendgridattachment
def send_email_sendgrid(to, subject, html_content, files=None, dryrun=False, cc=None, bcc=None, mime_subtype='mixed'): """ Send an email with html content using sendgrid. """ mail = Mail() mail.from_email = Email(configuration.get('sendgrid', 'SENDGRID_MAIL_FROM')) mail.subject = subject # Add the list of to emails. to = get_email_address_list(to) personalization = Personalization() for to_address in to: personalization.add_to(Email(to_address)) mail.add_personalization(personalization) mail.add_content(Content('text/html', html_content)) # Add email attachment. for fname in files or []: basename = os.path.basename(fname) attachment = Attachment() with open(fname, "rb") as f: attachment.content = base64.b64encode(f.read()) attachment.type = mimetypes.guess_type(basename)[0] attachment.filename = basename attachment.disposition = "attachment" attachment.content_id = '<%s>' % basename mail.add_attachment(attachment) _post_sendgrid_mail(mail.get())
def _build_sg_mail(self, msg): mail = Mail() mail.from_email = Email(*self._parse_email_address(msg.from_email)) mail.subject = msg.subject personalization = Personalization() for addr in msg.to: personalization.add_to(Email(*self._parse_email_address(addr))) for addr in msg.cc: personalization.add_cc(Email(*self._parse_email_address(addr))) for addr in msg.bcc: personalization.add_bcc(Email(*self._parse_email_address(addr))) personalization.subject = msg.subject for k, v in msg.extra_headers.items(): if k.lower() == "reply-to": mail.reply_to = Email(v) else: personalization.add_header(Header(k, v)) if hasattr(msg, "template_id"): mail.template_id = msg.template_id if hasattr(msg, "substitutions"): for k, v in msg.substitutions.items(): personalization.add_substitution(Substitution(k, v)) mail.add_personalization(personalization) if hasattr(msg, "reply_to") and msg.reply_to: if mail.reply_to: # If this code path is triggered, the reply_to on the sg mail was set in a header above reply_to = Email(*self._parse_email_address(msg.reply_to)) if reply_to.email != mail.reply_to.email or reply_to.name != mail.reply_to.name: raise ValueError("Sendgrid only allows 1 email in the reply-to field. " + "Reply-To header value != reply_to property value.") if not isinstance(msg.reply_to, basestring): if len(msg.reply_to) > 1: raise ValueError("Sendgrid only allows 1 email in the reply-to field") mail.reply_to = Email(*self._parse_email_address(msg.reply_to[0])) else: mail.reply_to = Email(*self._parse_email_address(msg.reply_to)) for attch in msg.attachments: attachment = Attachment() if isinstance(attch, MIMEBase): filename = attch.get_filename() if not filename: ext = mimetypes.guess_extension(attch.get_content_type()) filename = "part-{0}{1}".format(uuid.uuid4().hex, ext) attachment.filename = filename # todo: Read content if stream? attachment.content = attch.get_payload().replace("\n", "") attachment.type = attch.get_content_type() content_id = attch.get("Content-ID") if content_id: attachment.content_id = content_id attachment.disposition = "inline" else: filename, content, mimetype = attch attachment.filename = filename # todo: Read content if stream? attachment.content = base64.b64encode(content) attachment.type = mimetype mail.add_attachment(attachment) if isinstance(msg, EmailMultiAlternatives): mail.add_content(Content("text/plain", msg.body)) for alt in msg.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif msg.content_subtype == "html": mail.add_content(Content("text/plain", " ")) mail.add_content(Content("text/html", msg.body)) else: mail.add_content(Content("text/plain", msg.body)) if hasattr(msg, "categories"): for cat in msg.categories: mail.add_category(Category(cat)) mail_settings = MailSettings() mail_settings.sandbox_mode = SandBoxMode(self.sandbox_mode) mail.mail_settings = mail_settings tracking_settings = TrackingSettings() tracking_settings.open_tracking = OpenTracking(self.track_email) mail.tracking_settings = tracking_settings 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 stuff(): """ Accept data from the form, generate, display, and email QR code to user """ for user in db.session.query(User).all(): if request.form['email'] == user.get_email(): return 'Email address {} already found in database!\ Please re-enter the form correctly!'.format(request.form['email']) if str(request.form['phone_number']) == str(user.get_phone()): return 'Phone number {} already found in database!\ Please re-enter the form correctly!'.format( request.form['phone_number']) codex_id = get_current_id() user = User(name=request.form['name'], email=request.form['email'], phone=request.form['phone_number'], codex_id=codex_id, department=DEPARTMENTS[request.form['department']]) try: db.session.add(user) db.session.commit() except exc.IntegrityError: return "Error occurred trying to enter values into the database!" img = generate_qr(request.form, codex_id) img.save('qr.png') img_data = open('qr.png', 'rb').read() encoded = base64.b64encode(img_data).decode() name = request.form['name'] from_email = Email(FROM_EMAIL) to_email = Email(request.form['email']) p = None if request.form['email_second_person'] and request.form[ 'name_second_person']: cc_email = Email(request.form['email_second_person']) name += ', {}'.format(request.form['name_second_person']) p = Personalization() p.add_to(cc_email) subject = 'Registration for CodeX April 2019 - ID {}'.format(codex_id) message = """<img src='https://drive.google.com/uc?id=12VCUzNvU53f_mR7Hbumrc6N66rCQO5r-&export=download'> <hr> {}, your registration is done! <br/> A QR code has been attached below! <br/> You're <b>required</b> to present this on the day of the event. """.format(name) content = Content('text/html', message) mail = Mail(from_email, subject, to_email, content) if p: mail.add_personalization(p) attachment = Attachment() attachment.type = 'image/png' attachment.filename = 'qr.png' attachment.content = encoded mail.add_attachment(attachment) response = sg.client.mail.send.post(request_body=mail.get()) print(response.status_code) print(response.body) print(response.headers) return 'Please save this QR Code. It has also been emailed to you.<br><img src=\ "data:image/png;base64, {}"/>'.format(encoded)
def _build_sg_mail(self, msg): mail = Mail() mail.from_email = Email(*self._parse_email_address(msg.from_email)) mail.subject = msg.subject personalization = Personalization() for addr in msg.to: personalization.add_to(Email(*self._parse_email_address(addr))) for addr in msg.cc: personalization.add_cc(Email(*self._parse_email_address(addr))) for addr in msg.bcc: personalization.add_bcc(Email(*self._parse_email_address(addr))) personalization.subject = msg.subject for k, v in msg.extra_headers.items(): if k.lower() == "reply-to": mail.reply_to = Email(v) else: personalization.add_header(Header(k, v)) if hasattr(msg, "template_id"): mail.template_id = msg.template_id if hasattr(msg, "substitutions"): for k, v in msg.substitutions.items(): personalization.add_substitution(Substitution(k, v)) # write through the ip_pool_name attribute if hasattr(msg, "ip_pool_name"): if not isinstance(msg.ip_pool_name, basestring): raise ValueError( "ip_pool_name must be a string, got: {}; " "see https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html#-Request-Body-Parameters" .format(type(msg.ip_pool_name))) if not 2 <= len(msg.ip_pool_name) <= 64: raise ValueError( "the number of characters of ip_pool_name must be min 2 and max 64, got: {}; " "see https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html#-Request-Body-Parameters" .format(len(msg.ip_pool_name))) mail.ip_pool_name = msg.ip_pool_name # write through the send_at attribute if hasattr(msg, "send_at"): if not isinstance(msg.send_at, int): raise ValueError( "send_at must be an integer, got: {}; " "see https://sendgrid.com/docs/API_Reference/SMTP_API/scheduling_parameters.html#-Send-At" .format(type(msg.send_at))) personalization.send_at = msg.send_at mail.add_personalization(personalization) if hasattr(msg, "reply_to") and msg.reply_to: if mail.reply_to: # If this code path is triggered, the reply_to on the sg mail was set in a header above reply_to = Email(*self._parse_email_address(msg.reply_to)) if reply_to.email != mail.reply_to.email or reply_to.name != mail.reply_to.name: raise ValueError( "Sendgrid only allows 1 email in the reply-to field. " + "Reply-To header value != reply_to property value.") if not isinstance(msg.reply_to, basestring): if len(msg.reply_to) > 1: raise ValueError( "Sendgrid only allows 1 email in the reply-to field") mail.reply_to = Email( *self._parse_email_address(msg.reply_to[0])) else: mail.reply_to = Email(*self._parse_email_address(msg.reply_to)) for attch in msg.attachments: attachment = Attachment() if isinstance(attch, MIMEBase): filename = attch.get_filename() if not filename: ext = mimetypes.guess_extension(attch.get_content_type()) filename = "part-{0}{1}".format(uuid.uuid4().hex, ext) attachment.filename = filename # todo: Read content if stream? attachment.content = attch.get_payload().replace("\n", "") attachment.type = attch.get_content_type() content_id = attch.get("Content-ID") if content_id: # Strip brackets since sendgrid's api adds them if content_id.startswith("<") and content_id.endswith(">"): content_id = content_id[1:-1] attachment.content_id = content_id attachment.disposition = "inline" else: filename, content, mimetype = attch attachment.filename = filename # todo: Read content if stream? if isinstance(content, str): content = content.encode() attachment.content = base64.b64encode(content).decode() attachment.type = mimetype mail.add_attachment(attachment) msg.body = ' ' if msg.body == '' else msg.body if isinstance(msg, EmailMultiAlternatives): mail.add_content(Content("text/plain", msg.body)) for alt in msg.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif msg.content_subtype == "html": mail.add_content(Content("text/plain", " ")) mail.add_content(Content("text/html", msg.body)) else: mail.add_content(Content("text/plain", msg.body)) if hasattr(msg, "categories"): for cat in msg.categories: mail.add_category(Category(cat)) if hasattr(msg, "asm"): if "group_id" not in msg.asm: raise KeyError("group_id not found in asm") if "groups_to_display" in msg.asm: mail.asm = ASM(msg.asm["group_id"], msg.asm["groups_to_display"]) else: mail.asm = ASM(msg.asm["group_id"]) mail_settings = MailSettings() mail_settings.sandbox_mode = SandBoxMode(self.sandbox_mode) mail.mail_settings = mail_settings tracking_settings = TrackingSettings() tracking_settings.open_tracking = OpenTracking(self.track_email) mail.tracking_settings = tracking_settings return mail.get()
def _build_sg_mail(self, msg): mail = Mail() mail.from_email = Email(*self._parse_email_address(msg.from_email)) mail.subject = msg.subject personalization = Personalization() for addr in msg.to: personalization.add_to(Email(*self._parse_email_address(addr))) for addr in msg.cc: personalization.add_cc(Email(*self._parse_email_address(addr))) for addr in msg.bcc: personalization.add_bcc(Email(*self._parse_email_address(addr))) personalization.subject = msg.subject for k, v in msg.extra_headers.items(): if k.lower() == "reply-to": mail.reply_to = Email(v) else: personalization.add_header(Header(k, v)) if hasattr(msg, "template_id"): mail.template_id = msg.template_id if hasattr(msg, "substitutions"): for k, v in msg.substitutions.items(): personalization.add_substitution(Substitution(k, v)) # write through the ip_pool_name attribute if hasattr(msg, "ip_pool_name"): if not isinstance(msg.ip_pool_name, basestring): raise ValueError( "ip_pool_name must be a string, got: {}; " "see https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/" "index.html#-Request-Body-Parameters".format( type(msg.ip_pool_name))) if not 2 <= len(msg.ip_pool_name) <= 64: raise ValueError( "the number of characters of ip_pool_name must be min 2 and max 64, got: {}; " "see https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/" "index.html#-Request-Body-Parameters".format( len(msg.ip_pool_name))) mail.ip_pool_name = msg.ip_pool_name # write through the send_at attribute if hasattr(msg, "send_at"): if not isinstance(msg.send_at, int): raise ValueError( "send_at must be an integer, got: {}; " "see https://sendgrid.com/docs/API_Reference/SMTP_API/scheduling_parameters.html#-Send-At".format( type(msg.send_at))) personalization.send_at = msg.send_at mail.add_personalization(personalization) if hasattr(msg, "reply_to") and msg.reply_to: if mail.reply_to: # If this code path is triggered, the reply_to on the sg mail was set in a header above reply_to = Email(*self._parse_email_address(msg.reply_to)) if reply_to.email != mail.reply_to.email or reply_to.name != mail.reply_to.name: raise ValueError("Sendgrid only allows 1 email in the reply-to field. " + "Reply-To header value != reply_to property value.") if not isinstance(msg.reply_to, basestring): if len(msg.reply_to) > 1: raise ValueError("Sendgrid only allows 1 email in the reply-to field") mail.reply_to = Email(*self._parse_email_address(msg.reply_to[0])) else: mail.reply_to = Email(*self._parse_email_address(msg.reply_to)) for attch in msg.attachments: attachment = Attachment() if isinstance(attch, MIMEBase): filename = attch.get_filename() if not filename: ext = mimetypes.guess_extension(attch.get_content_type()) filename = "part-{0}{1}".format(uuid.uuid4().hex, ext) attachment.filename = filename # todo: Read content if stream? attachment.content = attch.get_payload().replace("\n", "") attachment.type = attch.get_content_type() content_id = attch.get("Content-ID") if content_id: # Strip brackets since sendgrid's api adds them if content_id.startswith("<") and content_id.endswith(">"): content_id = content_id[1:-1] attachment.content_id = content_id attachment.disposition = "inline" else: filename, content, mimetype = attch attachment.filename = filename # Convert content from chars to bytes, in both Python 2 and 3. # todo: Read content if stream? if isinstance(content, str): content = content.encode('utf-8') attachment.content = base64.b64encode(content).decode() attachment.type = mimetype mail.add_attachment(attachment) msg.body = ' ' if msg.body == '' else msg.body if isinstance(msg, EmailMultiAlternatives): mail.add_content(Content("text/plain", msg.body)) for alt in msg.alternatives: if alt[1] == "text/html": mail.add_content(Content(alt[1], alt[0])) elif msg.content_subtype == "html": mail.add_content(Content("text/plain", " ")) mail.add_content(Content("text/html", msg.body)) else: mail.add_content(Content("text/plain", msg.body)) if hasattr(msg, "categories"): for cat in msg.categories: mail.add_category(Category(cat)) if hasattr(msg, "asm"): if "group_id" not in msg.asm: raise KeyError("group_id not found in asm") if "groups_to_display" in msg.asm: mail.asm = ASM(msg.asm["group_id"], msg.asm["groups_to_display"]) else: mail.asm = ASM(msg.asm["group_id"]) mail_settings = MailSettings() mail_settings.sandbox_mode = SandBoxMode(self.sandbox_mode) mail.mail_settings = mail_settings tracking_settings = TrackingSettings() tracking_settings.open_tracking = OpenTracking(self.track_email) mail.tracking_settings = tracking_settings return mail.get()
def land(logname, lastrow, nrows, platform='Unknown', sender='*****@*****.**', recipient=None): """ Sends summary report to land via email. Args: logname (str): directory name under which log results are saved. lastrow (int): Last row of data delivered in past email. nrows (int): Number of rows to sent in current email. platform (str): Name of platform, the "callsign" for ships. """ # Get dataframe from CSV log file path = os.path.join(os.path.dirname(__file__), '..', 'log', logname, '') csv = path + logname + '.csv' df = pd.read_csv(csv) # Return last row sent and exit if dataframe has less than n new rows if len(df[lastrow:]) < nrows: return lastrow # Proceed with new delivery otherwise else: delivery = df[lastrow:lastrow + nrows] # Set sender, recipient, and subject sender = Email(sender) if recipient is None: raise Exception('No recipient email address') recipient = Email(recipient) subject = 'RapidKrill report: %s_%s' % ( platform, delivery.Time.tail(1).values[0]) # Prepare text content text = io.StringIO() text.write('Attachment header: %s, %s, %s, %s, %s, %s, %s, %s\n' % tuple(delivery.columns)) text = text.getvalue() # Prepare attachment data data = io.StringIO() for i, row in delivery.iterrows(): data.write( '%s, %10.5f, %9.5f, %4.0f, %5.1f, %6.1f, %10.2f, %5.1f\n' % tuple(row)) data = data.getvalue() # Build email and send logger.info('Sending report to land') config = os.path.join(os.path.dirname(__file__), 'config.toml') if not toml.load(config)['sendgrid']['key'].strip(): raise Exception('No sendgrid key in config.file. Report not sent.') apikey = toml.load(config)['sendgrid']['key'] sg = sendgrid.SendGridAPIClient(apikey=apikey) content = Content('text/plain', text) attachment = Attachment() encoded = base64.b64encode(str.encode(data)).decode() attachment.content = encoded attachment.type = 'application/csv' attachment.filename = 'data.csv' mail = Mail(sender, subject, recipient, content) mail.add_attachment(attachment) response = sg.client.mail.send.post(request_body=mail.get()) if response.status_code is 202: logger.info('Report sent') else: logger.warning('Sending report failed') # Return new last row sent lastrow = lastrow + nrows return lastrow
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) )
widget_file.close() # Send email via sendgrid sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY')) from_email = Email(os.environ.get('SENDGRID_SEND_FROM_EMAIL'), os.environ.get('SENDGRID_SEND_FROM_NAME')) subject = "Revcontent - Daily Stats" to_email = Email(os.environ.get("SENDGRID_SEND_TO_EMAIL")) content = Content("text/plain", "Here is the daily revcontent widget stats") # Generate attachment with open(widget_filename, 'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.content = encoded attachment.type = "text/csv" attachment.filename = widget_filename attachment.disposition = "attachment" attachment.content_id = widget_filename mail = Mail(from_email, subject, to_email, content) mail.add_attachment(attachment) response = sg.client.mail.send.post(request_body=mail.get()) print(response.status_code) print(response.body) print(response.headers)
def send_email(to, subject, html_content, files=None, cc=None, bcc=None, sandbox_mode=False, **kwargs): """ Send an email with html content using sendgrid. To use this plugin: 0. include sendgrid subpackage as part of your Airflow installation, e.g., pip install 'apache-airflow[sendgrid]' 1. update [email] backend in airflow.cfg, i.e., [email] email_backend = airflow.contrib.utils.sendgrid.send_email 2. configure Sendgrid specific environment variables at all Airflow instances: SENDGRID_MAIL_FROM={your-mail-from} SENDGRID_API_KEY={your-sendgrid-api-key}. """ if files is None: files = [] mail = Mail() from_email = kwargs.get('from_email') or os.environ.get( 'SENDGRID_MAIL_FROM') from_name = kwargs.get('from_name') or os.environ.get( 'SENDGRID_MAIL_SENDER') mail.from_email = Email(from_email, from_name) mail.subject = subject mail.mail_settings = MailSettings() if sandbox_mode: mail.mail_settings.sandbox_mode = SandBoxMode(enable=True) # Add the recipient list of to emails. personalization = Personalization() to = get_email_address_list(to) for to_address in to: personalization.add_to(Email(to_address)) if cc: cc = get_email_address_list(cc) for cc_address in cc: personalization.add_cc(Email(cc_address)) if bcc: bcc = get_email_address_list(bcc) for bcc_address in bcc: personalization.add_bcc(Email(bcc_address)) # Add custom_args to personalization if present pers_custom_args = kwargs.get('personalization_custom_args', None) if isinstance(pers_custom_args, dict): for key in pers_custom_args.keys(): personalization.add_custom_arg( CustomArg(key, pers_custom_args[key])) mail.add_personalization(personalization) mail.add_content(Content('text/html', html_content)) categories = kwargs.get('categories', []) for cat in categories: mail.add_category(Category(cat)) # Add email attachment. for fname in files: basename = os.path.basename(fname) attachment = Attachment() attachment.type = mimetypes.guess_type(basename)[0] attachment.filename = basename attachment.disposition = "attachment" attachment.content_id = '<{0}>'.format(basename) with open(fname, "rb") as file: attachment.content = base64.b64encode(file.read()).decode('utf-8') mail.add_attachment(attachment) _post_sendgrid_mail(mail.get())
def send_email(to, subject, html_content, files=None, dryrun=False, cc=None, bcc=None, mime_subtype='mixed', sandbox_mode=False, **kwargs): """ Send an email with html content using sendgrid. To use this plugin: 0. include sendgrid subpackage as part of your Airflow installation, e.g., pip install 'apache-airflow[sendgrid]' 1. update [email] backend in airflow.cfg, i.e., [email] email_backend = airflow.contrib.utils.sendgrid.send_email 2. configure Sendgrid specific environment variables at all Airflow instances: SENDGRID_MAIL_FROM={your-mail-from} SENDGRID_API_KEY={your-sendgrid-api-key}. """ if files is None: files = [] mail = Mail() from_email = kwargs.get('from_email') or os.environ.get('SENDGRID_MAIL_FROM') from_name = kwargs.get('from_name') or os.environ.get('SENDGRID_MAIL_SENDER') mail.from_email = Email(from_email, from_name) mail.subject = subject mail.mail_settings = MailSettings() if sandbox_mode: mail.mail_settings.sandbox_mode = SandBoxMode(enable=True) # Add the recipient list of to emails. personalization = Personalization() to = get_email_address_list(to) for to_address in to: personalization.add_to(Email(to_address)) if cc: cc = get_email_address_list(cc) for cc_address in cc: personalization.add_cc(Email(cc_address)) if bcc: bcc = get_email_address_list(bcc) for bcc_address in bcc: personalization.add_bcc(Email(bcc_address)) # Add custom_args to personalization if present pers_custom_args = kwargs.get('personalization_custom_args', None) if isinstance(pers_custom_args, dict): for key in pers_custom_args.keys(): personalization.add_custom_arg(CustomArg(key, pers_custom_args[key])) mail.add_personalization(personalization) mail.add_content(Content('text/html', html_content)) categories = kwargs.get('categories', []) for cat in categories: mail.add_category(Category(cat)) # Add email attachment. for fname in files: basename = os.path.basename(fname) attachment = Attachment() attachment.type = mimetypes.guess_type(basename)[0] attachment.filename = basename attachment.disposition = "attachment" attachment.content_id = '<{0}>'.format(basename) with open(fname, "rb") as f: attachment.content = base64.b64encode(f.read()).decode('utf-8') mail.add_attachment(attachment) _post_sendgrid_mail(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))
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()