def sess(self): """get session""" if self._sess: return self._sess # check if email server specified if not getattr(self, 'server'): err_msg = _('Email Account not setup. Please create a new Email Account from Setup > Email > Email Account') frappe.msgprint(err_msg) raise frappe.OutgoingEmailError(err_msg) try: if self.use_ssl: if not self.port: self.port = 465 self._sess = smtplib.SMTP_SSL((self.server or ""), cint(self.port)) else: if self.use_tls and not self.port: self.port = 587 self._sess = smtplib.SMTP(cstr(self.server or ""), cint(self.port) or None) if not self._sess: err_msg = _('Could not connect to outgoing email server') frappe.msgprint(err_msg) raise frappe.OutgoingEmailError(err_msg) if self.use_tls: self._sess.ehlo() self._sess.starttls() self._sess.ehlo() if self.login and self.password: ret = self._sess.login(str(self.login or ""), str(self.password or "")) # check if logged correctly if ret[0]!=235: frappe.msgprint(ret[1]) raise frappe.OutgoingEmailError(ret[1]) return self._sess except smtplib.SMTPAuthenticationError as e: from frappe.email.doctype.email_account.email_account import EmailAccount EmailAccount.throw_invalid_credentials_exception() except _socket.error as e: # Invalid mail server -- due to refusing connection frappe.throw( _("Invalid Outgoing Mail Server or Port"), exc=frappe.ValidationError, title=_("Incorrect Configuration") ) except smtplib.SMTPException: frappe.msgprint(_('Unable to send emails at this time')) raise
def set_incoming_outgoing_accounts(doc): from frappe.email.doctype.email_account.email_account import EmailAccount incoming_email_account = EmailAccount.find_incoming( match_by_email=doc.sender, match_by_doctype=doc.reference_doctype) doc.incoming_email_account = incoming_email_account.email_id if incoming_email_account else None doc.outgoing_email_account = EmailAccount.find_outgoing( match_by_email=doc.sender, match_by_doctype=doc.reference_doctype) if doc.sent_or_received == "Sent": doc.db_set("email_account", doc.outgoing_email_account.name)
def test_get_email_account(self): existing_email_accounts = frappe.get_all("Email Account", fields=[ "name", "enable_outgoing", "default_outgoing", "append_to" ]) unset_details = { "enable_outgoing": 0, "default_outgoing": 0, "append_to": None } for email_account in existing_email_accounts: frappe.db.set_value('Email Account', email_account['name'], unset_details) # remove mail_server config so that [email protected] is not created mail_server = frappe.conf.get('mail_server') del frappe.conf['mail_server'] frappe.local.outgoing_email_account = {} frappe.local.outgoing_email_account = {} # lowest preference given to email account with default incoming enabled create_email_account(email_id="*****@*****.**", password="******", enable_outgoing=1, default_outgoing=1) self.assertEqual(EmailAccount.find_outgoing().email_id, "*****@*****.**") frappe.local.outgoing_email_account = {} # highest preference given to email account with append_to matching create_email_account(email_id="*****@*****.**", password="******", enable_outgoing=1, default_outgoing=1, append_to="Blog Post") self.assertEqual( EmailAccount.find_outgoing(match_by_doctype="Blog Post").email_id, "*****@*****.**") # add back the mail_server frappe.conf['mail_server'] = mail_server for email_account in existing_email_accounts: set_details = { "enable_outgoing": email_account['enable_outgoing'], "default_outgoing": email_account['default_outgoing'], "append_to": email_account['append_to'] } frappe.db.set_value('Email Account', email_account['name'], set_details)
def get_outgoing_email_account(self): if not hasattr(self, '_outgoing_email_account'): if self.email_account: self._outgoing_email_account = EmailAccount.find(self.email_account) else: self._outgoing_email_account = EmailAccount.find_outgoing( match_by_email=self.sender_mailid, match_by_doctype=self.reference_doctype ) if self.sent_or_received == "Sent" and self._outgoing_email_account: self.db_set("email_account", self._outgoing_email_account.name) return self._outgoing_email_account
def get_email_account(self): if self.email_account: return frappe.get_doc('Email Account', self.email_account) return EmailAccount.find_outgoing( match_by_email=self.sender, match_by_doctype=self.reference_doctype)
def get_incoming_email_account(self): if not hasattr(self, '_incoming_email_account'): self._incoming_email_account = EmailAccount.find_incoming( match_by_email=self.sender_mailid, match_by_doctype=self.reference_doctype ) return self._incoming_email_account
def get_outgoing_email_account(self): if self._email_account: return self._email_account self._email_account = EmailAccount.find_outgoing( match_by_doctype=self.reference_doctype, match_by_email=self._sender, _raise_error=True) return self._email_account
def get_formatted_html(subject, message, footer=None, print_html=None, email_account=None, header=None, unsubscribe_link=None, sender=None, with_container=False): email_account = email_account or EmailAccount.find_outgoing( match_by_email=sender) signature = None if "<!-- signature-included -->" not in message: signature = get_signature(email_account) rendered_email = frappe.get_template( "templates/emails/standard.html").render({ "brand_logo": get_brand_logo(email_account) if with_container or header else None, "with_container": with_container, "site_url": get_url(), "header": get_header(header), "content": message, "signature": signature, "footer": get_footer(email_account, footer), "title": subject, "print_html": print_html, "subject": subject }) html = scrub_urls(rendered_email) if unsubscribe_link: html = html.replace("<!--unsubscribe link here-->", unsubscribe_link.html) html = inline_style_in_html(html) return html
def _send(retry): from frappe.email.doctype.email_account.email_account import EmailAccount try: email_account = EmailAccount.find_outgoing(match_by_doctype=append_to) smtpserver = email_account.get_smtp_server() # validate is called in as_string email_body = email.as_string() smtpserver.sess.sendmail(email.sender, email.recipients + (email.cc or []), email_body) except smtplib.SMTPSenderRefused: frappe.throw(_("Invalid login or password"), title='Email Failed') raise except smtplib.SMTPRecipientsRefused: frappe.msgprint(_("Invalid recipient address"), title='Email Failed') raise except (smtplib.SMTPServerDisconnected, smtplib.SMTPAuthenticationError): if not retry: raise else: retry = retry - 1 _send(retry)
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, str): 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 \ EmailAccount.find_outgoing(match_by_email=sender, _raise_error=True)