def add_attachments_to_email(email, email_message, inline_headers): """ Retrieves all the attachments and adds them to the email. """ from ..utils import get_attachment_filename_from_url for attachment in email.attachments.all(): if attachment.inline: continue try: storage_file = default_storage._open(attachment.attachment.name) except IOError: logger.exception( 'Couldn\'t get attachment, not sending {}:{}'.format( email._meta.db_table, email.id)) raise filename = get_attachment_filename_from_url(attachment.attachment.name) storage_file.open() content = storage_file.read() storage_file.close() content_type, encoding = mimetypes.guess_type(filename) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) if main_type == 'text': msg = MIMEText(content, _subtype=sub_type) elif main_type == 'image': msg = MIMEImage(content, _subtype=sub_type) elif main_type == 'audio': msg = MIMEAudio(content, _subtype=sub_type) else: msg = MIMEBase(main_type, sub_type) msg.set_payload(content) Encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename)) email_message.attach(msg) # Add the inline attachments to email message header for inline_header in inline_headers: main_type, sub_type = inline_header['content-type'].split('/', 1) if main_type == 'image': msg = MIMEImage(inline_header['content'], _subtype=sub_type, name=os.path.basename( inline_header['content-filename'])) msg.add_header('Content-Disposition', inline_header['content-disposition'], filename=os.path.basename( inline_header['content-filename'])) msg.add_header('Content-ID', inline_header['content-id']) email_message.attach(msg) return True
def get(self, request, *args, **kwargs): try: attachment = EmailAttachment.objects.get( pk=self.kwargs['pk'], message__account__tenant_id=self.request.user.tenant.id ) except: raise Http404() s3_file = default_storage._open(attachment.attachment.name) wrapper = FileWrapper(s3_file) if hasattr(s3_file, 'key'): content_type = s3_file.key.content_type else: content_type = mimetypes.guess_type(s3_file.file.name)[0] response = HttpResponse(wrapper, content_type=content_type) inline = 'attachment' if attachment.inline: inline = 'inline' response['Content-Disposition'] = '%s; filename=%s' % (inline, get_attachment_filename_from_url(s3_file.name)) response['Content-Length'] = attachment.size return response
def get(self, request, *args, **kwargs): try: attachment = EmailAttachment.objects.get( pk=self.kwargs['pk'], message__account__tenant_id=self.request.user.tenant.id) except: raise Http404() s3_file = default_storage._open(attachment.attachment.name) wrapper = FileWrapper(s3_file) if hasattr(s3_file, 'key'): content_type = s3_file.key.content_type else: content_type = mimetypes.guess_type(s3_file.file.name)[0] response = HttpResponse(wrapper, content_type=content_type) inline = 'attachment' if attachment.inline: inline = 'inline' response['Content-Disposition'] = '%s; filename=%s' % ( inline, get_attachment_filename_from_url(s3_file.name)) response['Content-Length'] = attachment.size return response
def send_message(email_outbox_message_id, original_message_id=None): """ Send EmailOutboxMessage. Args: email_outbox_message_id (int): id of the EmailOutboxMessage original_message_id (int, optional): ID of the original EmailMessage """ send_logger = logging.getLogger('email_errors_temp_logger') send_logger.info('Start sending email_outbox_message: %d' % (email_outbox_message_id,)) sent_success = False try: email_outbox_message = EmailOutboxMessage.objects.get(pk=email_outbox_message_id) except EmailOutboxMessage.DoesNotExist: raise email_account = email_outbox_message.send_from # If we reply or forward, we want to add the thread_id original_message_thread_id = None if original_message_id: try: original_message = EmailMessage.objects.get(pk=original_message_id) if original_message.account.id is email_account.id: original_message_thread_id = original_message.thread_id except EmailMessage.DoesNotExist: raise # Add template attachments if email_outbox_message.template_attachment_ids: template_attachment_id_list = email_outbox_message.template_attachment_ids.split(',') for template_attachment_id in template_attachment_id_list: try: template_attachment = EmailTemplateAttachment.objects.get(pk=template_attachment_id) except EmailTemplateAttachment.DoesNotExist: pass else: attachment = EmailOutboxAttachment() attachment.content_type = template_attachment.content_type attachment.size = template_attachment.size attachment.email_outbox_message = email_outbox_message attachment.attachment = template_attachment.attachment attachment.save() # Add attachment from original message (if mail is being forwarded) if email_outbox_message.original_attachment_ids: original_attachment_id_list = email_outbox_message.original_attachment_ids.split(',') for attachment_id in original_attachment_id_list: try: original_attachment = EmailAttachment.objects.get(pk=attachment_id) except EmailAttachment.DoesNotExist: pass else: outbox_attachment = EmailOutboxAttachment() outbox_attachment.email_outbox_message = email_outbox_message outbox_attachment.tenant_id = original_attachment.message.tenant_id file = default_storage._open(original_attachment.attachment.name) file.open() content = file.read() file.close() file = ContentFile(content) file.name = original_attachment.attachment.name outbox_attachment.attachment = file outbox_attachment.inline = original_attachment.inline outbox_attachment.size = file.size outbox_attachment.save() if not email_account.is_authorized: logger.error('EmailAccount not authorized: %s', email_account) else: manager = GmailManager(email_account) try: manager.send_email_message(email_outbox_message.message(), original_message_thread_id) logger.debug('Message sent from: %s', email_account) # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more email_outbox_message.delete() sent_success = True except ManagerError, e: logger.error(traceback.format_exc(e)) raise except Exception, e: logger.error(traceback.format_exc(e)) raise
def send_message(email_outbox_message_id, original_message_id=None): """ Send EmailOutboxMessage. Args: email_outbox_message_id (int): id of the EmailOutboxMessage original_message_id (int, optional): ID of the original EmailMessage """ send_logger = logging.getLogger('email_errors_temp_logger') send_logger.info('Start sending email_outbox_message: %d' % (email_outbox_message_id, )) sent_success = False try: email_outbox_message = EmailOutboxMessage.objects.get( pk=email_outbox_message_id) except EmailOutboxMessage.DoesNotExist: raise email_account = email_outbox_message.send_from if not email_account.is_authorized: logger.error('EmailAccount not authorized: %s', email_account) return sent_success # If we reply or forward, we want to add the thread_id. original_message_thread_id = None if original_message_id: try: original_message = EmailMessage.objects.get(pk=original_message_id) if original_message.account.id is email_account.id: original_message_thread_id = original_message.thread_id except EmailMessage.DoesNotExist: raise # Add template attachments. if email_outbox_message.template_attachment_ids: template_attachment_id_list = email_outbox_message.template_attachment_ids.split( ',') for template_attachment_id in template_attachment_id_list: try: template_attachment = EmailTemplateAttachment.objects.get( pk=template_attachment_id) except EmailTemplateAttachment.DoesNotExist: pass else: attachment = EmailOutboxAttachment() attachment.content_type = template_attachment.content_type attachment.size = template_attachment.size attachment.email_outbox_message = email_outbox_message attachment.attachment = template_attachment.attachment attachment.tenant_id = template_attachment.tenant_id attachment.save() # Add attachment from original message (if mail is being forwarded). if email_outbox_message.original_attachment_ids: original_attachment_id_list = email_outbox_message.original_attachment_ids.split( ',') for attachment_id in original_attachment_id_list: try: original_attachment = EmailAttachment.objects.get( pk=attachment_id) except EmailAttachment.DoesNotExist: pass else: outbox_attachment = EmailOutboxAttachment() outbox_attachment.email_outbox_message = email_outbox_message outbox_attachment.tenant_id = original_attachment.message.tenant_id file = default_storage._open( original_attachment.attachment.name) file.open() content = file.read() file.close() file = ContentFile(content) file.name = original_attachment.attachment.name outbox_attachment.attachment = file outbox_attachment.inline = original_attachment.inline outbox_attachment.size = file.size outbox_attachment.save() manager = None try: manager = GmailManager(email_account) manager.send_email_message(email_outbox_message.message(), original_message_thread_id) logger.debug('Message sent from: %s', email_account) # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more. email_outbox_message.delete() sent_success = True # TODO: This should probably be moved to the front end once # we can notify users about sent mails. post_intercom_event(event_name='email-sent', user_id=email_account.owner.id) except HttpAccessTokenRefreshError: logger.warning('EmailAccount not authorized: %s', email_account) pass except Exception as e: logger.error(traceback.format_exc(e)) raise finally: if manager: manager.cleanup() send_logger.info( 'Done sending email_outbox_message: %d And sent_succes value: %s' % (email_outbox_message_id, sent_success)) return sent_success
def replace_cid_and_change_headers(html, pk): """ Check in the html source if there is an image tag with the attribute cid. Loop through the attachemnts that are linked with the email. If there is a match replace the source of the image with the cid information. After read the image information form the disk and put the data in a dummy header. At least create a plain text version of the html email. Args: html (string): HTML string of the email body to be sent. mapped_attachments (list): List of linked attachments to the email request (instance): The django request Returns: body_html (string), body_text (string), dummy_headers (dict) """ if html is None: return None dummy_headers = [] inline_images = [] soup = create_a_beautiful_soup_object(html) attachments = EmailAttachment.objects.filter(message_id=pk) if soup and attachments: inline_images = soup.findAll('img', {'cid': lambda cid: cid}) if (not soup or soup.get_text() == '') and not inline_images: body_html = html else: cid_done = [] for image in inline_images: image_cid = image['cid'] for attachment in attachments: if (attachment.cid[1:-1] == image_cid or attachment.cid == image_cid) and attachment.cid not in cid_done: image['src'] = "cid:%s" % image_cid storage_file = default_storage._open(attachment.attachment.name) filename = get_attachment_filename_from_url(attachment.attachment.name) if hasattr(storage_file, 'key'): content_type = storage_file.key.content_type else: content_type = mimetypes.guess_type(storage_file.file.name)[0] storage_file.open() content = storage_file.read() storage_file.close() response = { 'content-type': content_type, 'content-disposition': 'inline', 'content-filename': filename, 'content-id': attachment.cid, 'x-attachment-id': image_cid, 'content-transfer-encoding': 'base64', 'content': content } dummy_headers.append(response) cid_done.append(attachment.cid) del image['cid'] body_html = soup.encode_contents() body_text_handler = html2text.HTML2Text() body_text_handler.ignore_links = True body_text_handler.body_width = 0 body_text = body_text_handler.handle(html) return body_html, body_text, dummy_headers
def _open(self, name, mode='rb'): return default_storage._open(name, mode=mode) # pylint: disable=protected-access
def message(self): from ..utils import get_attachment_filename_from_url, replace_cid_and_change_headers to = anyjson.loads(self.to) cc = anyjson.loads(self.cc) bcc = anyjson.loads(self.bcc) if self.send_from.from_name: # Add account name to From header if one is available from_email = '"%s" <%s>' % (Header(u"%s" % self.send_from.from_name, "utf-8"), self.send_from.email_address) else: # Otherwise only add the email address from_email = self.send_from.email_address html, text, inline_headers = replace_cid_and_change_headers(self.body, self.original_message_id) email_message = SafeMIMEMultipart("related") email_message["Subject"] = self.subject email_message["From"] = from_email if to: email_message["To"] = ",".join(list(to)) if cc: email_message["cc"] = ",".join(list(cc)) if bcc: email_message["bcc"] = ",".join(list(bcc)) email_message_alternative = SafeMIMEMultipart("alternative") email_message.attach(email_message_alternative) email_message_text = SafeMIMEText(text, "plain", "utf-8") email_message_alternative.attach(email_message_text) email_message_html = SafeMIMEText(html, "html", "utf-8") email_message_alternative.attach(email_message_html) for attachment in self.attachments.all(): if attachment.inline: continue try: storage_file = default_storage._open(attachment.attachment.name) except IOError: logger.exception("Couldn't get attachment, not sending %s" % self.id) return False filename = get_attachment_filename_from_url(attachment.attachment.name) storage_file.open() content = storage_file.read() storage_file.close() content_type, encoding = mimetypes.guess_type(filename) if content_type is None or encoding is not None: content_type = "application/octet-stream" main_type, sub_type = content_type.split("/", 1) if main_type == "text": msg = MIMEText(content, _subtype=sub_type) elif main_type == "image": msg = MIMEImage(content, _subtype=sub_type) elif main_type == "audio": msg = MIMEAudio(content, _subtype=sub_type) else: msg = MIMEBase(main_type, sub_type) msg.set_payload(content) Encoders.encode_base64(msg) msg.add_header("Content-Disposition", "attachment", filename=os.path.basename(filename)) email_message.attach(msg) # Add the inline attachments to email message header for inline_header in inline_headers: main_type, sub_type = inline_header["content-type"].split("/", 1) if main_type == "image": msg = MIMEImage( inline_header["content"], _subtype=sub_type, name=os.path.basename(inline_header["content-filename"]), ) msg.add_header( "Content-Disposition", inline_header["content-disposition"], filename=os.path.basename(inline_header["content-filename"]), ) msg.add_header("Content-ID", inline_header["content-id"]) email_message.attach(msg) return email_message
def message(self): from ..utils import get_attachment_filename_from_url, replace_cid_and_change_headers to = anyjson.loads(self.to) cc = anyjson.loads(self.cc) bcc = anyjson.loads(self.bcc) if self.send_from.from_name: # Add account name to From header if one is available from_email = '"%s" <%s>' % (Header( u'%s' % self.send_from.from_name, 'utf-8'), self.send_from.email_address) else: # Otherwise only add the email address from_email = self.send_from.email_address html, text, inline_headers = replace_cid_and_change_headers( self.body, self.original_message_id) email_message = SafeMIMEMultipart('related') email_message['Subject'] = self.subject email_message['From'] = from_email if to: email_message['To'] = ','.join(list(to)) if cc: email_message['cc'] = ','.join(list(cc)) if bcc: email_message['bcc'] = ','.join(list(bcc)) email_message_alternative = SafeMIMEMultipart('alternative') email_message.attach(email_message_alternative) email_message_text = SafeMIMEText(text, 'plain', 'utf-8') email_message_alternative.attach(email_message_text) email_message_html = SafeMIMEText(html, 'html', 'utf-8') email_message_alternative.attach(email_message_html) for attachment in self.attachments.all(): if attachment.inline: continue try: storage_file = default_storage._open( attachment.attachment.name) except IOError: logger.exception('Couldn\'t get attachment, not sending %s' % self.id) return False filename = get_attachment_filename_from_url( attachment.attachment.name) storage_file.open() content = storage_file.read() storage_file.close() content_type, encoding = mimetypes.guess_type(filename) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) if main_type == 'text': msg = MIMEText(content, _subtype=sub_type) elif main_type == 'image': msg = MIMEImage(content, _subtype=sub_type) elif main_type == 'audio': msg = MIMEAudio(content, _subtype=sub_type) else: msg = MIMEBase(main_type, sub_type) msg.set_payload(content) Encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename)) email_message.attach(msg) # Add the inline attachments to email message header for inline_header in inline_headers: main_type, sub_type = inline_header['content-type'].split('/', 1) if main_type == 'image': msg = MIMEImage(inline_header['content'], _subtype=sub_type, name=os.path.basename( inline_header['content-filename'])) msg.add_header('Content-Disposition', inline_header['content-disposition'], filename=os.path.basename( inline_header['content-filename'])) msg.add_header('Content-ID', inline_header['content-id']) email_message.attach(msg) return email_message
def send_message(email_outbox_message_id, original_message_id=None): """ Send EmailOutboxMessage. Args: email_outbox_message_id (int): id of the EmailOutboxMessage original_message_id (int, optional): ID of the original EmailMessage """ send_logger = logging.getLogger('email_errors_temp_logger') send_logger.info('Start sending email_outbox_message: %d' % (email_outbox_message_id, )) sent_success = False try: email_outbox_message = EmailOutboxMessage.objects.get( pk=email_outbox_message_id) except EmailOutboxMessage.DoesNotExist: raise email_account = email_outbox_message.send_from # If we reply or forward, we want to add the thread_id original_message_thread_id = None if original_message_id: try: original_message = EmailMessage.objects.get(pk=original_message_id) if original_message.account.id is email_account.id: original_message_thread_id = original_message.thread_id except EmailMessage.DoesNotExist: raise # Add template attachments if email_outbox_message.template_attachment_ids: template_attachment_id_list = email_outbox_message.template_attachment_ids.split( ',') for template_attachment_id in template_attachment_id_list: try: template_attachment = EmailTemplateAttachment.objects.get( pk=template_attachment_id) except EmailTemplateAttachment.DoesNotExist: pass else: attachment = EmailOutboxAttachment() attachment.content_type = template_attachment.content_type attachment.size = template_attachment.size attachment.email_outbox_message = email_outbox_message attachment.attachment = template_attachment.attachment attachment.save() # Add attachment from original message (if mail is being forwarded) if email_outbox_message.original_attachment_ids: original_attachment_id_list = email_outbox_message.original_attachment_ids.split( ',') for attachment_id in original_attachment_id_list: try: original_attachment = EmailAttachment.objects.get( pk=attachment_id) except EmailAttachment.DoesNotExist: pass else: outbox_attachment = EmailOutboxAttachment() outbox_attachment.email_outbox_message = email_outbox_message outbox_attachment.tenant_id = original_attachment.message.tenant_id file = default_storage._open( original_attachment.attachment.name) file.open() content = file.read() file.close() file = ContentFile(content) file.name = original_attachment.attachment.name outbox_attachment.attachment = file outbox_attachment.inline = original_attachment.inline outbox_attachment.size = file.size outbox_attachment.save() if not email_account.is_authorized: logger.error('EmailAccount not authorized: %s', email_account) else: manager = GmailManager(email_account) try: manager.send_email_message(email_outbox_message.message(), original_message_thread_id) logger.debug('Message sent from: %s', email_account) # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more email_outbox_message.delete() sent_success = True except ManagerError, e: logger.error(traceback.format_exc(e)) raise except Exception, e: logger.error(traceback.format_exc(e)) raise
def message(self): from ..utils import get_attachment_filename_from_url, replace_cid_and_change_headers to = anyjson.loads(self.to) cc = anyjson.loads(self.cc) bcc = anyjson.loads(self.bcc) if self.send_from.from_name: # Add account name to From header if one is available from_email = '"%s" <%s>' % ( Header(u'%s' % self.send_from.from_name, 'utf-8'), self.send_from.email_address ) else: # Otherwise only add the email address from_email = self.send_from.email_address html, text, inline_headers = replace_cid_and_change_headers(self.body, self.original_message_id) email_message = SafeMIMEMultipart('related') email_message['Subject'] = self.subject email_message['From'] = from_email if to: email_message['To'] = ','.join(list(to)) if cc: email_message['cc'] = ','.join(list(cc)) if bcc: email_message['bcc'] = ','.join(list(bcc)) email_message_alternative = SafeMIMEMultipart('alternative') email_message.attach(email_message_alternative) email_message_text = SafeMIMEText(text, 'plain', 'utf-8') email_message_alternative.attach(email_message_text) email_message_html = SafeMIMEText(html, 'html', 'utf-8') email_message_alternative.attach(email_message_html) for attachment in self.attachments.all(): if attachment.inline: continue try: storage_file = default_storage._open(attachment.attachment.name) except IOError: logger.exception('Couldn\'t get attachment, not sending %s' % self.id) return False filename = get_attachment_filename_from_url(attachment.attachment.name) storage_file.open() content = storage_file.read() storage_file.close() content_type, encoding = mimetypes.guess_type(filename) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) if main_type == 'text': msg = MIMEText(content, _subtype=sub_type) elif main_type == 'image': msg = MIMEImage(content, _subtype=sub_type) elif main_type == 'audio': msg = MIMEAudio(content, _subtype=sub_type) else: msg = MIMEBase(main_type, sub_type) msg.set_payload(content) Encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename)) email_message.attach(msg) # Add the inline attachments to email message header for inline_header in inline_headers: main_type, sub_type = inline_header['content-type'].split('/', 1) if main_type == 'image': msg = MIMEImage( inline_header['content'], _subtype=sub_type, name=os.path.basename(inline_header['content-filename']) ) msg.add_header( 'Content-Disposition', inline_header['content-disposition'], filename=os.path.basename(inline_header['content-filename']) ) msg.add_header('Content-ID', inline_header['content-id']) email_message.attach(msg) return email_message
def add_attachments_to_email(email, email_message, inline_headers): """ Retrieves all the attachments and adds them to the email. """ from ..utils import get_attachment_filename_from_url for attachment in email.attachments.all(): if attachment.inline: continue try: storage_file = default_storage._open(attachment.attachment.name) except IOError: logger.exception( 'Couldn\'t get attachment, not sending {}:{}'.format( email._meta.db_table, email.id ) ) raise filename = get_attachment_filename_from_url(attachment.attachment.name) storage_file.open() content = storage_file.read() storage_file.close() content_type, encoding = mimetypes.guess_type(filename) if content_type is None or encoding is not None: content_type = 'application/octet-stream' main_type, sub_type = content_type.split('/', 1) if main_type == 'text': msg = MIMEText(content, _subtype=sub_type) elif main_type == 'image': msg = MIMEImage(content, _subtype=sub_type) elif main_type == 'audio': msg = MIMEAudio(content, _subtype=sub_type) else: msg = MIMEBase(main_type, sub_type) msg.set_payload(content) Encoders.encode_base64(msg) msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename)) email_message.attach(msg) # Add the inline attachments to email message header for inline_header in inline_headers: main_type, sub_type = inline_header['content-type'].split('/', 1) if main_type == 'image': msg = MIMEImage( inline_header['content'], _subtype=sub_type, name=os.path.basename(inline_header['content-filename']) ) msg.add_header( 'Content-Disposition', inline_header['content-disposition'], filename=os.path.basename(inline_header['content-filename']) ) msg.add_header('Content-ID', inline_header['content-id']) email_message.attach(msg) return True
def send_message(email_id, original_message_id=None, draft=False): """ Send EmailOutboxMessage or EmailDraft. Args: email_outbox_message_id (int): id of the EmailOutboxMessage original_message_id (int, optional): ID of the original EmailMessage draft (bool, optional): whether the newer EmailDraft should be queried """ send_logger = logging.getLogger('email_errors_temp_logger') send_logger.info('Start sending email_outbox_message: %d' % (email_id,)) # Below describes the differences between EmailOutboxMessage and EmailDraft. # As soon as EmailDraft is proven to work, this class can be refactored to only work for EmailDraft. email_class = EmailOutboxMessage email_attachment_class = EmailOutboxAttachment email_attachment_to_email_class_field_name = 'email_outbox_message' email_message_function_name = 'message' if draft: email_class = EmailDraft email_attachment_class = EmailDraftAttachment email_attachment_to_email_class_field_name = 'email_draft' email_message_function_name = 'mime_message' sent_success = False try: email = email_class.objects.get(pk=email_id) except email_class.DoesNotExist: raise email_account = email.send_from if not email_account.is_authorized: logger.error('EmailAccount not authorized: %s', email_account) return sent_success # If we reply or forward, we want to add the thread_id. original_message_thread_id = None if original_message_id: try: original_message = EmailMessage.objects.get(pk=original_message_id) if original_message.account.id is email_account.id: original_message_thread_id = original_message.thread_id except EmailMessage.DoesNotExist: raise # Add template attachments. if email.template_attachment_ids: template_attachment_id_list = email.template_attachment_ids.split(',') for template_attachment_id in template_attachment_id_list: try: template_attachment = EmailTemplateAttachment.objects.get(pk=template_attachment_id) except EmailTemplateAttachment.DoesNotExist: pass else: attachment = email_attachment_class() attachment.content_type = template_attachment.content_type attachment.size = template_attachment.size setattr(attachment, email_attachment_to_email_class_field_name, email) attachment.attachment = template_attachment.attachment attachment.tenant_id = template_attachment.tenant_id attachment.save() # Add attachment from original message (if mail is being forwarded). if email.original_attachment_ids: original_attachment_id_list = email.original_attachment_ids.split(',') for attachment_id in original_attachment_id_list: try: original_attachment = EmailAttachment.objects.get(pk=attachment_id) except EmailAttachment.DoesNotExist: pass else: outbox_attachment = email_attachment_class() setattr(outbox_attachment, email_attachment_to_email_class_field_name, email) outbox_attachment.tenant_id = original_attachment.message.tenant_id file = default_storage._open(original_attachment.attachment.name) file.open() content = file.read() file.close() file = ContentFile(content) file.name = original_attachment.attachment.name outbox_attachment.attachment = file outbox_attachment.inline = original_attachment.inline outbox_attachment.size = file.size outbox_attachment.save() manager = None try: manager = GmailManager(email_account) manager.send_email_message(getattr(email, email_message_function_name)(), original_message_thread_id) logger.debug('Message sent from: %s', email_account) # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more. email.delete() sent_success = True # TODO: This should probably be moved to the front end once # we can notify users about sent mails. post_intercom_event(event_name='email-sent', user_id=email_account.owner.id) except HttpAccessTokenRefreshError: logger.warning('EmailAccount not authorized: %s', email_account) pass except Exception as e: logger.error(traceback.format_exc(e)) raise finally: if manager: manager.cleanup() send_logger.info('Done sending {}: {} And sent_succes value: {}'.format( email_attachment_to_email_class_field_name, email_id, sent_success )) return sent_success
def send_message(email_outbox_message_id, original_message_id=None): """ Send EmailOutboxMessage. Args: email_outbox_message_id (int): id of the EmailOutboxMessage original_message_id (int, optional): ID of the original EmailMessage """ send_logger = logging.getLogger('email_errors_temp_logger') send_logger.info('Start sending email_outbox_message: %d' % (email_outbox_message_id,)) sent_success = False try: email_outbox_message = EmailOutboxMessage.objects.get(pk=email_outbox_message_id) except EmailOutboxMessage.DoesNotExist: raise email_account = email_outbox_message.send_from if not email_account.is_authorized: logger.error('EmailAccount not authorized: %s', email_account) return sent_success # If we reply or forward, we want to add the thread_id. original_message_thread_id = None if original_message_id: try: original_message = EmailMessage.objects.get(pk=original_message_id) if original_message.account.id is email_account.id: original_message_thread_id = original_message.thread_id except EmailMessage.DoesNotExist: raise # Add template attachments. if email_outbox_message.template_attachment_ids: template_attachment_id_list = email_outbox_message.template_attachment_ids.split(',') for template_attachment_id in template_attachment_id_list: try: template_attachment = EmailTemplateAttachment.objects.get(pk=template_attachment_id) except EmailTemplateAttachment.DoesNotExist: pass else: attachment = EmailOutboxAttachment() attachment.content_type = template_attachment.content_type attachment.size = template_attachment.size attachment.email_outbox_message = email_outbox_message attachment.attachment = template_attachment.attachment attachment.tenant_id = template_attachment.tenant_id attachment.save() # Add attachment from original message (if mail is being forwarded). if email_outbox_message.original_attachment_ids: original_attachment_id_list = email_outbox_message.original_attachment_ids.split(',') for attachment_id in original_attachment_id_list: try: original_attachment = EmailAttachment.objects.get(pk=attachment_id) except EmailAttachment.DoesNotExist: pass else: outbox_attachment = EmailOutboxAttachment() outbox_attachment.email_outbox_message = email_outbox_message outbox_attachment.tenant_id = original_attachment.message.tenant_id file = default_storage._open(original_attachment.attachment.name) file.open() content = file.read() file.close() file = ContentFile(content) file.name = original_attachment.attachment.name outbox_attachment.attachment = file outbox_attachment.inline = original_attachment.inline outbox_attachment.size = file.size outbox_attachment.save() manager = None try: manager = GmailManager(email_account) manager.send_email_message(email_outbox_message.message(), original_message_thread_id) logger.debug('Message sent from: %s', email_account) # Seems like everything went right, so the EmailOutboxMessage object isn't needed any more. email_outbox_message.delete() sent_success = True # TODO: This should probably be moved to the front end once # we can notify users about sent mails. post_intercom_event(event_name='email-sent', user_id=email_account.owner.id) except HttpAccessTokenRefreshError: logger.warning('EmailAccount not authorized: %s', email_account.email_address) pass except Exception as e: logger.error(traceback.format_exc(e)) raise finally: if manager: manager.cleanup() send_logger.info( 'Done sending email_outbox_message: %d And sent_succes value: %s' % (email_outbox_message_id, sent_success) ) return sent_success