def email_html_content(self): email_account = self.get_outgoing_email_account() return get_formatted_html(self.subject, self._message, header=self.header, email_account=email_account, unsubscribe_link=self.unsubscribe_message(), with_container=self.with_container)
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, 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)
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, 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, doctype='User', email_field='email', subject='[No Subject]', message='[No Content]', ref_doctype=None, ref_docname=None, add_unsubscribe_link=True, attachments=None, reply_to=None): def is_unsubscribed(rdata): if not rdata: return 1 return cint(rdata.unsubscribed) def check_bulk_limit(new_mails): this_month = frappe.db.sql( """select count(*) from `tabBulk Email` where month(creation)=month(%s)""" % nowdate())[0][0] # No limit for own email settings smtp_server = SMTPServer() if smtp_server.email_account and not getattr( smtp_server.email_account, "from_site_config", False) or frappe.flags.in_test: monthly_bulk_mail_limit = frappe.conf.get( 'monthly_bulk_mail_limit') or 500 if (this_month + len(recipients)) > monthly_bulk_mail_limit: throw( _("Bulk email limit {0} crossed").format( monthly_bulk_mail_limit), BulkLimitCrossedError) def update_message(formatted, doc, add_unsubscribe_link): updated = formatted if add_unsubscribe_link: unsubscribe_link = """<div style="padding: 7px; border-top: 1px solid #aaa; margin-top: 17px;"> <small><a href="%s/?%s"> Unsubscribe</a> from this list.</small></div>""" % ( get_url(), urllib.urlencode({ "cmd": "frappe.email.bulk.unsubscribe", "email": doc.get(email_field), "type": doctype, "email_field": email_field })) updated = updated.replace("<!--unsubscribe link here-->", unsubscribe_link) return updated if not recipients: recipients = [] 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(len(recipients)) formatted = get_formatted_html(subject, message) for r in filter(None, list(set(recipients))): rdata = frappe.db.sql("""select * from `tab%s` where %s=%s""" % (doctype, email_field, '%s'), (r, ), as_dict=1) doc = rdata and rdata[0] or {} if (not add_unsubscribe_link) or (not is_unsubscribed(doc)): # add to queue updated = update_message(formatted, doc, add_unsubscribe_link) try: text_content = html2text(updated) except HTMLParser.HTMLParseError: text_content = "[See html attachment]" add(r, sender, subject, updated, text_content, ref_doctype, ref_docname, attachments, reply_to)
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): """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 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 = recipients.split(",") 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 = [] for email in filter(None, list(set(recipients))): if email not in unsubscribed: email_content = formatted email_text_context = text_content if reference_doctype: unsubscribe_url = get_unsubcribed_url(reference_doctype, reference_name, email, unsubscribe_method, unsubscribe_params) # add to queue email_content = add_unsubscribe_link(email_content, email, reference_doctype, reference_name, unsubscribe_url, unsubscribe_message) email_text_context += "\n" + _("This email was sent to {0}. To unsubscribe click on this link: {1}").format(email, unsubscribe_url) add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, send_after)
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 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=(), message_id=None, send_after=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 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 = recipients.split(",") 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})] else: unsubscribed = [] for email in filter(None, list(set(recipients))): if email not in unsubscribed: email_content = formatted email_text_context = text_content if reference_doctype: unsubscribe_url = get_unsubcribed_url(reference_doctype, reference_name, email, unsubscribe_method, unsubscribe_params) # add to queue email_content = add_unsubscribe_link(email_content, email, reference_doctype, reference_name, unsubscribe_url, unsubscribe_message) email_text_context += "\n" + _("This email was sent to {0}. To unsubscribe click on this link: {1}").format(email, unsubscribe_url) add(email, sender, subject, email_content, email_text_context, reference_doctype, reference_name, attachments, reply_to, cc, message_id, send_after)