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)
def validate_email(doc): """Validate Email Addresses of Recipients and CC""" if not (doc.communication_type=="Communication" and doc.communication_medium == "Email"): 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)
def validate(self): if self.get("__islocal"): if self.reference_doctype and self.reference_name: self.status = "Linked" else: self.status = "Open" # validate recipients for email in split_emails(self.recipients): validate_email_add(email, throw=True) # validate CC for email in split_emails(self.cc): validate_email_add(email, throw=True)
def send_email(success, service_name, error_status=None): if success: if frappe.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 frappe.db: frappe.connect() recipients = split_emails(frappe.db.get_value("Dropbox Settings", None, "send_notifications_to")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
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 doc.reference_doctype and doc.reference_name: if fetched_from_email_account: bcc.append(get_owner_email(doc)) bcc += get_assignees(doc) if bcc: exclude = [] exclude += [d[0] for d in frappe.db.get_all("User", ["name"], {"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 frappe.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 send_email(success, service_name, error_status=None): if success: if frappe.db.get_value("Tortal LMS System Settings", None, "send_email_for_successful_upload") == '0': return subject = "Tortal FTP Upload Successful" message = """<h3>Backup Uploaded Successfully! on %s</h3><p>Hi there, this is just to inform you that your files were successfully uploaded to Tortal system. So relax!</p> """ % ( datetime.now()) else: subject = "[Warning] Tortal FTP Upload Failed" message = """<h3>Upload Failed! on %s </h3><p>Oops, your automated upload to Tortal system failed. </p> <p>Error message: %s</p> <p>Please contact your system manager for more information.</p>""" % (datetime.now(), error_status) if not frappe.db: frappe.connect() if frappe.db.get_value("Tortal LMS System Settings", None, "notification_email"): recipients = split_emails( frappe.db.get_value("Tortal LMS System Settings", None, "notification_email")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def send_email(success, service_name, error_status=None): if success: if frappe.db.get_value("S3 Backup Settings", None, "send_email_for_successful_backup") == '0': return subject = _("Backup Upload Successful") message = """<h3>{0} </h3><p>{1}</p> """.format(_("Backup Uploaded Successfully!"), \ _("Hi there, this is just to inform you that your backup was successfully uploaded to your Amazon S3 bucket. So relax!")) else: subject = _("[Warning] Backup Upload Failed") message = """<h3>{0} </h3><p>{1}</p> <p></p>{2} <p>{3}</p>""".format(_("Backup Upload Failed!"), \ _("Oops, your automated backup to Amazon S3 failed."), _("Error message: %s"), \ _("Please contact your system manager for more information.")) % error_status print(message) return if not frappe.db: frappe.connect() recipients = split_emails( frappe.db.get_value("S3 Backup Settings", None, "notify_email")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def get_recipients_and_cc(doc, recipients, cc, 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 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 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)) return recipients, cc
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 frappe.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 frappe.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 send_email(success, service_name, error_status=None): if success: if frappe.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 frappe.db: frappe.connect() if frappe.db.get_value("S3 Backup Settings", None, "notification_email"): recipients = split_emails( frappe.db.get_value("S3 Backup Settings", None, "notification_email")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def send_email(success, service_name, error_status=None): if success: if frappe.db.get_value("Nextcloud 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 frappe.db: frappe.connect() recipients = split_emails( frappe.db.get_value("Nextcloud Settings", None, "send_notifications_to")) frappe.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 __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_recipients_and_cc(self, recipients, cc, fetched_from_email_account=False): self.all_email_addresses = [] if not recipients: recipients = self.get_recipients() if not cc: cc = self.get_cc( 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, [] # cc that was received in the email original_cc = split_emails(self.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)) return recipients, cc
def send_email(success, service_name, error_status=None): if success: if frappe.db.get_value("Dropbox Settings", None, "send_email_for_successful_backup") == '0': return subject = _("Backup Upload Successful") message ="""<h3>{0}</h3><p>{1}</p> """.format(_("Backup Uploaded Successfully"), \ _("Hi there, this is just to inform you that your backup was successfully uploaded to your %s account. So relax!")) % service_name else: subject = _("[Warning] Backup Upload Failed") message ="""<h3>{0}</h3><p>{1}</p> <p>{2} <br> <pre><code>%s</code></pre> </p> <p>{3}</p> """.format(_("Backup Upload Failed"), _("Oops, your automated backup to %s failed."), _("Error message:"), \ _("Please contact your system manager for more information.")) % (service_name, error_status) if not frappe.db: frappe.connect() recipients = split_emails( frappe.db.get_value("Dropbox Settings", None, "send_notifications_to")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def __init__(self, sender='', recipients=(), subject='', alternative=0, reply_to=None, cc=(), email_account=None): from email.mime.multipart import MIMEMultipart from email import Charset Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') if isinstance(recipients, basestring): 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.msg_root = MIMEMultipart('mixed') self.msg_multipart = MIMEMultipart('alternative') self.msg_root.attach(self.msg_multipart) self.cc = cc or [] self.html_set = False self.email_account = email_account
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 = frappe.db.get_value( "Communication", doc.in_reply_to, "sender") recipients.append(doc.previous_email_sender) if recipients: # exclude email accounts exclude = [ d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True) ] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] recipients = filter_email_list(doc, recipients, exclude) return recipients
def get_recipients_and_cc(doc, recipients, cc, 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 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 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)) return recipients, cc
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 frappe.db.get_all("User", ["name"], {"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 frappe.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 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 email accounts, unfollows, recipients and unsubscribes exclude = [d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True)] exclude += [d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0]] exclude += [d[0] for d in frappe.db.get_all("User", ["name"], {"thread_notify": 0}, as_list=True)] exclude += [(parseaddr(email)[1] or "").lower() for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parseaddr(doc.sender)[1]] if doc.reference_doctype and doc.reference_name: exclude += [d[0] for d in frappe.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 get_cc(self, recipients=None, fetched_from_email_account=False): """Build a list of email addresses for CC""" # get a copy of CC list cc = split_emails(self.cc) if self.reference_doctype and self.reference_name: if not cc or fetched_from_email_account: # if CC is not mentioned from the UI or is a fetched email, add follows to CC cc.append(self.get_owner_email()) cc += self.get_assignees() cc += self.get_starrers() if fetched_from_email_account and self.in_reply_to: # add sender of previous reply cc.append( frappe.db.get_value("Communication", self.in_reply_to, "sender")) if cc: # this will be used to eventually find email addresses that aren't sent to self.all_email_addresses.extend(cc) # exclude email accounts, unfollows, recipients and unsubscribes exclude = [ d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True) ] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] exclude += [ d[0] for d in frappe.db.get_all( "User", ["name"], {"thread_notify": 0}, as_list=True) ] exclude += [parseaddr(email)[1] for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parseaddr(self.sender)[1]] if self.reference_doctype and self.reference_name: exclude += [ d[0] for d in frappe.db.get_all( "Email Unsubscribe", ["email"], { "reference_doctype": self.reference_doctype, "reference_name": self.reference_name }, as_list=True) ] cc = self.filter_email_list(cc, exclude) if getattr(self, "send_me_a_copy", False) and self.sender not in cc: self.all_email_addresses.append(self.sender) cc.append(self.sender) return cc
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 frappe.utils import validate_email_add for email in email_list: if not validate_email_add(email): frappe.throw(_("{0} is an invalid email address in 'Recipients'").format(email)) else: frappe.throw(_("'Recipients' not specified"))
def get_cc(self, recipients=None, fetched_from_email_account=False): """Build a list of email addresses for CC""" # get a copy of CC list cc = split_emails(self.cc) if self.reference_doctype and self.reference_name: if not cc or fetched_from_email_account: # if CC is not mentioned from the UI or is a fetched email, add follows to CC cc.append(self.get_owner_email()) cc += self.get_assignees() cc += self.get_starrers() if fetched_from_email_account and self.in_reply_to: # add sender of previous reply cc.append(frappe.db.get_value("Communication", self.in_reply_to, "sender")) if cc: # this will be used to eventually find email addresses that aren't sent to self.all_email_addresses.extend(cc) # exclude email accounts, unfollows, recipients and unsubscribes exclude = [ d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True) ] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] exclude += [d[0] for d in frappe.db.get_all("User", ["name"], {"thread_notify": 0}, as_list=True)] exclude += [parseaddr(email)[1] for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parseaddr(self.sender)[1]] if self.reference_doctype and self.reference_name: exclude += [ d[0] for d in frappe.db.get_all( "Email Unsubscribe", ["email"], {"reference_doctype": self.reference_doctype, "reference_name": self.reference_name}, as_list=True, ) ] cc = self.filter_email_list(cc, exclude) if getattr(self, "send_me_a_copy", False) and self.sender not in cc: self.all_email_addresses.append(self.sender) cc.append(self.sender) return cc
def get_cc(self, recipients=None, fetched_from_email_account=False): """Build a list of email addresses for CC""" # get a copy of CC list cc = split_emails(self.cc) if self.reference_doctype and self.reference_name: if fetched_from_email_account: # if it is a fetched email, add follows to CC cc.append(self.get_owner_email()) cc += self.get_assignees() cc += self.get_starrers() if cc: # exclude email accounts, unfollows, recipients and unsubscribes exclude = [ d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True) ] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] exclude += [ d[0] for d in frappe.db.get_all( "User", ["name"], {"thread_notify": 0}, as_list=True) ] exclude += [(parseaddr(email)[1] or "").lower() for email in recipients] if fetched_from_email_account: # exclude sender when pulling email exclude += [parseaddr(self.sender)[1]] if self.reference_doctype and self.reference_name: exclude += [ d[0] for d in frappe.db.get_all( "Email Unsubscribe", ["email"], { "reference_doctype": self.reference_doctype, "reference_name": self.reference_name }, as_list=True) ] cc = self.filter_email_list(cc, exclude, is_cc=True) if getattr(self, "send_me_a_copy", False) and self.sender not in cc: self.all_email_addresses.append((parseaddr(self.sender)[1] or "").lower()) cc.append(self.sender) return cc
def validate_notification_email_id(doc): if doc.notification_email_address: email_list = split_emails(doc.notification_email_address.replace("\n", "")) from frappe.utils import validate_email_add for email in email_list: if not validate_email_add(email): throw(_("{0} is an invalid email address in 'Notification \ Email Address'").format(email)) else: frappe.throw(_("'Notification Email Addresses' not specified for recurring %s") \ % doc.doctype)
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 = frappe.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_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 _get_emails_list(emails=None, exclude_displayname=False): """Returns list of emails from given email string. * Removes duplicate mailids * Removes display name from email address if exclude_displayname is True """ emails = split_emails(emails) if isinstance(emails, str) else (emails or []) if exclude_displayname: return [ email.lower() for email in set([parse_addr(email)[1] for email in emails]) if email ] return [email.lower() for email in set(emails) if email]
def get_recipients(self): """Build a list of email addresses for To""" # [EDGE CASE] self.recipients can be None when an email is sent as BCC recipients = split_emails(self.recipients) if recipients: # exclude email accounts exclude = [d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True)] exclude += [d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0]] recipients = self.filter_email_list(recipients, exclude) return recipients
def send_email(success, service_name, error_status=None): if success: 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 frappe.db: frappe.connect() if frappe.db.get_value("S3 Backup Settings", None, "notification_email"): recipients = split_emails(frappe.db.get_value("S3 Backup Settings", None, "notification_email")) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def send_email(success, machine, error_status=None): if not cint(machine.send_notification): return if success: subject = "Attendance Import Successful - {0}".format(machine.name) message ="""<h3>Attendance Imported Successfully</h3><p>Hi there, this is just to inform you that your attendance have been successfully imported.</p>""" else: subject = "[Warning] Attendance Import Failed - {0}".format(machine.name) message ="""<h3>Attendance Import has Failed</h3><p>Oops, your automated attendance Import has Failed</p> <p>Error message: <br> <pre><code>%s</code></pre> </p> <p>Please contact your system manager for more information.</p> """ % (error_status) recipients = split_emails(machine.notification_mail_address) frappe.sendmail(recipients=recipients, subject=subject, message=message)
def send_email(status, transactiontype, error_status=None, pos_transaction_date=None, log_name=None, attachment=None): if not frappe.db: frappe.connect() if status == 'Successful': subject = """Ekleel data imported Successful for %s dated %s as on """ % ( transactiontype, pos_transaction_date) + ( datetime.now()).strftime("%Y%m%d") message = """<h3>Pixel-point POS data imported successfully for --<i> %s </i></h3><p>Hi there,<br> This is just to inform you that your POS data for %s was successfully imported to ERPNext account. So relax!</p>""" % ( transactiontype, transactiontype) elif status == 'Failed': subject = """[Warning] Ekleel data import failed for %s dated %s as on """ % ( transactiontype, pos_transaction_date) + ( datetime.now()).strftime("%Y%m%d") message = """<h3>Pixel-point POS data import failed for --<i> %s </i></h3><p>Oops, your automated import to ERPNext failed for - %s</p><p><h4>Error message: </h4><br><pre><code>%s</code></pre></p><p><h4>Detailed sync log at :%s </h4><br><hr><h2>Instructions</h2><ol type="1"><li>Download the attached file</li><li>Correct the file content with respect to above mentioned error message</li><li>Retry the data import at %s</li></ol> """ % ( transactiontype, transactiontype, error_status, get_link_to_form('Pixel Point Sync Log', log_name, 'LogLink'), get_link_to_form('Retry data import', 'Retry data import', 'Retry')) elif status == 'File not found failure': subject = """[Warning] Ekleel data import failed for %s dated %s as on """ % ( transactiontype, pos_transaction_date) + ( datetime.now()).strftime("%Y%m%d") message = """<h3>Pixel-point POS data import failed for --<i> %s </i></h3><p>Oops, your automated import to ERPNext failed for - %s</p><p><h4>Error message: </h4><br><pre><code>%s</code></pre></p><p><h4>Detailed sync log at :%s </h4><br><hr><h2>Instructions</h2><ol type="1"><li>It appears no file was kept by Pixel point POS</li><li>Check with pixel point POS and get the required file</li><li>Retry the data import at %s</li></ol> """ % ( transactiontype, transactiontype, error_status, get_link_to_form('Pixel Point Sync Log', log_name, 'Log link'), get_link_to_form('Retry data import', 'Retry data import', 'Retry')) recipients = split_emails( frappe.db.get_value("PixelPoint Settings", None, "send_notifications_to")) frappe.sendmail(recipients=recipients, subject=subject, message=message, attachments=attachment, now=True)
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 = frappe.db.get_value("Communication", doc.in_reply_to, "sender") recipients.append(doc.previous_email_sender) if recipients: # exclude email accounts exclude = [d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True)] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] recipients = filter_email_list(doc, recipients, exclude) return recipients
def get_recipients_and_cc(self, recipients, cc, fetched_from_email_account=False): self.all_email_addresses = [] if not recipients: recipients = self.get_recipients() if not cc: cc = self.get_cc(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, [] # cc that was received in the email original_cc = split_emails(self.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)) return recipients, cc
def send_email(name, email, phone, is_guest, vendor_list): vendor_offer_doc = frappe.get_single('Vendor Carousel and Email template') raw_subject = vendor_offer_doc.subject or '' raw_email = vendor_offer_doc.email or '' if is_guest == True: is_guest = 'No, user is a guest' else: is_guest = 'Yes, user is an existing member' raw_vendor_list = json.loads(vendor_list) count = 0 for vendor in raw_vendor_list: subject = raw_subject.replace('{sender_name}', name or "").replace( '{sender_email}', email or "").replace('{sender_phone}', phone or "").replace( '{sender_is_guest}', is_guest or "").replace('{vendor_name}', vendor or "") email = raw_email.replace('{sender_name}', name or "").replace( '{sender_email}', email or "").replace('{sender_phone}', phone or "").replace( '{sender_is_guest}', is_guest or "").replace('{vendor_name}', vendor or "") vendor_email = frappe.db.sql( """select contact_email_for_offers from `tabSupplier` where name=%s""", vendor, as_dict=1) outgoing_email_id = frappe.get_doc("Email Account", {"default_outgoing": "1"}) if outgoing_email_id: recipients = split_emails( frappe.db.get_value("Supplier", filters={"name": vendor}, fieldname="contact_email_for_offers")) frappe.sendmail(recipients=recipients, message=email, subject=subject) recipients = None subject = None email = None count = count + 1 return count
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", policy=policy.SMTPUTF8) self.msg_alternative = MIMEMultipart("alternative", policy=policy.SMTPUTF8) 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 __init__(self, sender="", recipients=(), subject="", alternative=0, reply_to=None, cc=()): from email.mime.multipart import MIMEMultipart from email import Charset Charset.add_charset("utf-8", Charset.QP, Charset.QP, "utf-8") if isinstance(recipients, basestring): 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.msg_root = MIMEMultipart("mixed") self.msg_multipart = MIMEMultipart("alternative") self.msg_root.attach(self.msg_multipart) self.cc = cc or [] self.html_set = False
def get_recipients(self): """Build a list of email addresses for To""" # [EDGE CASE] self.recipients can be None when an email is sent as BCC recipients = split_emails(self.recipients) if recipients: # this will be used to eventually find email addresses that aren't sent to self.all_email_addresses.extend(recipients) # exclude email accounts exclude = [ d[0] for d in frappe.db.get_all("Email Account", ["email_id"], {"enable_incoming": 1}, as_list=True) ] exclude += [ d[0] for d in frappe.db.get_all("Email Account", ["login_id"], {"enable_incoming": 1}, as_list=True) if d[0] ] recipients = self.filter_email_list(recipients, exclude) return recipients
def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, attachments=None, reply_to=None, cc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None, send_priority=1, communication=None, now=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 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/frappe.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) """ if not unsubscribe_method: unsubscribe_method = "/api/method/frappe.email.queue.unsubscribe" if not recipients and not cc: return if isinstance(recipients, basestring): recipients = split_emails(recipients) if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) email_account = get_outgoing_email_account(True, append_to=reference_doctype) if not sender or sender == "Administrator": sender = email_account.default_sender check_email_limit(recipients) formatted = get_formatted_html(subject, message, email_account=email_account) try: text_content = html2text(formatted) except HTMLParser.HTMLParseError: text_content = "See html attachment" if reference_doctype and reference_name: unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"reference_doctype": reference_doctype, "reference_name": reference_name})] unsubscribed += [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1})] else: unsubscribed = [] recipients = [r for r in list(set(recipients)) if r and r not in unsubscribed] email_content = formatted email_text_context = text_content if reference_doctype and (unsubscribe_message or reference_doctype=="Newsletter"): unsubscribe_link = get_unsubscribe_message(unsubscribe_message, expose_recipients) email_content = email_content.replace("<!--unsubscribe link here-->", unsubscribe_link.html) email_text_context += unsubscribe_link.text # add to queue email_queue = add(recipients, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, in_reply_to, send_after, send_priority, email_account=email_account, communication=communication, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, expose_recipients=expose_recipients) if now: send_one(email_queue.name, now=True)
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=[], 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): """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/frappe.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/frappe.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(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" if reference_doctype and reference_name: unsubscribed = [ d.email for d in frappe.db.get_all( "Email Unsubscribe", "email", { "reference_doctype": reference_doctype, "reference_name": reference_name }) ] unsubscribed += [ d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1}) ] else: unsubscribed = [] recipients = [ r for r in list(set(recipients)) if r and r not in unsubscribed ] 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, 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)
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/frappe.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/frappe.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" if reference_doctype and reference_name: unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"reference_doctype": reference_doctype, "reference_name": reference_name})] unsubscribed += [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1})] else: unsubscribed = [] recipients = [r for r in list(set(recipients)) if r and r not in unsubscribed] if cc: cc = [r for r in list(set(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)
def get_recipients(doctype, email_field): if not frappe.db: frappe.connect() return split_emails(frappe.db.get_value(doctype, None, email_field))
def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, attachments=None, reply_to=None, cc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None, send_priority=1, communication=None, now=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 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/frappe.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) """ if not unsubscribe_method: unsubscribe_method = "/api/method/frappe.email.queue.unsubscribe" if not recipients and not cc: return if isinstance(recipients, basestring): recipients = split_emails(recipients) if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) email_account = get_outgoing_email_account(True, append_to=reference_doctype) if not sender or sender == "Administrator": sender = email_account.default_sender check_email_limit(recipients) formatted = get_formatted_html(subject, message, email_account=email_account) try: text_content = html2text(formatted) except HTMLParser.HTMLParseError: text_content = "See html attachment" if reference_doctype and reference_name: unsubscribed = [ d.email for d in frappe.db.get_all( "Email Unsubscribe", "email", { "reference_doctype": reference_doctype, "reference_name": reference_name }) ] unsubscribed += [ d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1}) ] else: unsubscribed = [] recipients = [ r for r in list(set(recipients)) if r and r not in unsubscribed ] email_content = formatted email_text_context = text_content if reference_doctype and (unsubscribe_message or reference_doctype == "Newsletter"): unsubscribe_link = get_unsubscribe_message(unsubscribe_message, expose_recipients) email_content = email_content.replace("<!--unsubscribe link here-->", unsubscribe_link.html) email_text_context += unsubscribe_link.text # add to queue email_queue = add(recipients, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, in_reply_to, send_after, send_priority, email_account=email_account, communication=communication, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, expose_recipients=expose_recipients) if now: send_one(email_queue.name, now=True)
def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, attachments=None, reply_to=None, cc=(), show_as_cc=(), message_id=None, in_reply_to=None, send_after=None, expose_recipients=False, bulk_priority=1, communication=None): """Add email to sending queue (Bulk Email) :param recipients: List of recipients. :param sender: Email sender. :param subject: Email subject. :param message: Email message. :param reference_doctype: Reference DocType of caller document. :param reference_name: Reference name of caller document. :param bulk_priority: Priority for bulk email, default 1. :param unsubscribe_method: URL method for unsubscribe. Default is `/api/method/frappe.email.bulk.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 message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email. :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 Bulk Email record """ if not unsubscribe_method: unsubscribe_method = "/api/method/frappe.email.bulk.unsubscribe" if not recipients: return if isinstance(recipients, basestring): recipients = split_emails(recipients) if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) email_account = get_outgoing_email_account(True, append_to=reference_doctype) if not sender or sender == "Administrator": sender = email_account.default_sender check_bulk_limit(recipients) formatted = get_formatted_html(subject, message, email_account=email_account) try: text_content = html2text(formatted) except HTMLParser.HTMLParseError: text_content = "See html attachment" if reference_doctype and reference_name: unsubscribed = [ d.email for d in frappe.db.get_all( "Email Unsubscribe", "email", { "reference_doctype": reference_doctype, "reference_name": reference_name }) ] unsubscribed += [ d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1}) ] else: unsubscribed = [] recipients = [ r for r in list(set(recipients)) if r and r not in unsubscribed ] for email in recipients: email_content = formatted email_text_context = text_content if reference_doctype: unsubscribe_link = get_unsubscribe_link( reference_doctype=reference_doctype, reference_name=reference_name, email=email, recipients=recipients, expose_recipients=expose_recipients, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message, show_as_cc=show_as_cc) email_content = email_content.replace( "<!--unsubscribe link here-->", unsubscribe_link.html) email_text_context += unsubscribe_link.text # show as cc cc_message = "" if email in show_as_cc: cc_message = _("This email was sent to you as CC") email_content = email_content.replace("<!-- cc message -->", cc_message) email_text_context = cc_message + "\n" + email_text_context # add to queue add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, in_reply_to, send_after, bulk_priority, email_account=email_account, communication=communication)
def send(recipients=None, sender=None, subject=None, message=None, reference_doctype=None, reference_name=None, unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None, attachments=None, reply_to=None, cc=(), message_id=None, send_after=None, expose_recipients=False, bulk_priority=1): """Add email to sending queue (Bulk Email) :param recipients: List of recipients. :param sender: Email sender. :param subject: Email subject. :param message: Email message. :param reference_doctype: Reference DocType of caller document. :param reference_name: Reference name of caller document. :param bulk_priority: Priority for bulk email, default 1. :param unsubscribe_method: URL method for unsubscribe. Default is `/api/method/frappe.email.bulk.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 message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email. :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. """ if not unsubscribe_method: unsubscribe_method = "/api/method/frappe.email.bulk.unsubscribe" if not recipients: return if isinstance(recipients, basestring): recipients = split_emails(recipients) if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) if not sender or sender == "Administrator": email_account = get_outgoing_email_account() sender = email_account.get("sender") or email_account.email_id check_bulk_limit(recipients) formatted = get_formatted_html(subject, message) try: text_content = html2text(formatted) except HTMLParser.HTMLParseError: text_content = "See html attachment" if reference_doctype and reference_name: unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"reference_doctype": reference_doctype, "reference_name": reference_name})] unsubscribed += [d.email for d in frappe.db.get_all("Email Unsubscribe", "email", {"global_unsubscribe": 1})] else: unsubscribed = [] recipients = [r for r in list(set(recipients)) if r and r not in unsubscribed] for email in recipients: email_content = formatted email_text_context = text_content if reference_doctype: unsubscribe_link = get_unsubscribe_link( reference_doctype=reference_doctype, reference_name=reference_name, email=email, recipients=recipients, expose_recipients=expose_recipients, unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message ) email_content = email_content.replace("<!--unsubscribe link here-->", unsubscribe_link.html) email_text_context += unsubscribe_link.text # add to queue add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, send_after, bulk_priority)