def send_email(success, service_name, error_status=None): if success: if dataent.db.get_value("Dropbox Settings", None, "send_email_for_successful_backup") == '0': return subject = "Backup Upload Successful" message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you that your backup was successfully uploaded to your %s account. So relax!</p> """ % service_name else: subject = "[Warning] Backup Upload Failed" message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s failed.</p> <p>Error message: <br> <pre><code>%s</code></pre> </p> <p>Please contact your system manager for more information.</p> """ % (service_name, error_status) if not dataent.db: dataent.connect() recipients = split_emails(dataent.db.get_value("Dropbox Settings", None, "send_notifications_to")) dataent.sendmail(recipients=recipients, subject=subject, message=message)
def __init__(self, sender='', recipients=(), subject='', alternative=0, reply_to=None, cc=(), bcc=(), email_account=None, expose_recipients=None): from email import charset as Charset Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') if isinstance(recipients, string_types): recipients = recipients.replace(';', ',').replace('\n', '') recipients = split_emails(recipients) # remove null recipients = filter(None, (strip(r) for r in recipients)) self.sender = sender self.reply_to = reply_to or sender self.recipients = recipients self.subject = subject self.expose_recipients = expose_recipients self.msg_root = MIMEMultipart('mixed') self.msg_alternative = MIMEMultipart('alternative') self.msg_root.attach(self.msg_alternative) self.cc = cc or [] self.bcc = bcc or [] self.html_set = False self.email_account = email_account or get_outgoing_email_account(sender=sender)
def get_bcc(doc, recipients=None, fetched_from_email_account=False): """Build a list of email addresses for BCC""" bcc = split_emails(doc.bcc) if bcc: exclude = [] exclude += [ d[0] for d in dataent.db.get_all( "User", ["email"], {"thread_notify": 0}, as_list=True) ] exclude += [(parse_addr(email)[1] or "").lower() for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parse_addr(doc.sender)[1]] if doc.reference_doctype and doc.reference_name: exclude += [ d[0] for d in dataent.db.get_all( "Email Unsubscribe", ["email"], { "reference_doctype": doc.reference_doctype, "reference_name": doc.reference_name }, as_list=True) ] bcc = filter_email_list(doc, bcc, exclude, is_bcc=True) return bcc
def validate_email(doc): """Validate Email Addresses of Recipients and CC""" if not (doc.communication_type == "Communication" and doc.communication_medium == "Email") or doc.flags.in_receive: return # validate recipients for email in split_emails(doc.recipients): validate_email_add(email, throw=True) # validate CC for email in split_emails(doc.cc): validate_email_add(email, throw=True) for email in split_emails(doc.bcc): validate_email_add(email, throw=True)
def get_recipients_cc_and_bcc(doc, recipients, cc, bcc, fetched_from_email_account=False): doc.all_email_addresses = [] doc.sent_email_addresses = [] doc.previous_email_sender = None if not recipients: recipients = get_recipients( doc, fetched_from_email_account=fetched_from_email_account) if not cc: cc = get_cc(doc, recipients, fetched_from_email_account=fetched_from_email_account) if not bcc: bcc = get_bcc(doc, recipients, fetched_from_email_account=fetched_from_email_account) if fetched_from_email_account: # email was already sent to the original recipient by the sender's email service original_recipients, recipients = recipients, [] # send email to the sender of the previous email in the thread which this email is a reply to #provides erratic results and can send external #if doc.previous_email_sender: # recipients.append(doc.previous_email_sender) # cc that was received in the email original_cc = split_emails(doc.cc) # don't cc to people who already received the mail from sender's email service cc = list(set(cc) - set(original_cc) - set(original_recipients)) remove_administrator_from_email_list(cc) original_bcc = split_emails(doc.bcc) bcc = list(set(bcc) - set(original_bcc) - set(original_recipients)) remove_administrator_from_email_list(bcc) remove_administrator_from_email_list(recipients) return recipients, cc, bcc
def validate_email_id(self): if self.notify_by_email: if self.recipients: email_list = split_emails(self.recipients.replace("\n", "")) from dataent.utils import validate_email_add for email in email_list: if not validate_email_add(email): dataent.throw( _("{0} is an invalid email address in 'Recipients'" ).format(email)) else: dataent.throw(_("'Recipients' not specified"))
def get_recipients(doc, fetched_from_email_account=False): """Build a list of email addresses for To""" # [EDGE CASE] doc.recipients can be None when an email is sent as BCC recipients = split_emails(doc.recipients) #if fetched_from_email_account and doc.in_reply_to: # add sender of previous reply #doc.previous_email_sender = dataent.db.get_value("Communication", doc.in_reply_to, "sender") #recipients.append(doc.previous_email_sender) if recipients: recipients = filter_email_list(doc, recipients, []) return recipients
def get_cc(doc, recipients=None, fetched_from_email_account=False): """Build a list of email addresses for CC""" # get a copy of CC list cc = split_emails(doc.cc) if doc.reference_doctype and doc.reference_name: if fetched_from_email_account: # if it is a fetched email, add follows to CC cc.append(get_owner_email(doc)) cc += get_assignees(doc) if getattr(doc, "send_me_a_copy", False) and doc.sender not in cc: cc.append(doc.sender) if cc: # exclude unfollows, recipients and unsubscribes exclude = [] #added to remove account check exclude += [ d[0] for d in dataent.db.get_all( "User", ["email"], {"thread_notify": 0}, as_list=True) ] exclude += [(parse_addr(email)[1] or "").lower() for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parse_addr(doc.sender)[1]] if doc.reference_doctype and doc.reference_name: exclude += [ d[0] for d in dataent.db.get_all( "Email Unsubscribe", ["email"], { "reference_doctype": doc.reference_doctype, "reference_name": doc.reference_name }, as_list=True) ] cc = filter_email_list(doc, cc, exclude, is_cc=True) return cc
def send_email(success, service_name, error_status=None): if success: if dataent.db.get_value("S3 Backup Settings", None, "send_email_for_successful_backup") == '0': return subject = "Backup Upload Successful" message = """<h3>Backup Uploaded Successfully! </h3><p>Hi there, this is just to inform you that your backup was successfully uploaded to your Amazon S3 bucket. So relax!</p> """ else: subject = "[Warning] Backup Upload Failed" message = """<h3>Backup Upload Failed! </h3><p>Oops, your automated backup to Amazon S3 failed. </p> <p>Error message: %s</p> <p>Please contact your system manager for more information.</p>""" % error_status if not dataent.db: dataent.connect() if dataent.db.get_value("S3 Backup Settings", None, "notification_email"): recipients = split_emails(dataent.db.get_value("S3 Backup Settings", None, "notification_email")) dataent.sendmail(recipients=recipients, subject=subject, message=message)
def send(recipients=None, sender=None, subject=None, message=None, text_content=None, reference_doctype=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, attachments=None, reply_to=None, cc=[], bcc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None, send_priority=1, communication=None, now=False, read_receipt=None, queue_separately=False, is_notification=False, add_unsubscribe_link=1, inline_images=None, header=None, print_letterhead=False): """Add email to sending queue (Email Queue) :param recipients: List of recipients. :param sender: Email sender. :param subject: Email subject. :param message: Email message. :param text_content: Text version of email message. :param reference_doctype: Reference DocType of caller document. :param reference_name: Reference name of caller document. :param send_priority: Priority for Email Queue, default 1. :param unsubscribe_method: URL method for unsubscribe. Default is `/api/method/dataent.email.queue.unsubscribe`. :param unsubscribe_params: additional params for unsubscribed links. default are name, doctype, email :param attachments: Attachments to be sent. :param reply_to: Reply to be captured here (default inbox) :param in_reply_to: Used to send the Message-Id of a received email back as In-Reply-To. :param send_after: Send this email after the given datetime. If value is in integer, then `send_after` will be the automatically set to no of days from current date. :param communication: Communication link to be set in Email Queue record :param now: Send immediately (don't send in the background) :param queue_separately: Queue each email separately :param is_notification: Marks email as notification so will not trigger notifications from system :param add_unsubscribe_link: Send unsubscribe link in the footer of the Email, default 1. :param inline_images: List of inline images as {"filename", "filecontent"}. All src properties will be replaced with random Content-Id :param header: Append header in email (boolean) """ if not unsubscribe_method: unsubscribe_method = "/api/method/dataent.email.queue.unsubscribe" if not recipients and not cc: return if isinstance(recipients, string_types): recipients = split_emails(recipients) if isinstance(cc, string_types): cc = split_emails(cc) if isinstance(bcc, string_types): bcc = split_emails(bcc) if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) email_account = get_outgoing_email_account(True, append_to=reference_doctype, sender=sender) if not sender or sender == "Administrator": sender = email_account.default_sender check_email_limit(recipients) if not text_content: try: text_content = html2text(message) except HTMLParser.HTMLParseError: text_content = "See html attachment" recipients = list(set(recipients)) cc = list(set(cc)) all_ids = recipients + cc unsubscribed = dataent.db.sql_list(''' SELECT distinct email from `tabEmail Unsubscribe` where email in %(all_ids)s and ( ( reference_doctype = %(reference_doctype)s and reference_name = %(reference_name)s ) or global_unsubscribe = 1 ) ''', { 'all_ids': all_ids, 'reference_doctype': reference_doctype, 'reference_name': reference_name, }) recipients = [r for r in recipients if r and r not in unsubscribed] if cc: cc = [r for r in cc if r and r not in unsubscribed] if not recipients and not cc: # Recipients may have been unsubscribed, exit quietly return email_text_context = text_content should_append_unsubscribe = (add_unsubscribe_link and reference_doctype and (unsubscribe_message or reference_doctype=="Newsletter") and add_unsubscribe_link==1) unsubscribe_link = None if should_append_unsubscribe: unsubscribe_link = get_unsubscribe_message(unsubscribe_message, expose_recipients) email_text_context += unsubscribe_link.text email_content = get_formatted_html(subject, message, email_account=email_account, header=header, unsubscribe_link=unsubscribe_link) # add to queue add(recipients, sender, subject, formatted=email_content, text_content=email_text_context, reference_doctype=reference_doctype, reference_name=reference_name, attachments=attachments, reply_to=reply_to, cc=cc, bcc=bcc, message_id=message_id, in_reply_to=in_reply_to, send_after=send_after, send_priority=send_priority, email_account=email_account, communication=communication, add_unsubscribe_link=add_unsubscribe_link, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, expose_recipients=expose_recipients, read_receipt=read_receipt, queue_separately=queue_separately, is_notification = is_notification, inline_images = inline_images, header=header, now=now, print_letterhead=print_letterhead)