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 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 _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 email_log_zip(self, sender, receiver1, receivers, subject_, body, file_path, attached=True): sender = '*****@*****.**' from_email = (sender, "") to_emails = [(receiver1, "")] if receivers != None: for i in receivers: to_emails.append((i, "")) subject = self.hostname + ':' + subject_ content_ = body content = Content("text/plain", content_) mail = Mail(from_email=from_email, to_emails=to_emails, subject=subject, plain_text_content=content) data = None if attached == True: 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/zip") attachment.file_name = FileName(file_path.split('/')[-1]) attachment.disposition = Disposition("attachment") attachment.content_id = ContentId("Example Content ID") mail.attachment = attachment response = self.sg.send(mail)
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 send_zip_to_user(self, file_name: str, data: bytes, to_email: str) -> bool: # create message message = Mail(self.from_email, to_email, send_zip_to_user_subject_he if self.language == "he" else send_zip_to_user_subject_en, html_content=send_zip_to_user_body_he if self.language == "he" else send_zip_to_user_body_en) # create attachment file_type = 'GED file' 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: logger.exception("Failed to sent gedcom") return False
def send_email_task_sendgrid(payload, headers, smtp_config): message = Mail( from_email=From(payload['from'], payload['fromname']), to_emails=payload['to'], subject=payload['subject'], html_content=payload["html"], ) if payload['attachments'] is not None: for attachment in payload['attachments']: with open(attachment, 'rb') as f: file_data = f.read() f.close() encoded = base64.b64encode(file_data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('application/pdf') attachment.file_name = FileName(payload['to']) attachment.disposition = Disposition('attachment') message.add_attachment(attachment) sendgrid_client = SendGridAPIClient(get_settings()['sendgrid_key']) logging.info( 'Sending an email regarding {} on behalf of {}'.format( payload["subject"], payload["from"] ) ) try: sendgrid_client.send(message) logging.info('Email sent successfully') except urllib.error.HTTPError as e: if e.code == 429: logging.warning("Sendgrid quota has exceeded") send_email_task_smtp.delay( payload=payload, headers=None, smtp_config=smtp_config ) elif e.code == 554: empty_attachments_send(sendgrid_client, message) else: logging.exception( "The following error has occurred with sendgrid-{}".format(str(e)) )
def add_picturs(self, message: Mail): """ Adding the pictures to the email. """ path = join(os.getcwd(), 'static', 'cypress', 'screenshots', '*', '*.png') files = glob(path) for file in files: with open(file, 'rb') as f: data = f.read() f.close() filename = file.split('/', )[-1] encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('image/png') attachment.file_name = FileName(filename) attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.add_attachment(attachment)
def add_videos(self, message: Mail): """ Adding videos to the email. """ files = glob(join(os.getcwd(), 'static', 'cypress', 'videos', '*.mp4')) for file in files: with open(file, 'rb') as f: data = f.read() f.close() filename = file.split('/', )[-1] encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('video/mp4') attachment.file_name = FileName( '_'.join(filename.split('.')[0:-1]) + '.mp4') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.add_attachment(attachment)
def send(self, message, envelope_from=None): assert message.send_to, "No recipients have been added" assert message.sender, ( "The message does not specify a sender and a default sender " "has not been configured") if message.has_bad_headers(): raise BadHeaderError if message.date is None: message.date = time.time() sgmessage = SGMail(from_email=message.sender, to_emails=', '.join( list(sanitize_addresses(message.recipients))), subject=message.subject, plain_text_content=message.body, html_content=message.html) if message.cc: for recipient in list(sanitize_addresses(message.cc)): sgmessage.add_cc(recipient) if message.bcc: for recipient in list(sanitize_addresses(message.bcc)): sgmessage.add_bcc(recipient) if message.attachments: for flask_attachment in message.attachments: attachment = Attachment() attachment.file_content = FileContent( base64.b64encode(flask_attachment.data).decode()) attachment.file_type = FileType(flask_attachment.content_type) attachment.file_name = FileName(flask_attachment.filename) attachment.disposition = Disposition( flask_attachment.disposition) sgmessage.add_attachment(attachment) sg = SendGridAPIClient(self.mail.api_key) response = sg.send(sgmessage) #sys.stderr.write("SendGrid status code: " + str(response.status_code) + "\n") #sys.stderr.write(str(response.body) + "\n") #sys.stderr.write("SendGrid response headers: " + str(response.headers) + "\n") if response.status_code >= 400: raise Exception("Failed to send e-mail message to SendGrid") email_dispatched.send(message, app=current_app._get_current_object())
def send_email(to_emails, from_email, subject, html_content=None, content=None, attachments=[], bcc=None): message = Mail(from_email=from_email, to_emails=to_emails, subject=subject, html_content=html_content, plain_text_content=content) if bcc is not None: message.bcc = Bcc(bcc) for data, filename, filetype in attachments: encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType(filetype) attachment.file_name = FileName(filename) attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.add_attachment(attachment) try: apikey = os.environ.get('SENDGRID_API_KEY') sg = SendGridAPIClient(apikey) response = sg.send(message) if response.status_code == 202: return True, None else: return False, "Failed: status code is {}".format( response.status_code) except Exception as e: return False, "Failed: {}".format(e)
def send(**kwargs): print('sending message') print(_green(kwargs)) result = True body = Content( "text/html", loader.render_to_string(kwargs.get('email_template'), kwargs.get('context'))) try: message = Mail(from_email=settings.SENGRID_SENDER_EMAIL, to_emails=kwargs.get('to_email'), subject=kwargs.get('subject'), html_content=body) file_path = kwargs.get('file_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/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) attachment.file_name = FileName(file_path.split('/')[1]) attachment.disposition = Disposition("attachment") attachment.content_id = ContentId("Excel Document file") message.add_attachment(attachment) sengrid_email = SendGridAPIClient(api_key=settings.SENDGRID_API_KEY) email_request = sengrid_email.send(message) print(_green('----------- sendgrid email response -----------')) print(email_request.status_code) print(email_request.body) print(email_request.headers) print(_green('----------- sendgrid email response -----------')) except Exception as e: result = False print(_red('Error sending email caused by : {}'.format(str(e)))) return result
def sendEmail(to, subject, filename, content, apikey): # Attachment print('Sending the doc to {}'.format(to)) message = Mail(from_email='*****@*****.**', to_emails=to, subject=subject, html_content='<p>Attached: {}</p>'.format(filename)) encoded = base64.b64encode(content).decode() attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType( 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ) attachment.file_name = FileName(filename) attachment.disposition = Disposition('attachment') message.attachment = attachment # sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) print('sending the email now using api key {}'.format(apikey)) sendgrid_client = SendGridAPIClient(apikey) response = sendgrid_client.send(message) print('Email sent with response code {}'.format(response.status_code))
def SendGrid(to, fromMail, subject, mailContent, html, attachments=[], inlineImages=[]): success = True desc = 'Status: ' to_emails = [ (emailAddr, emailAddr) for emailAddr in to ] message = Mail( from_email=fromMail.encode('utf8'), to_emails=to_emails, subject=subject.encode('utf8'), html_content=mailContent.encode('utf8')) for file_path in attachments: 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/pdf') attachment.file_name = FileName(os.path.basename(file_path)) attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.add_attachment(attachment) try: sg = SendGridAPIClient(utils.config.mailApiKey) response = sg.send(message) status_code = response.status_code desc += str(status_code) except Exception as e: desc += (str(e)) success = False return success, desc
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 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 email_lease_analysis(to_email, lease): formatted = LeaseFormatterService.format_lease_for_android(lease) subject = "RentSafe - " if len(formatted["Issues"]): subject += "{} issues(s) found".format(len(formatted["Issues"])) else: subject += "No issues found" content = EmailService._get_email_html(formatted) message = Mail( from_email="*****@*****.**", to_emails=to_email, subject=subject, html_content=content, ) with open(lease["LeaseDocumentPath"], "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/pdf") attachment.file_name = FileName(lease["LeaseDocumentName"]) attachment.disposition = Disposition("attachment") attachment.content_id = ContentId("") message.attachment = attachment try: sg = SendGridAPIClient(EmailService.SG_API_KEY) sg.send(message) return True except Exception as e: print(e) return False
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(acct): """ Sends email that attaches final csv results via sendgrid Params: none """ load_dotenv() date = datetime.date.today() SENDGRID_API_KEY = os.environ.get( "SENDGRID_API_KEY", "OOPS, please set env var called 'SENDGRID_API_KEY'") SENDGRID_TEMPLATE_ID = os.environ.get( "SENDGRID_TEMPLATE_ID", "OOPS, please set env var called 'SENDGRID_TEMPLATE_ID'") file_path = os.path.join(os.path.dirname(__file__), '..', "data", "final_list.csv") 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('text/csv') attachment.file_name = FileName('final_list.csv') attachment.disposition = Disposition('attachment') template_data = {"human_friendly_timestamp": date.strftime("%B %d, %Y")} client = SendGridAPIClient(SENDGRID_API_KEY) message = Mail(from_email=acct, to_emails=acct) message.template_id = SENDGRID_TEMPLATE_ID message.dynamic_template_data = template_data message.attachment = attachment try: client.send(message) except Exception as e: print("Oops, Sendgrid is down. Our bad.", e)
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 send_certificate_by_mail(name, to_email, file_path): message = Mail( from_email=('*****@*****.**','Rahul from Widhya'), to_emails=to_email, subject='Congratulations Are In Order From Widhya \u2764\uFE0F', html_content='<html><body>Hi,<br><br>Thank you for filling up the feedback form. Your feedback really matters. As promised, PFA your certificate for attending the workshop. It\'s great that you took the extra effort to be a part of the workshop as this workshop would really help you hone your fullstack skills. It\'s a great start and we hope to ensure that you continue going a long way in your career. As a result, we would send emails about openings and positions, depending on the areas of interest that you mentioned in the feedback form. Hope to meet you soon! And all the best for your future!<br><strong>Hope you choose Widhya for your upcoming career and learning experiences !</strong><br/> It was great knowing you!<br/><br/>Regards,<br/>Rahul Arulkumaran<br>Co-Founder & CEO - Widhya<br>+91-7893798125</body></html>') file_path = file_path filename = name.split(" ")[0] + "certificate.png" with open(file_path, 'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = sendgrid.helpers.mail.FileContent(encoded) attachment.file_type = sendgrid.helpers.mail.FileType('image/png') attachment.file_name = sendgrid.helpers.mail.FileName(filename) attachment.disposition = sendgrid.helpers.mail.Disposition('attachment') attachment.content_id = sendgrid.helpers.mail.ContentId('cert') message.attachment = attachment sendgrid_client = SendGridAPIClient(EMAIL_API_KEY) response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers)
def auto_credited_email(employee_object): # send email to employee for auto credited money to wallet ( not a cron job) date_time_string = datetime.datetime.now().strftime('%b %d, %Y (%a)') # get email attachment file_path = os.path.join( BASE_DIR, 'static/images/auto_credited.png') with open(file_path, '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('auto_credited.png') attachment.disposition = Disposition('inline') attachment.content_id = ContentId('auto_credited') get_daily_salary = employee_object.get_daily_salary() base_url = settings.BASE_URL if employee_object and employee_object.email: date_string = datetime.datetime.now().strftime('%b %-d, %Y') company_first_name = utilities.get_company_first_name(employee_object) response = send_email( "Rs." + str(get_daily_salary) + " salary credited for " + str(date_string), # subject "auto_credited", # template [str(employee_object.email)], # to_emails '*****@*****.**', # from_email attachment, str(employee_object.name) if employee_object.name else '', int(get_daily_salary), int(employee_object.balance), str(employee_object.unsubscribe_token), str(base_url), str(company_first_name) ) return response
def main(): print("Getting data from the sheet...") creds = None if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) service = build('sheets', 'v4', credentials=creds) # Call the Sheets API sheet = service.spreadsheets() result = sheet.values().get(spreadsheetId=SAMPLE_SPREADSHEET_ID, range=SAMPLE_RANGE_NAME).execute() values = result.get('values', []) if not values: print('No data found.') else: # We can access the sheet values here print("Data received.") for row in values: reg_id = row[0] name = row[1] + ' ' + row[2] email = row[3] designation = row[18] inst = row[19] org = row[21] print('Generating card for %s...' % (name)) qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=10, border=2, ) qr.add_data(reg_id) qr.make(fit=True) img = qr.make_image() # Resize the QR code to 150px X 150px img.thumbnail((221, 221), Image.ANTIALIAS) img.save(os.path.join('qrcodes', email + '.png')) template = Image.open('template.png') # Paste QR code template.paste(img, (205, 360)) # Write the name draw = ImageDraw.Draw(template) font = ImageFont.truetype(FONT, 55) x, y = font.getsize(name) draw.text(((321 - x / 2), (710 - y / 2)), name, font=font, fill='black') # Write the designation if designation != 'NA': draw = ImageDraw.Draw(template) font = ImageFont.truetype(FONT, 26) x, y = font.getsize(designation) draw.text(((321 - x / 2), (770 - y / 2)), designation, font=font, fill='black') if org != 'NA': draw = ImageDraw.Draw(template) font = ImageFont.truetype(FONT, 30) x, y = font.getsize(org) draw.text(((321 - x / 2), (810 - y / 2)), org, font=font, fill='black') elif inst != 'NA': draw = ImageDraw.Draw(template) font = ImageFont.truetype(FONT, 30) x, y = font.getsize(inst) draw.text(((321 - x / 2), (810 - y / 2)), inst, font=font, fill='black') # Add abstract element element = Image.open('element.png') element.thumbnail((59, 59), Image.ANTIALIAS) template.paste(element, (407, 557), element) # Save the card template.save(os.path.join('cards', email + '.png')) buffer = BytesIO() template.save(buffer, format="PNG") base64Value = base64.b64encode(buffer.getvalue()) message = Mail(from_email=(ORG_EMAIL, "GDG Gandhinagar"), subject="[ID Card] GDG Gandhinagar - DevFest 2019", to_emails=[(email, name)], html_content=Content("text/html", mail_temp(name, email))) attachment = Attachment() attachment.file_content = base64Value.decode() attachment.file_type = "image/png" attachment.file_name = "{}.png".format(name) attachment.disposition = "attachment" message.add_attachment(attachment) print("\tSending mail to " + name + "...") result = sg.client.mail.send.post(message.get()) if result.status_code == 200: print("\t\tMail sent.") else: print("\t\tMail not sent.") print('All cards sent successfully.')
average_percent[1], average_percent[2], average_percent[3], average_percent[4])) logger.info("Write to file complete. Now, sending the email.") message = Mail( from_email='*****@*****.**', to_emails='*****@*****.**', subject='Crypto Capture Report Update: ' + str(time.asctime()), html_content='PFA quality check report for database ' + DATABASE) with open(report, 'rb') as rep: data = rep.read() encoded_content = base64.b64encode(data).decode() attachment = Attachment() attachment.file_content = FileContent(encoded_content) attachment.file_type = FileType('application/txt') attachment.file_name = FileName('Report.txt') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId(time.asctime()) message.attachment = attachment try: sendgrid_client = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY')) response = sendgrid_client.send(message) logger.info("Email Sent. DONE!") except Exception as e: logger.error("Error Sending EMail!", exc_info=True)
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 file: attachment.content = base64.b64encode(file.read()).decode('utf-8') mail.add_attachment(attachment) _post_sendgrid_mail(mail.get())
def email(cases): for item in cases: subj = [] from_address = [] to = [] content = [] encoded_base = [] filename = [] mime_type = [] files = os.listdir(item) for file in files: file_path = os.path.join(item, file) if file.endswith(".json"): with open(file_path) as json_file: data = json.load(json_file) from_address.append(data['from_email']) to.append(data['to_email']) content.append(data['html_content']) subj.append(data['subject']) elif file.endswith(".pdf"): filename.append(file) filetype = 'application/pdf' mime_type.append(filetype) with open(file_path, 'rb') as f: data = f.read() f.close() encoded_base.append(base64.b64encode(data).decode()) elif file.endswith(".jpg"): filename.append(file) filetype = 'application/jpg' mime_type.append(filetype) with open(file_path, 'rb') as f: data = f.read() f.close() encoded_base.append(base64.b64encode(data).decode()) elif file.endswith(".png"): filetype = 'application/png' mime_type.append(filetype) filename.append(file) with open(file_path, 'rb') as f: data = f.read() f.close() encoded_base.append(base64.b64encode(data).decode()) message = Mail( from_email=str(from_address[0]), to_emails=str(to[0]), subject=str(subj[0]), html_content=(content[0]) ) if len(encoded_base) == 0: pass else: attachment = Attachment() attachment.file_content = FileContent(encoded_base[0]) # The Base64 encoded content of the attachment attachment.file_type = FileType(mime_type[0]) # The MIME type of the content you are attaching attachment.file_name = FileName(filename[0]) # The filename of the attachment attachment.disposition = Disposition('attachment') # Attachment or Inline (inside emails body) attachment.content_id = ContentId('Example Content ID') # Only used for Disposition(inline) 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.message) time.sleep(10)
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, 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 run( self, from_email: str = "*****@*****.**", to_emails: Union[str, Tuple[str, str], List[str], List[Tuple[str, str]]] = None, subject: str = None, html_content: str = None, category: Union[str, List[str]] = None, attachment_file_path: Union[str, Path] = None, sendgrid_secret: str = None, ) -> Response: """ Run message which sends an email via SendGrid. Args: - from_email (str): The email address of the sender; defaults to the one provided at initialization - to_emails (Union[str, Tuple[str, str], List[str], List[Tuple[str, str]]]): The email address of the recipient(s); defaults to the one provided at initialization. Refer to [SendGrid-Python](https://github.com/sendgrid/sendgrid-python) for specifics. - subject (str, optional): The subject of the email; defaults to the one provided at initialization - html_content (str): The html body of the email; defaults to the one provided at initialization - category (Union[str, List[str]], optional): The category/categories to use for the email; defaults to those provided at initialization - attachment_file_path (Union[str, Path], optional): The file path of the email attachment; defaults to the one provided at initialization - sendgrid_secret (str, optional): the name of the Prefect Secret which stores your SendGrid API key; defaults to `"SENDGRID_API_KEY"`; if not provided here, will use the value provided at initialization Returns: - python_http_client.client.Response: A [Python-HTTP-Client](https://github.com/sendgrid/python-http-client) object indicating the status of the response """ # Based on the SendGrid example use-case code here: # https://github.com/sendgrid/sendgrid-python/blob/aa39f715a061f0de993811faea0adb8223657d01/use_cases/attachment.md sendgrid_api_key = Secret(sendgrid_secret).get() import base64 import mimetypes from sendgrid.helpers.mail import ( Attachment, Category, Disposition, FileContent, FileName, FileType, Mail, ) from sendgrid import SendGridAPIClient message = Mail( from_email=from_email, to_emails=to_emails, subject=subject, html_content=html_content, ) if category: if not isinstance(category, list): category = [category] message.category = [Category(str(c)) for c in category] if attachment_file_path: with open(attachment_file_path, "rb") as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() guessed_type, content_encoding = mimetypes.guess_type( attachment_file_path, strict=True ) attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType(guessed_type) attachment.file_name = FileName(Path(attachment_file_path).name) attachment.disposition = Disposition("attachment") message.attachment = attachment sendgrid_client = SendGridAPIClient(sendgrid_api_key) response = sendgrid_client.send(message) return response
def output(self): mail = { 'html_body': '', 'text_body': '', 'mail_from': '', 'mail_to': '', 'mail_subject': '', } if 'from' not in self.output_config: raise NotConfiguredException( 'No sender (from) configured for email output!') if 'to' not in self.output_config: raise NotConfiguredException( 'No recipient (to) configured for email output!') if 'subject' not in self.output_config: raise NotConfiguredException( 'No subject configured for email output!') if 'body' not in self.output_config: raise NotConfiguredException( 'No body configured for email output!') for mail_type in ['html', 'text']: if mail_type in self.output_config['body']: mail_template = self.jinja_environment.from_string( self.output_config['body'][mail_type]) mail_template.name = mail_type mail['%s_body' % mail_type] = mail_template.render() if mail['html_body'] == '' and mail['text_body'] == '': raise NotConfiguredException( 'No HMTL or text email body configured for email output!') for tpl in ['from', 'to', 'subject']: mail_template = self.jinja_environment.from_string( self.output_config[tpl]) mail['mail_%s' % tpl] = mail_template.render() self.logger.debug('Canonicalizing email formats...') # Canonicalize the email formats for tpl in ['from', 'to']: parsed_emails = email.utils.getaddresses([mail['mail_%s' % tpl]]) if tpl == 'from' and len(parsed_emails) > 1: raise MultipleSendersException( 'Multiple senders in from field!') new_email = '' for e in parsed_emails: new_email += ', ' if new_email != '' else '' new_email += email.utils.formataddr(e) mail['mail_%s' % tpl] = new_email if 'expandGroupRecipients' in self.output_config and self.output_config[ 'expandGroupRecipients']: to_emails = email.utils.getaddresses([mail['mail_to']]) self.logger.debug('Starting expansion of group recipients...', extra={'to': to_emails}) service_account = self.output_config[ 'serviceAccountEmail'] if 'serviceAccountEmail' in self.output_config else None user_credentials = Credentials( self.get_token_for_scopes([ 'https://www.googleapis.com/auth/admin.directory.user.readonly' ], service_account=service_account)) group_credentials = Credentials( self.get_token_for_scopes([ 'https://www.googleapis.com/auth/cloud-identity.groups.readonly' ], service_account=service_account)) user_service = discovery.build('admin', 'directory_v1', credentials=user_credentials) group_service = discovery.build('cloudidentity', 'v1beta1', credentials=group_credentials) new_emails = [] for e in to_emails: request = group_service.groups().lookup() request.uri += "&groupKey.id=" + e[1] try: response = request.execute() except errors.HttpError as exc: if exc.resp.status == 404 or exc.resp.status == 403: self.logger.debug( 'Did not find group %s in Cloud Identity.' % (e[1]), extra={'response': exc.resp}) response = None else: raise exc if response and 'name' in response: m_request = group_service.groups().memberships().list( parent=response['name']) m_response = m_request.execute() if 'memberships' in m_response: # If this field doesn't exist, it's probably an empty group for membership in m_response['memberships']: new_emails.append( email.utils.formataddr( ('', membership['memberKey']['id']))) else: try: u_response = user_service.users().get( userKey=e[1]).execute() if u_response: new_emails.append(e[1]) except errors.HttpError as exc: if not 'ignoreNonexistentGroups' in self.output_config or not self.output_config[ 'ignoreNonexistentGroups']: raise GroupNotFoundException( 'Failed to find group %s in Cloud Identity!' % e[1]) elif 'ignoreNonexistentGroups' in self.output_config and isinstance( self.output_config['ignoreNonexistentGroups'], str ) and not e[1].endswith( self.output_config['ignoreNonexistentGroups']): new_emails.append(e[1]) else: self.logger.debug('Non-existent user %s skipped.' % (e[1]), extra={'response': exc.resp}) new_to = '' for e in new_emails: new_to += ', ' if new_to != '' else '' new_to += e mail['mail_to'] = new_to self.logger.debug('Finished expanding group recipients.', extra={'to': new_to}) if 'transports' not in self.output_config: raise NotConfiguredException( 'No transports configured for sending email.') embedded_images = {} if 'images' in self.output_config['body']: for image in self.output_config['body']['images']: image_template = self.jinja_environment.from_string(image) image_template.name = 'image' image_url = image_template.render() self.logger.debug('Fetching attached image...', extra={'image': image_url}) image_filename = None if image_url.startswith('gs://'): # Cloud Storage file image_filename, image_content = self._get_attachment( image_url) else: if os.path.exists(image_url): # Local file image_filename = os.path.basename(image_url) image_content = open(image_url, 'rb').read() else: self.logger.error('Could not find image attachment.', extra={'image': image_url}) if image_filename: embedded_images[image_filename] = image_content self.logger.debug('Attaching embedded image.', extra={ 'image': image_url, 'image_name': image_filename, 'size': len(image_content) }) sent_successfully = False for transport in self.output_config['transports']: try: if transport['type'] == 'smtp': if 'host' not in transport: raise NotConfiguredException( 'No host configured for SMTP transport.') port = int( transport['port']) if 'port' in transport else 25 self.logger.debug('Trying transport.', extra={ 'host': transport['host'], 'port': port }) server = None if 'verifyCertificate' in transport and transport[ 'verifyCertificate'] == False: context = ssl._create_unverified_context() else: context = ssl.create_default_context() if 'ssl' in transport and transport['ssl']: self.logger.debug('Using SSL connection for SMTP.') server = smtplib.SMTP_SSL(transport['host'], port, context=context) else: server = smtplib.SMTP(transport['host'], port) if 'starttls' in transport and transport['starttls']: self.logger.debug('Using STARTTLS for SMTP.') server.starttls(context=context) if 'user' in transport and 'password' in transport: self.logger.debug('Logging into SMTP server.') server.login(transport['user'], transport['password']) message = MIMEMultipart('alternative') message['Subject'] = mail['mail_subject'] message['From'] = mail['mail_from'] message['To'] = mail['mail_to'] if mail['text_body'] != '': text_part = MIMEText(mail['text_body'], 'plain') message.attach(text_part) if mail['html_body'] != '': html_part = MIMEText(mail['html_body'], 'html') message.attach(html_part) if 'attachments' in self.output_config['body']: for attachment in self.output_config['body'][ 'attachments']: attachment_template = self.jinja_environment.from_string( attachment) attachment_template.name = 'attachment' attachment_url = attachment_template.render() self.logger.debug( 'Fetching attachment...', extra={'attachment': attachment_url}) filename, content = self._get_attachment( attachment_url) file_part = MIMEBase('application', 'octet-stream') file_part.set_payload(content) encoders.encode_base64(file_part) file_part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % filename) self.logger.debug('Attached file.', extra={ 'attachment_filename': filename, 'attachment_size': len(content) }) message.attach(file_part) if len(embedded_images) > 0: for file_name, content in embedded_images.items(): image = MIMEImage(content) image.add_header('Content-ID', '<%s>' % file_name) image.add_header( 'Content-Disposition', 'inline; filename="%s"; size="%d";' % (file_name, len(content))) message.attach(image) self.logger.debug('Sending email thru SMTP.') server.sendmail(mail['mail_from'], mail['mail_to'], message.as_string()) server.quit() sent_successfully = True break elif transport['type'] == 'sendgrid': api_key = None if 'apiKey' in transport: api_key = transport['apiKey'] if os.getenv('SENDGRID_API_KEY'): api_key = os.getenv('SENDGRID_API_KEY') if not api_key: raise NotConfiguredException( 'No Sendgrid API key configured!') sg = sendgrid.SendGridAPIClient(api_key=api_key) from_email = sendgrid.Email(mail['mail_from']) to_email = sendgrid.To(mail['mail_to']) text_content = sendgrid.Content('text/plain', mail['text_body']) html_content = sendgrid.Content('text/html', mail['html_body']) sendgrid_mail = sendgrid.Mail(from_email, to_email, mail['mail_subject'], text_content) sendgrid_mail.add_content(html_content) if len(embedded_images) > 0: for file_name, content in embedded_images.items(): attachment = Attachment() attachment.file_content = base64.b64encode( content).decode() attachment.file_type = 'application/octet-stream' attachment.file_name = file_name attachment.disposition = 'inline' attachment.content_id = file_name sendgrid_mail.attachment = attachment if 'attachments' in self.output_config['body']: for attachment in self.output_config['body'][ 'attachments']: attachment_template = self.jinja_environment.from_string( attachment) attachment_template.name = 'attachment' attachment_url = attachment_template.render() self.logger.debug( 'Fetching attachment...', extra={'attachment': attachment_url}) filename, content = self._get_attachment( attachment_url) attachment = Attachment() attachment.file_content = base64.b64encode( content).decode() attachment.file_type = 'application/octet-stream' attachment.file_name = filename attachment.disposition = 'attachment' attachment.content_id = filename sendgrid_mail.attachment = attachment self.logger.debug('Attached file.', extra={ 'attachment_filename': filename, 'attachment_size': len(content) }) self.logger.debug('Sending email through SendGrid.') response = sg.client.mail.send.post( request_body=sendgrid_mail.get()) if response.status_code >= 200 and response.status_code <= 299: sent_successfully = True break else: self.logger.exception( 'Unknown transport type %s in configuration.' % transport['type']) except Exception: transport_sanitized = transport transport_sanitized.pop('apiKey', None) transport_sanitized.pop('user', None) transport_sanitized.pop('password', None) self.logger.exception( 'Error when attempting to use transport.', extra={ 'transport': transport_sanitized, 'mail': mail }) if not sent_successfully: self.logger.error( 'Unable to send email, none of the transports worked.') else: self.logger.info('Message sent!', extra={ 'from': mail['mail_from'], 'to': mail['mail_to'], 'subject': mail['mail_subject'] })
def send_pdf_email_using_SendGrid(sender, receiver, mail_subject, mail_content, pdf_attachment, txt_attachment=None, cc_email=None): # Where it was uploaded Path. file_path = pdf_attachment with open(file_path, 'rb') as f: data = f.read() # Encode contents of file as Base 64 encoded = base64.b64encode(data).decode() """Build PDF attachment""" attachment = Attachment() attachment.file_content = FileContent(encoded) attachment.file_type = FileType('application/pdf') attachment.file_name = FileName('your_quote.pdf') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') """ Add txt file """ if txt_attachment: file_path = txt_attachment with open(file_path, 'rb') as f: data = f.read() # Encode contents of file as Base 64 encoded = base64.b64encode(data).decode() """Build txt attachment""" attachment2 = Attachment() attachment2.file_content = FileContent(encoded) attachment2.file_type = FileType('text/html') attachment2.file_name = FileName('quote.txt') attachment2.disposition = Disposition('attachment') attachment2.content_id = ContentId('Text Example Content ID') message = Mail( from_email=sender, #to_emails = receiver, # Removed since it generates an extra email with SendGrid subject=mail_subject, html_content=mail_content) message.attachment = attachment if cc_email: cc = Email(cc_email) to = Email(receiver) p = Personalization() p.add_to(to) p.add_cc(cc) message.add_personalization(p) else: # no cc to = Email(receiver) p = Personalization() p.add_to(to) message.add_personalization(p) if txt_attachment: message.add_attachment(attachment2) 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.message) return
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 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, 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 email(self, emails, jobs, employer, cv_data, resume, user, email): for i in range(len(emails)): # Generate email message = Mail( from_email='*****@*****.**', to_emails=str(email), subject='Resume', html_content= '<p>To whoever this may concern,</p><p>Attached below is a copy of a resume & cover letter for a qualified candidate for your position at ' + str(employer[i]) + ' for the position of ' + str(jobs[i]) + '. We have contacted you through your listed email at ' + str(emails[i]) + '</p><p>Thank you for your consideration,</p><p>The Jabber Team</p>' ) # Generate Cover Letter cv = cvgen.cvgen(cv_data, jobs[i], employer[i], "Toronto, ON", 'data/' + user + 'CVE.pdf') cv.generate() # Generate Resume cv = cvgen.cvgen(resume, jobs[i], employer[i], "Toronto, ON", 'data/' + user + 'RE.pdf') cv.generate() # Attach Cover Letter file_path = user + 'CVE.pdf' with open('data/' + 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/pdf') attachment.file_name = FileName(user + 'CVE.pdf') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.attachment = attachment # Attach Resume file_path = user + 'RE.pdf' with open('data/' + 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/pdf') attachment.file_name = FileName(user + 'RE.pdf') attachment.disposition = Disposition('attachment') attachment.content_id = ContentId('Example Content ID') message.attachment = attachment # Send Email try: sendgrid_client = SendGridAPIClient(secret.SENDGRID_KEY) response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e.message) # Generate confirmation email to user message = Mail( from_email='*****@*****.**', to_emails=str(email), subject='Resume', html_content= '<p>Hello,</p><p>Our automated service has executed and applied you for the following roles:</p> ' + str(employer) + ' <br> ' + str(jobs) + '<p>Thank you for using our service,</p><p>The Jabber Team</p>') # Send confirmation email to user try: sendgrid_client = SendGridAPIClient(secret.SENDGRID_KEY) response = sendgrid_client.send(message) print(response.status_code) print(response.body) print(response.headers) except Exception as e: print(e.message)
file_path = 'C:\\Users\\dean\\Desktop\\email_collector\\mail_cases\\normal_with_attachment\\example.pdf' with open(file_path, 'rb') as f: data = f.read() f.close() encoded = base64.b64encode(data).decode() print(encoded) attachment = Attachment() attachment.file_content = FileContent( encoded) # The Base64 encoded content of the attachment attachment.file_type = FileType( 'application/pdf') # The MIME type of the content you are attaching attachment.file_name = FileName( 'test_filename.pdf') # The filename of the attachment attachment.disposition = Disposition( 'attachment') # Attachment or Inline (inside emails body) attachment.content_id = ContentId( 'Example Content ID') # Only used for Disposition(inline) 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.message) ''' # elif file.endswith(".pdf"): # with open(file_path) as pdf_file: