def _create_sg_attachment(self, django_attch: DjangoAttachment) -> Attachment: """ Handles the conversion between a django attachment object and a sendgrid attachment object. Due to differences between sendgrid's API versions, use this method when constructing attachments to ensure that attachments get properly instantiated. """ def set_prop(attachment, prop_name, value): if SENDGRID_5: setattr(attachment, prop_name, value) else: if prop_name == "filename": prop_name = "name" setattr(attachment, "file_{}".format(prop_name), value) sg_attch = Attachment() if isinstance(django_attch, MIMEBase): filename = django_attch.get_filename() if not filename: ext = mimetypes.guess_extension( django_attch.get_content_type()) filename = "part-{0}{1}".format(uuid.uuid4().hex, ext) set_prop(sg_attch, "filename", filename) # todo: Read content if stream? set_prop(sg_attch, "content", django_attch.get_payload().replace("\n", "")) # Content-type handling. Includes the 'method' param. content_type = django_attch.get_content_type() method = django_attch.get_param("method") if method: if content_type.strip()[-1] != ";": content_type += ";" content_type += f" method={method};" set_prop(sg_attch, "type", content_type) content_id = django_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] # These 2 properties did not change in v6, so we set them the usual way sg_attch.content_id = content_id sg_attch.disposition = "inline" else: filename, content, mimetype = django_attch set_prop(sg_attch, "filename", filename) # todo: Read content if stream? if isinstance(content, str): content = content.encode() set_prop(sg_attch, "content", base64.b64encode(content).decode()) set_prop(sg_attch, "type", mimetype) return sg_attch
def send_registration_mail(attendee: Attendee, event: Event): qr_data = gen_qrcode(data=str(attendee.uuid)).read() template = templates['REGISTRATION'] mail = Mail() mail.from_email = Email(template['FROM_EMAIL'], template['FROM_NAME']) mail.template_id = template['ID'] mail.add_category(Category(template['CATEGORY'])) attachment1 = Attachment() attachment1.content = base64.b64encode(qr_data).decode('ascii') attachment1.filename = template['FILENAME'] mail.add_attachment(attachment1) personalization = Personalization() personalization.add_substitution( Substitution("%first_name%", attendee.name.split()[0])) personalization.add_substitution(Substitution("%event_name%", event.name)) personalization.add_to(Email(attendee.email, attendee.name)) mail.add_personalization(personalization) try: sg.client.mail.send.post(request_body=mail.get()) return qr_data except Exception as e: raise e
def update(self, instance, validated_data): user = self.context['request'].user mail_subject = 'Покупка пакета' message = render_to_string('liqpay.html', { 'pocket': validated_data['user_pocket'], }) data = { 'to_emails': [ user.email, ], 'subject': mail_subject, 'html_content': message } pdfkit.from_string('TEST', 'smart_lead_pocket_paid.pdf') from_email = settings.DEFAULT_FROM_EMAIL message = Mail( from_email=from_email, **data, ) attachment = Attachment() with open('smart_lead_pocket_paid.pdf', 'rb') as f: attachment.file_content = base64.b64encode( f.read()).decode('utf-8') attachment.file_name = 'smart_lead_pocket_paid.pdf' message.add_attachment(attachment) sg = SendGridAPIClient(settings.SENDGRID_API_KEY) sg.send(message) # send_email_task.delay(**data) return super().update(instance, validated_data)
def sendMail(file_path, timesec, to_mail): message = Mail( from_email='*****@*****.**', to_emails=to_mail, subject='IGuard: Обнаружено Нарушение', html_content="<strong>Обнаружено нарушение в {}</strong>".format( time.strftime('%H:%M:%S, %d.%m.%Y', time.localtime(timesec)))) with open(file_path, 'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('image/jpg') attachment.file_name = FileName('ImageIGuard.jpg') message.attachment = attachment try: sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sg.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e)
def send_email(self): """Send email with transcription attached""" import base64 from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import (Mail, Attachment, Email, FileContent, FileName, FileType) text_file = "transcription.txt" mail = Mail( from_email=Email('*****@*****.**', "Chi from Damaris"), to_emails=self.email, subject="Your transcription from Damaris 🔥", plain_text_content="Thank you for using Damaris. Please find \ attached your transcribed file.") with open(text_file, 'rb') as f: data = f.read() encoded_text_file = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded_text_file) attachment.file_type = FileType("text/plain") attachment.file_name = FileName("transcription.txt") mail.attachment = attachment try: sg = SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY')) sg.send(mail) log.info('Email sent successfully!') except Exception as e: log.error("Could not send email {}".format(e))
def send_csv(self, file_name: str, data: bytes) -> bool: # create message message = Mail(self.from_email, self.to_email, self.subject, self.content) # create attachment file_type = "text/csv" encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType(file_type) attachment.file_name = file_name # attachment.disposition = Disposition('attachment') # attachment.content_id = ContentId('Example Content ID') message.attachment = attachment # This code is for testing purposes. # Allows to test the class above without sending mail. # If a value in "SENDGRID_TEST" environment equals to "True" this function will return boolean True # otherwise this function will return boolean False. if os.environ.get("SENDGRID_TEST") is not None: return os.environ.get("SENDGRID_TEST") == "True" # send try: sg = SendGridAPIClient(self.api_key) response = sg.send(message) logger.info( "Sent gedcom successfully with response code: {}".format( response.status_code)) return True except Exception as error: logger.exception(f"Failed to sent csv {error}") return False
def send_certificate_mail(name, email, event, cpf=None): template = templates['CERTIFICATE_EMITTED'] mail = Mail() mail.from_email = Email(template['FROM_EMAIL'], template['FROM_NAME']) mail.template_id = template['ID'] mail.add_category(Category(template['CATEGORY'])) attachment1 = Attachment() if isinstance(event, Event): event_place = event.place event_duration = event.formated_duration event_date = event.formated_dates event_min_percent = event.certificate_minimum_time else: event_place = event.event_day.event.place event_duration = event.event_day.event.formated_duration event_date = event.event_day.event.formated_dates event_min_percent = event.event_day.event.certificate_minimum_time cpf_text = _(', bearer of the registry number %(cpf)s,') % { 'cpf': cpf } if cpf else '' data = { 'name': name, 'event': event.name, 'cpf': cpf_text, 'event_date': event_date, 'event_place': event_place, 'event_duration': event_duration, 'event_min_percent': event_min_percent } certificate_data = event.certificate_model.generate_certificate(data) attachment1.content = base64.b64encode( certificate_data.read()).decode('ascii') attachment1.filename = template['FILENAME'] mail.add_attachment(attachment1) personalization = Personalization() personalization.add_substitution( Substitution("%first_name%", name.split()[0])) personalization.add_substitution(Substitution("%event_name%", event.name)) personalization.add_to(Email(email, name)) mail.add_personalization(personalization) try: response = sg.client.mail.send.post(request_body=mail.get()) return True except Exception as e: print(response.body) raise e
def digicam_sender(file_path: str, user_email: str, is_for_card: bool): """Sends the images to the users email""" # Sending is optional. if config.sendgrid_key is None: return html_content = """Hello! Attached are your images from the Digicam Print Channel. We hope you enjoy, and thank you for using our service!""" if is_for_card: html_content += f""" It looks like you ordered a business card. Did you know you can share these publicly via Digicard? If you're interested, visit https://card.wiilink24.com. Your order ID to link is {current_order.order_id}. Do not share this order ID with anyone else, or they will be able to use your card. """ html_content += """ The WiiLink24 Team""" msg = Mail( from_email="*****@*****.**", to_emails=user_email, subject="Here is your order!", html_content=html_content, ) with open(file_path, "rb") as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() if is_for_card: msg.attachment = Attachment( FileContent(encoded_file), FileName("business_card.jpeg"), FileType("application/jpeg"), Disposition("attachment"), ) else: msg.attachment = Attachment( FileContent(encoded_file), FileName("images.zip"), FileType("application/zip"), Disposition("attachment"), ) sg = SendGridAPIClient(config.sendgrid_key) sg.send(msg)
def test_attachment(self): from sendgrid.helpers.mail import (FileContent, FileType, FileName, Disposition, ContentId) a1 = Attachment(FileContent('Base64EncodedString'), FileName('example.pdf'), FileType('application/pdf'), Disposition('attachment'), ContentId('123')) a2 = Attachment('Base64EncodedString', 'example.pdf', 'application/pdf', 'attachment', '123') self.assertEqual(a1.file_content.get(), a2.file_content.get()) self.assertEqual(a1.file_name.get(), a2.file_name.get()) self.assertEqual(a1.file_type.get(), a2.file_type.get()) self.assertEqual(a1.disposition.get(), a2.disposition.get()) self.assertEqual(a1.content_id.get(), a2.content_id.get())
def get_attachment(file_path): """ Generates an attachment for sendgrid from the file in the path """ with open(file_path, 'rb') as f: data = f.read() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('application/xlsx') #can be changed to take type from extension of file, or maybe not mandatory :p attachment.file_name = FileName(file_path.split("/")[-1]) return attachment
def _prepare_sendgrid_data(self): self.ensure_one() s_mail = Mail() s_mail.set_from(Email(self.email_from)) s_mail.set_reply_to(Email(self.reply_to)) s_mail.add_custom_arg(CustomArg('odoo_id', self.message_id)) html = self.body_html or ' ' p = re.compile(r'<.*?>') # Remove HTML markers text_only = self.body_text or p.sub('', html.replace('<br/>', '\n')) s_mail.add_content(Content("text/plain", text_only)) s_mail.add_content(Content("text/html", html)) test_address = config.get('sendgrid_test_address') # TODO For now only one personalization (transactional e-mail) personalization = Personalization() personalization.set_subject(self.subject or ' ') if not test_address: if self.email_to: personalization.add_to(Email(self.email_to)) for recipient in self.recipient_ids: personalization.add_to(Email(recipient.email)) if self.email_cc: personalization.add_cc(Email(self.email_cc)) else: _logger.info('Sending email to test address {}'.format( test_address)) personalization.add_to(Email(test_address)) self.email_to = test_address if self.sendgrid_template_id: s_mail.set_template_id(self.sendgrid_template_id.remote_id) for substitution in self.substitution_ids: personalization.add_substitution(Substitution( substitution.key, substitution.value)) s_mail.add_personalization(personalization) for attachment in self.attachment_ids: s_attachment = Attachment() # Datas are not encoded properly for sendgrid s_attachment.set_content(base64.b64encode(base64.b64decode( attachment.datas))) s_attachment.set_filename(attachment.name) s_mail.add_attachment(s_attachment) return s_mail.get()
def _setup_email(_notify): mail = Mail() mail.from_email = Email(**_notify.from_email) for attachment in _notify.attachment_list(): _att = Attachment() _att.content = gb64(attachment) _att.filename = os.path.split(attachment)[-1] _att.disposition = "attachment" mail.add_attachment(_att) mail.add_content(Content("text/html", _notify.message)) return mail
def send_email(email, attachment): message = Mail( from_email='*****@*****.**', to_emails=email, subject='Your monthly invoice is ready...', html_content= '<strong>Please see the attached document.</strong><br>If you have any questions please call.<br><br>Matt Sewell<br>509.863.3607' ) with open(attachment, 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName(attachment), FileType('application/pdf'), Disposition('attachment')) message.attachment = attachedFile try: sg = SendGridAPIClient( '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' ) response = sg.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e.message)
def send_email_update(test_mode, overall_total_positive, sendgrid_api_key): from_email = settings.from_email to_email = settings.to_email subject_prefix = settings.subject_prefix subject = subject_prefix + str(overall_total_positive) if test_mode: subject = "TEST MODE: " + subject html_content = 'See <a href=\"' + settings.url + '\">complete dashboard</a> for more information.' message = Mail(from_email=from_email, to_emails=to_email, subject=subject, html_content=html_content) with open('screenshot.png', 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName('screenshot.png'), FileType('image/png'), Disposition('attachment')) message.attachment = attachedFile try: sg = SendGridAPIClient(sendgrid_api_key) sg.send(message) except Exception as e: print(e)
def go_sendgrid(email_sender, email_recipients, subject, my_tenant, mail_txt, local_file, SENDGRID_API_KEY): # Send mail message = Mail(from_email=Email(email_sender), to_emails=email_recipients, subject="{} {}".format(subject, my_tenant), plain_text_content=Content("text/plain", mail_txt)) with open(local_file, 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName(local_file), FileType('application/txt'), Disposition('attachment')) message.attachment = attachedFile try: sg = sendgrid.SendGridAPIClient(api_key=SENDGRID_API_KEY) response = sg.send(message) #print(response.status_code) #print(response.body) #print(response.headers) except Exception as e: print(e) finally: print("Email sent to:\n\t") for recipient in email_recipients: print(recipient[0]) print()
def posiljanje( recipient="*****@*****.**", subject=f"Mass HR dokumentacija {datum}", message="Sporočilo je bilo avtomatizirano s pomočjo Pythona.\nSestavil, uredil in poslal: Erik Jerman\n", file_path=f'{path}/csv_in_xlsx_datoteke_HR/{datum}.xlsx'): print(f"Sending {subject}") to_emails = [('*****@*****.**'), (recipient)] message = Mail(from_email='*****@*****.**', to_emails=to_emails, is_multiple=True, subject=subject, html_content=message) try: with open(file_path, 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName(f'{datum}.xlsx'), FileType('text/xlsx'), Disposition('attachment')) message.attachment = attachedFile except FileNotFoundError: print("Datoteka ne obstaja") sg = SendGridAPIClient('ENTER_YOUR_API_KEY_HERE') response = sg.send(message) print(response.status_code, response.body, response.headers)
def send_email(filename): import os import json from sendgrid import SendGridAPIClient from sendgrid.helpers.mail import Mail, Attachment, FileContent, FileName, FileType, Disposition to_emails = [('*****@*****.**', 'Suyoj Man Tamrakar'), ('*****@*****.**', 'Sanjay Man Tamrakar')] with open(filename, 'rb') as fd: encoded = base64.b64encode(fd.read()).decode() attachment = Attachment(FileContent(encoded), FileName(filename), FileType('text/csv'), Disposition('attachment')) print('Sendinggggggg') message = Mail( from_email=('*****@*****.**', 'Suyoj Man Tamrakar'), to_emails=to_emails, subject='Sentiment Survey Past Results', html_content= "<h2>These are the following details of the Sentiment Survey Past Results.</h2>" " <h2>STAY HOME STAY SAFE </h2> ") message.attachment = attachment try: sendgrid_client = SendGridAPIClient('') response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print('Errrrorrrrrrrrrr') print(e) return "Done"
def send_invoice_via_email(self, email): print("Sending email to {0}...".format(email)) message = Mail( from_email='*****@*****.**', to_emails=email, subject='New Order - Azen Store', html_content= '<strong>Your order has been received. Thanks for your purchase.</strong>' ) with open(os.path.join(settings.BASE_DIR, "invoice.pdf"), 'rb') as f: file_data = f.read() f.close() encoded_file = base64.b64encode(file_data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName('attachment.pdf'), FileType('application/pdf'), Disposition('attachment')) message.attachment = attachedFile sg = SendGridAPIClient(settings.SENDGRID_API_KEY) response = sg.send(message) print(response.status_code, response.body, response.headers)
def send(self, request): contents = self.contents.read().decode('utf-8') subscribers = Subscriber.objects.filter(confirmed=True) sg = SendGridAPIClient(settings.SENDGRID_API_KEY) for sub in subscribers: message = Mail( from_email=settings.FROM_EMAIL, to_emails=sub.email, subject=self.subject, html_content=contents + ( '<br><center>If you no longer wish to receive our newsletters, you can ' \ '<a href="{}/?email={}&conf_num={}">unsubscribe</a></center>.').format( request.build_absolute_uri('/delete/'), sub.email, sub.conf_num)) with open(self.attachment.path, 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment(FileContent(encoded_file), FileName(self.attachment.path), FileType('application/pdf'), Disposition('attachment')) message.attachment = attachedFile sg.send(message)
def sendMailWithPdf(email): #mailMsg = '{ # "subject": "subject", # "to": "*****@*****.**", # "from": "*****@*****.**", # "text": "Text", # "html": "", # "filename": "stats.xlsx", # "contentId": "stats" #}' #mailMsgJson = json.loads(mailMsg) message = Mail() message.to = To(email.data['to']) message.subject = Subject(email.data['subject'], p=0) message.from_email = From(email.data['from'], 'My Team Manager') message.template_id = TemplateId(email.data['templateId']) message.attachment = Attachment(FileContent(email.data['pdf']), FileName(email.data['filename']), FileType('application/pdf'), Disposition('attachment'), ContentId('Content ID 1')) message.content = Content(MimeType.text, email.data['text']) message.content = Content(MimeType.html, email.data['html']) sg = SendGridAPIClient(mailApiKey) response = sg.send(message) print(response.status_code) print(response.body) print(response.headers)
def digicam_sender(file, toemail, password): """Sends the images to the users email""" msg = Mail( from_email="*****@*****.**", to_emails=toemail, subject="Here is your photo!", html_content=f"The photo is in attachments! Enjoy! The password is {password}", ) with open(file, "rb") as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() msg.attachment = Attachment( FileContent(encoded_file), FileName("images.zip"), FileType("application/zip"), Disposition("attachment"), ) sg = SendGridAPIClient(config.sendgrid_key) response = sg.send(msg) print(response.status_code)
def send(self): message = Mail( from_email="*****@*****.**", to_emails=NOTIFICATION_RECIPIENTS, subject="TSLA Model Prediction from Tradium", html_content="<strong>predictions from Tradium</strong>", ) with open(get_abs_path(__file__, "../charts/tsla-prediction.png"), "rb") as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attachedFile = Attachment( FileContent(encoded_file), FileName("chart.png"), FileType("application/png"), Disposition("attachment"), ) message.attachment = attachedFile try: sg = SendGridAPIClient(SENDGRID_API_KEY) response = sg.send(message) print(f"Email sent status code: {response.status_code}") print(f"Email sent response body: {response.body}") except Exception as e: print(f"Printing exception: ", e)
def send_mail(from_user: tuple, to: list, subject: str, content: str, attachments=None) -> bool: if attachments is None: attachments = [] # Bail out if SendGrid API key has not been set if SENDGRID_API_KEY is None: return False # Create a Content object html_content = Content('text/html', content) # Create a Mail object mail = Mail(from_user, to, subject, html_content) # Add attachments, if any for attachment in attachments: try: mail.add_attachment( Attachment(attachment['data'], attachment['filename'], attachment['type'])) except KeyError: return False # Actually send the email try: SendGridAPIClient(SENDGRID_API_KEY).send(mail) except Exception as e: log('Exception occurred while sending mail!') log(e) return False return True
def send_email(subject="[Daily Briefing] This is a test", html="<p>Hello World</p>"): client = SendGridAPIClient(SENDGRID_API_KEY) #> <class 'sendgrid.sendgrid.SendGridAPIClient> print("CLIENT:", type(client)) print("SUBJECT:", subject) #print("HTML:", html) message = Mail( from_email=MY_EMAIL, to_emails=MY_EMAIL, subject=subject, html_content=html, ) with open('stock_info.xlsx', 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attached_file = Attachment( FileContent(encoded_file), FileName('stock_info.xlsx'), FileType('application/xlsx') #Disposition('attatchment') ) message.attachment = attached_file try: response = client.send(message) print("RESPONSE:", type(response)) #> <class 'python_http_client.client.Response'> print(response.status_code) #> 202 indicates SUCCESS return response except Exception as e: print("OOPS", e.message) return None
def add_attachment(self, data, file_name, file_type): encoded_file = base64.b64encode(data).decode() attached_file = Attachment(FileContent(encoded_file), FileName(file_name), FileType(file_type), Disposition('attachment')) self._message.attachment = attached_file
def send_messages(self, email_messages): sg = sendgrid.SendGridAPIClient(api_key=self.api_key) for email_message in email_messages: mail = Mail( from_email=email_message.from_email, to_emails=email_message.to, subject=email_message.subject, html_content=HtmlContent(email_message.body), ) for attachment in email_message.attachments: mail.add_attachment(Attachment( file_name=attachment[0], file_content=base64.b64encode(attachment[1]).decode(), file_type=attachment[2], )) try: response = sg.client.mail.send.post(request_body=mail.get()) if response.status_code // 100 != 2: error_message = ( f'Email "{email_message.subject}" was not sent to {email_message.to}. ' f'Status is {response.status_code}' ) if self.fail_silently: logger.error(error_message) else: raise SendGridBadStatusError(error_message) except HTTPError as error: if self.fail_silently: if type(error) == ForbiddenError: logger.exception(f'Email {email_message.subject} was not sent to {email_message.to} - {error.to_dict}') else: logger.exception(f'Email {email_message.subject} was not sent to {email_message.to} - {error}') else: raise
def send(): receiver = request.form['email-input'] pdf_path = './' + request.form['pdf'][1:] pdf_filename = pdf_path.split('static/media/')[-1] print(pdf_path) print(pdf_filename) message = Mail( from_email='*****@*****.**', to_emails=receiver, subject='Scribe: Your notes.', html_content= "<p>Scribe has sent you notes! View the attached PDF for audio transcription and visual aides.</p><br><br><p>Class Scribe</p>" ) with open(pdf_path, 'rb') as f: data = f.read() f.close() encoded_file = base64.b64encode(data).decode() attached_file = Attachment(FileContent(encoded_file), FileName(pdf_filename), FileType('application/pdf'), Disposition('attachment')) message.attachment = attached_file try: sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sg.send(message) except Exception as e: print(e) flash('Email sent! You may upload another video file now.') return redirect(url_for('upload'))
def send_email_notification(user, from_email, to_email, subject, body, attachment_url=None): if to_email: message = Mail( from_email=from_email, to_emails=to_email, subject=subject, html_content=body ) if attachment_url is not None: try: document = requests.get(attachment_url).content document = base64.b64encode(document) message.attachment = Attachment(FileContent(document.decode()), FileName('account-summary.pdf'), FileType('application/pdf'), Disposition('attachment') ) except Exception as e: raise e try: sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sg.send(message) status = True except Exception as e: logger.error("Email not sent !", exc_info=True) status = False
def send_styled_email(to_email): load_dotenv(dotenv_path='sendgrid.env') message = Mail( from_email='*****@*****.**', to_emails=to_email, subject='Here is your Stylized image!', html_content= '<strong>and easy to do anywhere, even with Python</strong>') file_path = 'output.jpg' with open(file_path, 'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('application/jpg') attachment.file_name = FileName('output.jpg') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.attachment = attachment try: sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e)
def sendMailWithAttachment(context): # print(context) html_version = 'email/email.html' message = Mail( from_email='*****@*****.**', to_emails=context['emails'], subject="Reg: Payment remittance for {} ${} {} Vendor : {}".format( context["clearing_date"], context["amount"], context["currency"], context["supplier"]), html_content=render_to_string(html_version, {'context': context})) with open(context['attachment'], 'rb') as f: data = f.read() f.close() print(data) encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('text/csv') attachment.file_name = FileName(context['attachment']) attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('REMITTANCE') message.add_attachment(attachment) try: sg = SendGridAPIClient( "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" ) response = sg.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e) # sendMailWithAttachment()
def send_email(email, file): with open(file, 'r') as f: data = f.readlines() today = data[-1].strip("\n").split(" ") yesterday = data[-2].strip("\n").split(" ") message = Mail(from_email="*****@*****.**", to_emails=["*****@*****.**"], subject='ExchangeTracer-{}'.format(today[0]), html_content=''' <strong>BOC info</strong>\n\n <i>Yesterday (full data): {}</i>\n\n <i>Opening: {}</i>\n\n <i>Max: {}</i>\n\n <i>Min: {}</i>\n\n <i>Closing: {}</i>\n\n\n\n <i>Today(Newest): {}</i>\n\n <i>Opening: {}</i>\n\n <i>Max: {}</i>\n\n <i>Min: {}</i>\n\n <i>Closing: {}</i>'''.format(yesterday[0], yesterday[1], yesterday[2], yesterday[3], yesterday[4], today[0], today[1], today[2], today[3], today[4])) with open(file, 'r') as f: string_csv = f.read() file_name = 'output-{}.txt'.format(today[0]) b64data = base64.b64encode(bytes(string_csv, 'utf-8')) attachment = Attachment() attachment.file_content = FileContent(str(b64data, 'utf-8')) attachment.file_name = FileName(file_name) message.attachment = attachment try: sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e) print('Done')
def send_email(subject="Unemployment Data", html="<p>Unemployment Data</p>", png=image_name): client = SendGridAPIClient( SENDGRID_API_KEY) #> <class 'sendgrid.sendgrid.SendGridAPIClient> message = Mail(from_email=MY_EMAIL, to_emails=MY_EMAIL, subject=subject, html_content=html) #Attaches the PNG we Generated Earlier Using Selenium with open(image_name, 'rb') as f: image = f.read() f.close() image_encoded = base64.b64encode(image).decode() attachment = Attachment() attachment.file_content = FileContent(image_encoded) attachment.file_type = FileType('image/png') attachment.file_name = FileName('unemployment_rate.png') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.attachment = attachment #Send Email try: response = client.send(message) print(response.status_code) print(response.body) return response except Exception as e: print("OOPS", e.message) return None
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 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 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 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 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 _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 _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 send_email_back(recipient, subject, attachments, text_content=None, html_content=None): from sendgrid.helpers import mail from sendgrid.helpers.mail import Attachment import premailer logging.info("sending mail to %s (%s/%s)", recipient, SENDGRID_API_KEY, SENDGRID_SENDER) to_email = mail.Email(recipient) from_email = mail.Email(SENDGRID_SENDER) message = mail.Mail() message.set_from(from_email) message.set_subject(subject) personalization = mail.Personalization() personalization.add_to(to_email) message.add_personalization(personalization) if not text_content and not html_content: message.add_content(mail.Content("text/plain", global_body)) if text_content: message.add_content(mail.Content("text/plain", text_content)) if html_content: message.add_content(mail.Content("text/html", html_content)) for att in attachments: data = att["data"] file_name = att["name"] if file_name.endswith(".htm") or file_name.endswith(".html"): stub_css = "https://%s.appspot.com/css/stub.css" % app_identity.get_application_id() data = re.sub( r'\"D:\\ssis\\SecureMail\\SecureMailTest\\MailItemImages\\BankB1\.gifstyle\.css
.*\"', '"%s"' % stub_css, data) logging.info("before transform(%s) %s", type(data), data) logging.info("using premailer for %s", file_name) data = data.decode("utf8") p = premailer.Premailer(data) data = p.transform().encode("utf8") logging.info("after transform(%s) %s", type(data), data) attachment = Attachment() attachment.set_content(base64.b64encode(data)) attachment.set_type(att["type"]) attachment.set_filename(att["name"]) attachment.set_disposition("attachment") attachment.set_content_id(att["name"]) message.add_attachment(attachment) data = json.dumps(message.get()) logging.debug("sending %s", data) headers = { "Authorization": 'Bearer {0}'.format(SENDGRID_API_KEY), "Content-Type": "application/json", "Accept": 'application/json' } response = urlfetch.fetch( url="https://api.sendgrid.com/v3/mail/send", payload=data, method=urlfetch.POST, headers=headers) if response.status_code > 299: logging.error("response %s(%s)", response.content, response.status_code) else: logging.info("response %s(%s)", response.content, response.status_code) if response.status_code > 299: raise Exception("Failed to call sendgrid API")
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) )