Merge pull request #959 from koriaf/master

feat(emails): Do not auto-reply on auto-replies and add auto-reply header for auto-replies and fix headers propagation for our email messages
This commit is contained in:
Garret Wassermann 2021-04-20 10:44:28 -04:00 committed by GitHub
commit a8ae89ce23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 23 deletions

View File

@ -302,6 +302,21 @@ def decode_mail_headers(string):
]) ])
def is_autoreply(message):
"""
Accepting message as something with .get(header_name) method
Returns True if it's likely to be auto-reply or False otherwise
So we don't start mail loops
"""
any_if_this = [
False if not message.get("Auto-Submitted") else message.get("Auto-Submitted").lower() != "no",
True if message.get("X-Auto-Response-Suppress") in ("DR", "AutoReply", "All") else False,
message.get("List-Id"),
message.get("List-Unsubscribe"),
]
return any(any_if_this)
def create_ticket_cc(ticket, cc_list): def create_ticket_cc(ticket, cc_list):
if not cc_list: if not cc_list:
@ -429,30 +444,41 @@ def create_object_from_email_message(message, ticket_id, payload, files, logger)
for email_address in ticket_cc_list: for email_address in ticket_cc_list:
notifications_to_be_sent.append(email_address) notifications_to_be_sent.append(email_address)
# send mail to appropriate people now depending on what objects autoreply = is_autoreply(message)
# were created and who was CC'd if autoreply:
if new: logger.info("Message seems to be auto-reply, not sending any emails back to the sender")
ticket.send(
{'submitter': ('newticket_submitter', context),
'new_ticket_cc': ('newticket_cc', context),
'ticket_cc': ('newticket_cc', context)},
fail_silently=True,
extra_headers={'In-Reply-To': message_id},
)
else: else:
context.update(comment=f.comment) # send mail to appropriate people now depending on what objects
ticket.send( # were created and who was CC'd
{'submitter': ('newticket_submitter', context), # Add auto-reply headers because it's an auto-reply and we must
'assigned_to': ('updated_owner', context)}, extra_headers = {
fail_silently=True, 'In-Reply-To': message_id,
extra_headers={'In-Reply-To': message_id}, "Auto-Submitted": "auto-replied",
) "X-Auto-Response-Suppress": "All",
if queue.enable_notifications_on_email_events: "Precedence": "auto_reply",
}
if new:
ticket.send( ticket.send(
{'ticket_cc': ('updated_cc', context)}, {'submitter': ('newticket_submitter', context),
'new_ticket_cc': ('newticket_cc', context),
'ticket_cc': ('newticket_cc', context)},
fail_silently=True, fail_silently=True,
extra_headers={'In-Reply-To': message_id}, extra_headers=extra_headers,
) )
else:
context.update(comment=f.comment)
ticket.send(
{'submitter': ('newticket_submitter', context),
'assigned_to': ('updated_owner', context)},
fail_silently=True,
extra_headers=extra_headers,
)
if queue.enable_notifications_on_email_events:
ticket.send(
{'ticket_cc': ('updated_cc', context)},
fail_silently=True,
extra_headers=extra_headers,
)
return ticket return ticket
@ -469,6 +495,7 @@ def object_from_message(message, queue, logger):
sender = message.get('from', _('Unknown Sender')) sender = message.get('from', _('Unknown Sender'))
sender = decode_mail_headers(decodeUnknown(message.get_charset(), sender)) sender = decode_mail_headers(decodeUnknown(message.get_charset(), sender))
# to address bug #832, we wrap all the text in front of the email address in # to address bug #832, we wrap all the text in front of the email address in
# double quotes by using replace() on the email string. Then, # double quotes by using replace() on the email string. Then,
# take first item of list, second item of tuple is the actual email address. # take first item of list, second item of tuple is the actual email address.

View File

@ -614,7 +614,7 @@ class Ticket(models.Model):
'assigned_to': (template_name2, context), 'assigned_to': (template_name2, context),
} }
**kwargs are passed to send_templated_mail defined in templated_mail.py **kwargs are passed to send_templated_mail defined in templated_email.py
returns the set of email addresses the notification was delivered to. returns the set of email addresses the notification was delivered to.
@ -634,6 +634,7 @@ class Ticket(models.Model):
template, context = roles[role] template, context = roles[role]
send_templated_mail(template, context, recipient, sender=self.queue.from_address, **kwargs) send_templated_mail(template, context, recipient, sender=self.queue.from_address, **kwargs)
recipients.add(recipient) recipients.add(recipient)
send('submitter', self.submitter_email) send('submitter', self.submitter_email)
send('ticket_cc', self.queue.updated_ticket_cc) send('ticket_cc', self.queue.updated_ticket_cc)
send('new_ticket_cc', self.queue.new_ticket_cc) send('new_ticket_cc', self.queue.new_ticket_cc)

View File

@ -15,7 +15,7 @@ def send_templated_mail(template_name,
bcc=None, bcc=None,
fail_silently=False, fail_silently=False,
files=None, files=None,
extra_headers={}): extra_headers=None):
""" """
send_templated_mail() is a wrapper around Django's e-mail routines that send_templated_mail() is a wrapper around Django's e-mail routines that
allows us to easily send multipart (text/plain & text/html) e-mails using allows us to easily send multipart (text/plain & text/html) e-mails using
@ -53,6 +53,8 @@ def send_templated_mail(template_name,
from helpdesk.settings import HELPDESK_EMAIL_SUBJECT_TEMPLATE, \ from helpdesk.settings import HELPDESK_EMAIL_SUBJECT_TEMPLATE, \
HELPDESK_EMAIL_FALLBACK_LOCALE HELPDESK_EMAIL_FALLBACK_LOCALE
headers = extra_headers or {}
locale = context['queue'].get('locale') or HELPDESK_EMAIL_FALLBACK_LOCALE locale = context['queue'].get('locale') or HELPDESK_EMAIL_FALLBACK_LOCALE
try: try:
@ -95,7 +97,8 @@ def send_templated_mail(template_name,
msg = EmailMultiAlternatives(subject_part, text_part, msg = EmailMultiAlternatives(subject_part, text_part,
sender or settings.DEFAULT_FROM_EMAIL, sender or settings.DEFAULT_FROM_EMAIL,
recipients, bcc=bcc) recipients, bcc=bcc,
headers=headers)
msg.attach_alternative(html_part, "text/html") msg.attach_alternative(html_part, "text/html")
if files: if files: