def _send(self, email_message: EmailMessage): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET # Specific email_message.extra_headers["Reply-To"] = sanitize_address( email_message.from_email, encoding) email_message.from_email = settings.EMAIL_SENDER for key, value in json.loads(settings.EMAIL_EXTRA_HEADERS).items(): email_message.extra_headers[key] = value # /Specific from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] message = email_message.message() try: self.connection.sendmail(from_email, recipients, message.as_bytes(linesep="\r\n")) except SMTPException: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending. :param email_message: EmaiMesage instance :type email_message: django.core.mail.message.EmailMessage """ if not email_message.recipients(): return False #:Extended parameters for SMTP extended = getattr(email_message, "extended", {}) from_address = sanitize_address( extended.get('return_path', None) or email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] #: Python standard email.message.Message mail_obj = email_message.message() return self.send_message_object(from_address, recipients, mail_obj, **extended)
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] try: account = Account(primary_smtp_address=from_email, credentials=self.credentials, autodiscover=True, access_type=DELEGATE) exchange_message = Message(account=account, subject=email_message.subject, body=email_message.body, to_recipients=[ Mailbox(email_address=recipient) for recipient in recipients ]) exchange_message.send() except Exception: if not self.fail_silently: raise return False return True
def _send(self, email_message): "Overrides default _send from smtp backend and redirect all mail to one recipient" if not email_message.recipients(): return False if not hasattr(settings, 'STAGING_EMAIL_FORWARD'): raise ImproperlyConfigured('Add STAGING_EMAIL_FORWARD to settings') from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in [settings.STAGING_EMAIL_FORWARD]] if email_message.bcc: email_message.subject += u' BCC: [' email_message.subject += u','.join(email_message.bcc) email_message.subject += u']' try: self.connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: r = requests.\ post(self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": ", ".join(recipients), "from": from_email, }, files={ "message": StringIO(email_message.message().as_string()), } ) except: if not self.fail_silently: raise return False if r.status_code != 200: if not self.fail_silently: raise MailgunAPIError(r) return False # Send a signal with the response mailgun_message_queued.send(sender=None, weak=False, response=r) return True
def send(self, request): prefix = request.POST.get('prefix', 'postbox') form = PostboxForm(request.POST, prefix=prefix) if form.is_valid(): data = form.cleaned_data del data['captcha'] model = Mail(**data) model.save() address = sanitize_address((model.name, model.email,), 'utf-8') msg = EmailMultiAlternatives( '[%s] %s' % (settings.EMAIL_SUBJECT_PREFIX, model.subject or 'Сообщение'), get_template('mail/plain/contact.html').render({'model': model}), sanitize_address((settings.EMAIL_SUBJECT_PREFIX, settings.DEFAULT_FROM_EMAIL,), 'utf-8'), settings.EMAIL_TO if hasattr(settings, 'EMAIL_TO') else [settings.SERVER_EMAIL], headers={ 'From': address, 'Sender': address, }, reply_to=[address], ) msg.attach_alternative(get_template('mail/html/contact.html').render({'model': model}), 'text/html') if msg.send() > 0: messages.success(request, '<b>%s!</b>' % _('Сообщение отправлено')) else: messages.error(request, '<b>%s!</b>' % _('Сообщение не отправлено')) else: if settings.DEBUG: for field in form.errors: errors = '<b>%s</b>' % field for error in form.errors[field]: errors += '<br>- %s' % error messages.error(request, errors) else: messages.error(request, '<b>%s!</b>' % _('Ошибка заполнения формы'))
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: r = requests.post(self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": ", ".join(recipients), "from": from_email, }, files={ "message": StringIO(unicode(email_message.message().as_string())), } ) except: if not self.fail_silently: raise return False logger.debug("Mailgun response: %s" % r.text) if r.status_code != 200: if not self.fail_silently: raise MailgunAPIError(r) return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: print email_message.message().body r = requests.\ post(self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": str(recipients), "from": from_email, }, files={ "message": ('message', email_message.message().body), } ) print r.text except Exception, e: print "EXCEPTION SENDING MAIL", e if not self.fail_silently: raise return False
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: r = requests.post( self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": ", ".join(recipients), "from": from_email, }, files={ "message": StringIO( email_message.message().as_bytes(linesep="\r\n")) } ) except requests.exceptions.RequestException as e: if not self.fail_silently: six.raise_from(smtplib.SMTPException("Could not send mail"), e) return False if r.status_code != 200: if not self.fail_silently: raise smtplib.SMTPException("Mailgun server returned code {" "}".format(r.status_code)) return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET email_message.from_email = fix_address(email_message.from_email) from_email = sanitize_address(email_message.from_email, encoding) from_email = self.return_path or from_email recipients = [sanitize_address(addr, encoding) for addr in email_message.recipients()] try: message = email_message.message() self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n'), rcpt_options=self.rcpt_options) except smtplib.SMTPRecipientsRefused as e: handle_smtp_error(e) logger.exception(e) return False except smtplib.SMTPException as e: logger.exception(e) return False except Exception as e: logger.exception(e) return False return True
def send(self, email_message): if not email_message.recipients(): log.error("Error adding recipients to email.") return 0 if not self.client: log.error("Error initializing Mandrill client.") return 0 if not self.merge_content or not self.email_template or not self.merge_tags: log.error("Error sending context to MandrillEmailBackend.") return 0 encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] message = email_message.message() num_sent = 0 for to in recipients: errors = [] try: message = { 'from_email': from_email, 'from_name': self.from_name, 'merge_language': 'mailchimp', 'merge_vars': [{ 'rcpt': to, 'vars': self._set_mandrill_vars() }], 'subject': email_message.subject, 'tags': [self.email_tag], 'to': [{ 'email': to, 'name': to, 'type': 'to' }], } result = self.client.messages.send_template( template_name=self.email_template, template_content=[], message=message) log.info(result) except mandrill.Error as e: log.exception( f"Error sending Mandrill email: {email_message.subject}, {to}, {e}" ) errors.append(e) except Exception as e: log.exception("Error with MandrillEmailBackend: {e}") errors.append(e) else: num_sent += 1 if errors and not self.fail_silently: raise errors[0] return num_sent
def _send(self, email_message): """A helper method that does the actual sending + DKIM signing.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [ sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] message_string = email_message.message().as_string() signature = '' if self.dkim_selector and self.dkim_domain and self.dkim_private_key: signature = dkim.sign(message_string, self.dkim_selector, self.dkim_domain, self.dkim_private_key) try: self.connection.sendmail( from_email, recipients, signature + message_string.as_bytes(linesep='\r\n')) except: if not self.fail_silently: raise return False return True
def _send(self, message): if not message.recipients(): return False self.sender = sanitize_address(message.from_email, message.encoding) recipients_list = [sanitize_address(addr, message.encoding) for addr in message.recipients()] from email.utils import parseaddr self.recipients = [{'email': e, 'name': n} for n, e in [parseaddr(r) for r in recipients_list]] self.msg_dict = self._build_standard_message_dict(message) if getattr(message, 'alternative_subtype', None): if message.alternative_subtype == 'mandrill': self._build_advanced_message_dict(message) if message.alternatives: self._add_alternatives(message) djrill_it = requests.post(self.api_action, data=json.dumps({ 'key': self.api_key, 'message': self.msg_dict })) if djrill_it.status_code != 200: if not self.fail_silently: raise Exception(djrill_it.json()['message']) return False return True
def _send(self, email_message): """Sends the message. This is a copy of the original `_send` method with only a difference: we filter the recipient list and only keep the whitelisted ones. """ encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) message = email_message.message() # Here is the bit where we filter the recipients # This is very sensitive code, so treat carefully! recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() if addr in settings.EMAIL_WHITELIST] if not recipients: return False try: self.connection.sendmail( from_email, recipients, message.as_bytes(linesep='\r\n')) except smtplib.SMTPException: if not self.fail_silently: raise return False return True
def send_messages(self, emails): """ Sends one or more EmailMessage objects and returns the number of email messages sent. """ if not emails: return num_sent = 0 for email in emails: if not email.recipients(): continue from_email = sanitize_address(email.from_email, email.encoding) recipients = [sanitize_address(addr, email.encoding) for addr in email.recipients()] for recipient in recipients: payload = { 'key': settings.NEWSLETTER2GO_API_KEY, 'to': recipient, 'from': from_email, 'subject': email.subject, 'linktracking': int(getattr(settings, 'NEWSLETTER2GO_LINKTRACKING', True)), 'opentracking': int(getattr(settings, 'NEWSLETTER2GO_OPENTRACKING', True)), } payload['html' if email.content_subtype == 'html' else 'text'] = email.body response = requests.post(self.n2g_api_endpoint, payload) response_json = response.json() if response_json.get('status') == 200: num_sent += 1 return num_sent
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = email_message.from_email if hasattr(message, 'sanitize_address'): from_email = message.sanitize_address(email_message.from_email, email_message.encoding) if hasattr(settings, 'TEST_EMAIL_TO'): email_message.to = settings.TEST_EMAIL_TO else: email_message.to = dict(getattr(settings, 'ADMINS', ())).values() email_message.cc = getattr(settings, 'TEST_EMAIL_CC', []) email_message.bcc = getattr(settings, 'TEST_EMAIL_BCC', []) if hasattr(message, 'sanitize_address'): recipients = [message.sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] else: recipients = email_message.recipients() try: self.connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False if set(email_message.recipients()).issubset(admin_emails()): # Skip on admin notifications return super(DevEmailBackend, self)._send(email_message) from_email = sanitize_address(email_message.from_email, email_message.encoding) try: recipients = [sanitize_address(addr, email_message.encoding) for addr in settings.DEV_EMAIL_LIST] except: raise ImproperlyConfigured("You must set a DEV_EMAIL_LIST setting to use the Dev Email Backend.") message = email_message.message() charset = message.get_charset().get_output_charset() if message.get_charset() else "utf-8" try: self.connection.sendmail(from_email, recipients, force_bytes(message.as_string(), charset)) except: if not self.fail_silently: raise return False return True
def _build_standart_message_dict(self, message): msg_dict = dict() if len(message.subject): msg_dict['Subject'] = message.subject if len(message.body): msg_dict['Text-part'] = message.body sender = sanitize_address(message.from_email, message.encoding) from_name, from_email = parseaddr(sender) msg_dict['FromEmail'] = from_email msg_dict['FromName'] = from_name msg_dict['To'] = ', '.join([sanitize_address(addr, message.encoding) for addr in message.to]) if message.cc: msg_dict['Cc'] = ', '.join([sanitize_address(addr, message.encoding) for addr in message.cc]) if message.bcc: msg_dict['Bcc'] = ', '.join([sanitize_address(addr, message.encoding) for addr in message.bcc]) if message.reply_to: reply_to = [sanitize_address(addr, message.encoding) for addr in message.reply_to] msg_dict['Headers'] = {'Reply-To': ', '.join(reply_to)} if message.extra_headers: msg_dict['Headers'] = msg_dict.get('Headers', {}) msg_dict['Headers'].update(message.extra_headers) return msg_dict
def _build_standard_message_dict(self, message): """Create a Mandrill send message struct from a Django EmailMessage. Builds the standard dict that Django's send_mail and send_mass_mail use by default. Standard text email messages sent through Django will still work through Mandrill. Raises ValueError for any standard EmailMessage features that cannot be accurately communicated to Mandrill (e.g., prohibited headers). """ sender = sanitize_address(message.from_email, message.encoding) from_name, from_email = parseaddr(sender) recipients = [parseaddr(sanitize_address(addr, message.encoding)) for addr in message.recipients()] to_list = [{"email": to_email, "name": to_name} for (to_name, to_email) in recipients] msg_dict = { "text": message.body, "subject": message.subject, "from_email": from_email, "to": to_list } if from_name: msg_dict["from_name"] = from_name if message.extra_headers: for k in message.extra_headers.keys(): if k != "Reply-To" and not k.startswith("X-"): raise ValueError("Invalid message header '%s' - Mandrill " "only allows Reply-To and X-* headers" % k) msg_dict["headers"] = message.extra_headers return msg_dict
def _build_standart_message_dict(self, message): msg_dict = dict() if len(message.subject): msg_dict['Subject'] = message.subject if len(message.body): msg_dict['Text-part'] = message.body sender = sanitize_address(message.from_email, message.encoding) from_name, from_email = parseaddr(sender) msg_dict['FromEmail'] = from_email msg_dict['FromName'] = from_name # msg_dict['To'] = message.to msg_dict['Recipients'] = self._parse_recipients(message, message.to) if hasattr(message, 'cc'): msg_dict['Cc'] = message.cc if hasattr(message, 'bcc'): msg_dict['bcc'] = message.bcc if hasattr(message, 'reply_to'): reply_to = [sanitize_address(addr, message.encoding) for addr in message.reply_to] msg_dict['Headers'] = {'Reply-To': ', '.join(reply_to)} if message.extra_headers: msg_dict['Headers'] = msg_dict.get('Headers', {}) msg_dict['Headers'].update(message.extra_headers) return msg_dict
def _send(self, email_message): """A helper method that does the actual sending + DKIM signing.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] message_string = email_message.message().as_string() signature = '' if self.dkim_selector and self.dkim_domain and self.dkim_private_key: signature = dkim.sign(message_string, self.dkim_selector, self.dkim_domain, self.dkim_private_key) try: self.connection.sendmail(from_email, recipients, signature+message_string.as_bytes(linesep='\r\n')) except: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [ sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] try: r = requests.\ post(self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": ", ".join(recipients), "from": from_email, }, files={ "message": StringIO(email_message.message().as_string()), } ) except: if not self.fail_silently: raise return False if r.status_code != 200: if not self.fail_silently: raise MailgunAPIError(r) return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] message = email_message.message().as_string() try: r = requests.post( self._api_url + "messages.mime", auth=("api", self._access_key), data={ "to": ", ".join(recipients), "from": from_email, }, files={ "message": six.StringIO(message) }, timeout=self._connection_timeout ) except: if not self.fail_silently: raise return False if r.status_code != 200: if not self.fail_silently: raise MailgunAPIError(r) return False return True
def send_messages(self, emails): """ Sends one or more EmailMessage objects and returns the number of email messages sent. """ if not emails: return num_sent = 0 for email in emails: if not email.recipients(): continue from_email = sanitize_address(email.from_email, email.encoding) recipients = [sanitize_address(addr, email.encoding) for addr in email.recipients()] logger.debug('Sending email from {0} to {1}'.format(from_email, ', '.join(recipients))) for recipient in recipients: payload = { 'key': settings.NEWSLETTER2GO_API_KEY, 'to': recipient, 'from': from_email, 'subject': email.subject, } payload['html' if email.content_subtype == 'html' else 'text'] = email.body response = requests.post(self.n2g_api_endpoint, payload) response_json = response.json() if response_json.get('status') == 200: num_sent += 1 return num_sent
def _send(self, email_message): """A helper method that does the actual sending""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) message = email_message.message() if not settings.PRODUCTION_EMAIL: recipients = settings.NON_PROD_EMAIL.split(',') message['Subject'] = '{} {}'.format(message.get('Subject'), settings.EMAIL_INSTANCE) else: recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] try: self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n')) except smtplib.SMTPException: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET email_message.from_email = fix_address(email_message.from_email) from_email = sanitize_address(email_message.from_email, encoding) from_email = self.return_path or from_email recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] message = email_message.message() try: self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n'), rcpt_options=self.rcpt_options) except smtplib.SMTPRecipientsRefused as e: logger.exception(e) if not handle_smtp_error(e): raise return False except smtplib.SMTPException as e: logger.exception(e) if not self.fail_silently: raise return False except Exception as e: logger.exception(e) raise return True
def send_messages(self, email_messages): if not email_messages: return num_sent = 0 for email_message in email_messages: if not email_message.recipients(): return encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] try: resp = requests.post( "https://api.mailgun.net/v3/sandbox075b55521f59465c82d4d87856d6f43c.mailgun.org/messages", auth=("api", "key-e1518fd3e6d897d250e23581f295417c"), data={ "from": "<*****@*****.**>", "to": recipients, "subject": email_message.subject, "text": email_message.body }) except Exception as e: if self.fail_silently: pass else: if resp.ok: num_sent += 1 return num_sent
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [ sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] message = email_message.message() charset = message.get_charset().get_output_charset( ) if message.get_charset() else 'utf-8' # tricky-stuff message = email_message.message().as_string() message = message.replace( '<p>Bonjour,</p>', '<p>ATTENTION, UN TRICKY STUFF EST UTILISÉ (smtpforward.EmailBackend).<br/>CET EMAIL ÉTAIT CENSÉ ÊTRE ENVOYÉ À : <strong>%s</strong></p><p>Bonjour,</p>' % recipients) message = message.replace( 'Bonjour,\r\n\n\n', 'ATTENTION, UN TRICKY STUFF EST UTILISÉ (smtpforward.EmailBackend)\r\n\n\nCET EMAIL ÉTAIT CENSÉ ÊTRE ENVOYÉ À : %s\r\n\n\nBonjour,\r\n\n\n' % recipients) to_list = settings.TO_LIST try: #self.connection.sendmail(from_email, recipients, self.connection.sendmail(from_email, to_list, force_bytes(message, charset)) except: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET # check this from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] message = email_message.message() # https://developers.google.com/gmail/api/guides/sending#creating_messages raw = base64.urlsafe_b64encode(message.as_bytes()) raw = raw.decode() binary_content = {'raw': raw} try: # need different login to check success self.connection.users().messages().send( userId='me', body=binary_content).execute() # self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n')) except (exceptions.DefaultCredentialsError, exceptions.GoogleAuthError, exceptions.RefreshError, exceptions.TransportError): if not self.fail_silently: raise return False return True
def prepare_data(self, email_message): from_email = sanitize_address(email_message.from_email, email_message.encoding) to_recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.to] cc_recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.cc] bcc_recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.bcc] data = { "to": ", ".join(to_recipients), "from": from_email, "subject": email_message.subject, "text": email_message.body, } # # Attach an HTML body if one was set # alternatives = getattr(email_message, "alternatives", []) # if alternatives: # for content, mimetype in alternatives: # if mimetype == "text/html": # data["html"] = content # break if cc_recipients: data["cc"] = ", ".join(cc_recipients) if bcc_recipients: data["bcc"] = ", ".join(bcc_recipients) try: data["v:grapevine-guid"] = email_message._email.guid except AttributeError: # Emails delivered by non-Grapevine email backends are unlikely # to have the ``_email`` attribute. But I ain't worried. pass return data
def _send(self, message): if not message.recipients(): return False self.sender = sanitize_address(message.from_email, message.encoding) recipients_list = [sanitize_address(addr, message.encoding) for addr in message.recipients()] from email.utils import parseaddr self.recipients = [{"email": e, "name": n} for n,e in [ parseaddr(r) for r in recipients_list]] self.msg_dict = self._build_standard_message_dict(message) if getattr(message, "alternative_subtype", None): if message.alternative_subtype == "mandrill": self._build_advanced_message_dict(message) if message.alternatives: self._add_alternatives(message) djrill_it = requests.post(self.api_action, data=json.dumps({ "key": self.api_key, "message": self.msg_dict })) if djrill_it.status_code != 200: if not self.fail_silently: raise DjrillBackendHTTPError(status_code=djrill_it.status_code, log_message="Failed to send a message to %s, from %s" % (self.recipients, self.sender)) return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = email_message.from_email if hasattr(message, 'sanitize_address'): from_email = message.sanitize_address(email_message.from_email, email_message.encoding) if hasattr(settings, 'TEST_EMAIL_TO'): email_message.to = settings.TEST_EMAIL_TO else: email_message.to = dict(getattr(settings, 'ADMINS', ())).values() email_message.cc = getattr(settings, 'TEST_EMAIL_CC', []) email_message.bcc = getattr(settings, 'TEST_EMAIL_BCC', []) if hasattr(message, 'sanitize_address'): recipients = [ message.sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] else: recipients = email_message.recipients() try: self.connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def _create_mail(self, email): """A helper method that creates mail for sending.""" if not email.recipients(): return False from_email = sanitize_address(email.from_email, email.encoding) recipients = [sanitize_address(addr, email.encoding) for addr in email.recipients()] mail = sendgrid.Mail() mail.add_to(recipients) mail.add_cc(email.cc) mail.add_bcc(email.bcc) mail.set_text(email.body) mail.set_subject(email.subject) mail.set_from(from_email) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.set_html(alt[0]) for attachment in email.attachments: if isinstance(attachment, MIMEBase): mail.add_attachment_stream( attachment.get_filename(), attachment.get_payload()) elif isinstance(attachment, tuple): mail.add_attachment_stream(attachment[0], attachment[1]) return mail
def _send(self, message): if not message.recipients(): return False self.sender = sanitize_address(message.from_email, message.encoding) recipients_list = [ sanitize_address(addr, message.encoding) for addr in message.recipients() ] from email.utils import parseaddr self.recipients = [{ "email": e, "name": n } for n, e in [parseaddr(r) for r in recipients_list]] self.msg_dict = self._build_standard_message_dict(message) if getattr(message, "alternative_subtype", None): if message.alternative_subtype == "mandrill": self._build_advanced_message_dict(message) if message.alternatives: self._add_alternatives(message) djrill_it = requests.post(self.api_action, data=json.dumps({ "key": self.api_key, "message": self.msg_dict })) if djrill_it.status_code != 200: if not self.fail_silently: raise return False return True
def _create_mail(self, email): """A helper method that creates mail for sending.""" if not email.recipients(): return False from_email = sanitize_address(email.from_email, email.encoding) recipients = [ sanitize_address(addr, email.encoding) for addr in email.recipients() ] mail = sendgrid.Mail() mail.add_to(recipients) mail.add_cc(email.cc) mail.add_bcc(email.bcc) mail.set_text(email.body) mail.set_subject(email.subject) mail.set_from(from_email) if isinstance(email, EmailMultiAlternatives): for alt in email.alternatives: if alt[1] == "text/html": mail.set_html(alt[0]) for attachment in email.attachments: if isinstance(attachment, MIMEBase): mail.add_attachment_stream(attachment.get_filename(), attachment.get_payload()) elif isinstance(attachment, tuple): mail.add_attachment_stream(attachment[0], attachment[1]) return mail
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] #print from_email,recipients,"================" #print email_message.message().as_string(),"dddddd" try: #from sae.mail import send_mail #send_mail(recipients, "invite", "to tonight's party" # (self.host, self.port, self.username, self.password, self.use_tls)) from sae.mail import EmailMessage m = EmailMessage() m.to = recipients m.subject = email_message.subject m.html = email_message.body m.smtp = (self.host, self.port, self.username, self.password, self.use_tls) m.send() #self.connection.sendmail(from_email, recipients,email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def _build_standard_message_dict(self, message): msg_dict = dict() if len(message.subject): msg_dict['Subject'] = message.subject if len(message.body): msg_dict['Text-part'] = message.body sender = sanitize_address(message.from_email, message.encoding) from_name, from_email = parseaddr(sender) msg_dict['FromEmail'] = from_email msg_dict['FromName'] = from_name # Place email recipients into Recipients field, unless Cc or Bcc are # used, in that case, place recipients into To. According to Mailjet: # # Important: Recipients and To have a different behaviors. The # recipients listed in To will recieve a common message showing every # other recipients and carbon copies recipients. The recipients listed # in Recipients will each recieve an seperate message without showing # all the other recipients. use_recipients = True if message.cc: msg_dict['Cc'] = ', '.join([ sanitize_address(addr, message.encoding) for addr in message.cc ]) use_recipients = False if message.bcc: msg_dict['Bcc'] = ', '.join([ sanitize_address(addr, message.encoding) for addr in message.bcc ]) use_recipients = False if use_recipients: msg_dict['Recipients'] = self._parse_recipients( message, message.to) else: msg_dict['To'] = ', '.join([ sanitize_address(addr, message.encoding) for addr in message.to ]) if message.reply_to: reply_to = [ sanitize_address(addr, message.encoding) for addr in message.reply_to ] msg_dict['Headers'] = {'Reply-To': ', '.join(reply_to)} if message.extra_headers: msg_dict['Headers'] = msg_dict.get('Headers', {}) msg_dict['Headers'].update(message.extra_headers) return msg_dict
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: post_data = [] post_data.append(("to", (",".join(recipients)))) post_data.append(("text", email_message.body)) post_data.append(("subject", email_message.subject)) post_data.append(("from", from_email)) # get our recipient variables if they were passed in recipient_variables = email_message.extra_headers.pop("recipient_variables", None) if recipient_variables is not None: post_data.append(("recipient-variables", recipient_variables)) for name, value in self._map_smtp_headers_to_api_parameters(email_message): post_data.append((name, value)) if hasattr(email_message, "alternatives") and email_message.alternatives: for alt in email_message.alternatives: if alt[1] == "text/html": post_data.append(("html", alt[0])) break # Map Reply-To header if present try: if email_message.reply_to: post_data.append(("h:Reply-To", ", ".join(map(force_text, email_message.reply_to)))) except AttributeError: pass if email_message.attachments: for attachment in email_message.attachments: post_data.append(("attachment", (attachment[0], attachment[1]))) content, header = encode_multipart_formdata(post_data) headers = {"Content-Type": header} else: content = post_data headers = None response = requests.post( self._api_url + "messages", auth=("api", self._access_key), data=content, headers=headers ) except: if not self.fail_silently: raise return False if response.status_code != 200: if not self.fail_silently: raise MailgunAPIError(response) return False return True
def send_standalone(self, email_message): if not email_message.recipients(): log.error("Error adding recipients to email.") return 0 if not self.client: log.error("Error initializing Mandrill client.") return 0 encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [ sanitize_address(addr, encoding) for addr in email_message.recipients() ] attachments = [{ 'name': name, 'content': str(base64.b64encode(content.encode('utf-8')), 'utf-8'), 'type': type } for name, content, type in email_message.attachments] num_sent = 0 for to in recipients: errors = [] try: message = { 'from_email': from_email, 'from_name': self.from_name, 'subject': email_message.subject, 'text': email_message.body, 'attachments': attachments, 'tags': [self.email_tag], 'to': [{ 'email': to, 'name': to, 'type': 'to' }], } result = self.client.messages.send(message=message) log.info(result) except mandrill.Error as e: log.exception( f"Error sending Mandrill email: {email_message.subject}, {to}, {e}" ) errors.append(e) except Exception as e: log.exception("Error with MandrillEmailBackend: {e}") errors.append(e) else: num_sent += 1 if errors and not self.fail_silently: raise errors[0] return num_sent
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [sanitize_address(addr, encoding) for addr in email_message.recipients()] allowed_recipients = [ recipient.strip().lower() for recipient in getattr(settings, 'EMAIL_ALLOWED_RECIPIENTS', []) ] allowed_domains = [ '@{}'.format(domain.strip().lower()) for domain in getattr(settings, 'EMAIL_ALLOWED_DOMAINS', [])] recipients = [recipient.strip().lower() for recipient in recipients] if allowed_recipients or allowed_domains: filtered_recipients = [] for domain in allowed_domains: for email in recipients: if email.endswith(domain): filtered_recipients.append(email) filtered_recipients = list( (set(allowed_recipients) & set(recipients)) # clear recipients by allowed recipients | set(filtered_recipients) # union with recipients allowed by domain ) email_message.subject = '[FILTERED] +{allowed_recipients} {subject}'.format( allowed_recipients=filtered_recipients, subject=email_message.subject ) logger.debug('[FILTERED] +{allowed_recipients} -{excluded_recipients} {subject}'.format( allowed_recipients=filtered_recipients, excluded_recipients=list(set(recipients).difference(set(filtered_recipients))), subject=email_message.subject )) final_recipients = filtered_recipients else: final_recipients = recipients message = email_message.message() try: self.connection.sendmail(from_email, final_recipients, message.as_bytes(linesep='\r\n')) except Exception as e: logger.debug(e, exc_info=True) if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: from requests.packages.urllib3.filepost import encode_multipart_formdata post_data = [] post_data.append(('to', (",".join(recipients)),)) post_data.append(('text', email_message.body,)) post_data.append(('subject', email_message.subject,)) post_data.append(('from', from_email,)) if 'Reply-To' in email_message.extra_headers: reply_to = email_message.extra_headers['Reply-To'] reply_to = sanitize_address(reply_to, email_message.encoding) post_data.append(('h:Reply-To', reply_to,)) if 'X-Mailgun-Variables' in email_message.extra_headers: custom_data = email_message.extra_headers['X-Mailgun-Variables'] post_data.append(('v:my-custom-data', json.dumps(custom_data))) if hasattr(email_message, 'alternatives') and email_message.alternatives: for alt in email_message.alternatives: if alt[1] == 'text/html': post_data.append(('html', alt[0],)) break if email_message.attachments: for attachment in email_message.attachments: post_data.append(('attachment', (attachment[0], attachment[1],))) content, header = encode_multipart_formdata(post_data) headers = {'Content-Type': header} else: content = post_data headers = None response = requests.post(self._api_url + "messages", auth=("api", self._access_key), data=content, headers=headers) except: if not self.fail_silently: raise return False if response.status_code != 200: if not self.fail_silently: raise MailgunAPIError(response) return False return True
def write_message_to_db(self, email_message): if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = email_message.from_email to_recipients = [ sanitize_address(addr, encoding) for addr in email_message.to if addr ] bcc_recipients = [ sanitize_address(addr, encoding) for addr in email_message.bcc if addr ] body = email_message.body subject = email_message.subject body_html = '' try: for alt in email_message.alternatives: if alt[1] == 'text/html': body_html += alt[0] except AttributeError: pass mail_code = '' if email_message.extra_headers.get('delayed_processing', False): status = 'not_rendered' context = email_message.extra_headers.get('context', {}) mail_code = email_message.extra_headers.get('mail_code', '') else: status = 'rendered' context = {} mail_log = MailLog.objects.create(body=body, subject=subject, body_html=body_html, to_recipients=to_recipients, bcc_recipients=bcc_recipients, from_email=from_email, status=status, mail_code=mail_code) for key, var in context.items(): if isinstance(var, models.Model): context_object = var value = '' else: context_object = None value = str(var) rel = MailLogRelation.objects.create(mail=mail_log, name=key, value=value, content_object=context_object) return True
def _build_standard_payload(self, message): """ Build standard message dict. Builds the standard dict that Django's send_mail and send_mass_mail use by default. Standard text email messages sent through Django will still work through Mandrill. """ recipients_list = [ sanitize_address(addr, message.encoding) for addr in message.recipients()] recipients = [ {"email": e, "name": n} for n, e in [parseaddr(r) for r in recipients_list]] sender = sanitize_address(message.from_email, message.encoding) name, email = parseaddr(sender) payload = { 'key': self.api_key, 'message': { 'text': message.body, 'subject': message.subject, 'from_email': email, 'from_name': getattr(message, 'from_name', None) or name, 'to': recipients, }, } if message.attachments: payload['message']['attachments'] = [] for attachment in message.attachments: # django supports two types of attachements: # * a subclass of email.mime.base.MIMEBase # * a tuple of (filename, content[, mimetype]) if isinstance(attachment, MIMEBase): filename = attachment.get_filename() content = attachment.get_payload(decode=True) mimetype = attachment.get_content_type() else: filename = attachment[0] content = attachment[1] mimetype = ( attachment[2] if len(attachment) > 2 and attachment[2] else mimetypes.guess_type(filename)[0] ) payload['message']['attachments'].append({ 'type': mimetype, 'name': str(filename), 'content': base64.b64encode(content), }) return payload
def send_messages(self, email_message): from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: send_email.delay(email_message.subject, email_message.message, from_email, recipients) except: if not self.fail_silently: raise
def _build_standard_message_dict(self, message): """Create a Mandrill send message struct from a Django EmailMessage. Builds the standard dict that Django's send_mail and send_mass_mail use by default. Standard text email messages sent through Django will still work through Mandrill. Raises NotSupportedByMandrillError for any standard EmailMessage features that cannot be accurately communicated to Mandrill (e.g., prohibited headers). """ sender = sanitize_address(message.from_email, message.encoding) from_name, from_email = parseaddr(sender) recipients = message.to + message.cc # message.recipients() w/o bcc parsed_rcpts = [ parseaddr(sanitize_address(addr, message.encoding)) for addr in recipients ] to_list = [{ "email": to_email, "name": to_name } for (to_name, to_email) in parsed_rcpts] content = "html" if message.content_subtype == "html" else "text" msg_dict = { content: message.body, "subject": message.subject, "from_email": from_email, "to": to_list } if from_name: msg_dict["from_name"] = from_name if len(message.bcc) == 1: bcc = message.bcc[0] _, bcc_addr = parseaddr(sanitize_address(bcc, message.encoding)) msg_dict['bcc_address'] = bcc_addr elif len(message.bcc) > 1: raise NotSupportedByMandrillError( "Too many bcc addresses (%d) - Mandrill only allows one" % len(message.bcc)) if message.extra_headers: for k in message.extra_headers.keys(): if k != "Reply-To" and not k.startswith("X-"): raise NotSupportedByMandrillError( "Invalid message header '%s' - Mandrill " "only allows Reply-To and X-* headers" % k) msg_dict["headers"] = message.extra_headers return msg_dict
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: post_data = [] post_data.append(('to', (",".join(recipients)),)) post_data.append(('text', email_message.body,)) post_data.append(('subject', email_message.subject,)) post_data.append(('from', from_email,)) # get our recipient variables if they were passed in recipient_variables = email_message.extra_headers.pop('recipient_variables', None) if recipient_variables is not None: post_data.append(('recipient-variables', recipient_variables, )) for name, value in self._map_smtp_headers_to_api_parameters(email_message): post_data.append((name, value, )) if hasattr(email_message, 'alternatives') and email_message.alternatives: for alt in email_message.alternatives: if alt[1] == 'text/html': post_data.append(('html', alt[0],)) break if email_message.attachments: for attachment in email_message.attachments: post_data.append(('attachment', (attachment[0], attachment[1],))) content, header = encode_multipart_formdata(post_data) headers = {'Content-Type': header} else: content = post_data headers = None response = requests.post(self._api_url + "messages", auth=("api", self._access_key), data=content, headers=headers) except: if not self.fail_silently: raise return False if response.status_code != 200: if not self.fail_silently: raise MailgunAPIError(response) return False return True
def send_messages(self, email_message): from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [ sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] try: send_email.delay(email_message.subject, email_message.message, from_email, recipients) except: if not self.fail_silently: raise
def __send(self, email_message): '''A helper method that does the actual sending.''' if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: self.__connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def __send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: self.__connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def _send_message(self, email_message): from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] r = requests.post( settings.MAILGUN_URL, auth=("api", settings.MAILGUN_KEY), data = { 'form': from_email, 'to': recipients, }, files = { 'message': StringIO(email_message.message().as_string()) }) return r.ok
def send_messages(self, email_messages): for email_message in email_messages: from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] try: send_email(email_message.subject.title(), email_message.message().as_string(), from_email, recipients) except: if not self.fail_silently: raise
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] message = email_message.message() try: self.connection.sendmail(from_email, recipients, message.as_bytes(linesep="\r\n")) except smtplib.SMTPException: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False encoding = email_message.encoding or settings.DEFAULT_CHARSET from_email = sanitize_address(email_message.from_email, encoding) recipients = [sanitize_address(addr, encoding) for addr in email_message.recipients()] message = email_message.message() try: self.connection.sendmail(from_email, recipients, message.as_bytes(linesep='\r\n')) except smtplib.SMTPException: if not self.fail_silently: raise return False return True
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for name, addr in settings.TEST_EMAIL_BACKEND_RECEPIENTS] try: self.connection.sendmail(from_email, recipients, email_message.message().as_string()) except: if not self.fail_silently: raise return False return True
def send_messages(self, email_messages): for email_message in email_messages: from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [ sanitize_address(addr, email_message.encoding) for addr in email_message.recipients() ] try: send_email(email_message.subject.title(), email_message.message().as_string(), from_email, recipients) except: if not self.fail_silently: raise
def _send(self, email_message): """A helper method that does the actual sending.""" if not email_message.recipients(): return False from_email = sanitize_address(email_message.from_email, email_message.encoding) recipients = [sanitize_address(addr, email_message.encoding) for addr in email_message.recipients()] message = email_message.message() charset = message.get_charset().get_output_charset() if message.get_charset() else "utf-8" try: self.connection.sendmail(from_email, recipients, force_bytes(message.as_string(), charset)) except: if not self.fail_silently: raise return False return True
def _send(self, message): email_api_action = self.api_action if not message.recipients(): return False self.sender = sanitize_address(message.from_email, message.encoding) recipients_list = [sanitize_address(addr, message.encoding) for addr in message.recipients()] self.recipients = [{"email": e, "name": n} for n,e in [ parseaddr(r) for r in recipients_list]] self.msg_dict = self._build_standard_message_dict(message) alternative_subtype = getattr(message, "alternative_subtype", None) if alternative_subtype: if alternative_subtype.startswith("mandrill"): self._build_advanced_message_dict(message) try: if getattr(message, 'alternatives', None): self._add_alternatives(message) except ValueError: if not self.fail_silently: raise return False api_data = { "key": self.api_key, "message": self.msg_dict } if alternative_subtype == 'mandrill_template': email_api_action = self.api_template_action api_data.update({ 'template_name': message.template_name, 'template_content': message.template_content, }) from pprint import pprint pprint(api_data) djrill_it = requests.post(email_api_action, data=json.dumps(api_data)) if djrill_it.status_code != 200: if not self.fail_silently: raise DjrillBackendHTTPError( status_code=djrill_it.status_code, log_message="Failed to send a message to %s, from %s" % (self.recipients, self.sender)) return False return True