Skip to content
Snippets Groups Projects
Commit f78c0e54 authored by Tanner Prestegard's avatar Tanner Prestegard Committed by GraceDB
Browse files

Updates to new phone alert code

Switch over to new phone alert code (somewhat improved compared
to the old code).  Made a few more updates and bugfixes.
parent 59b759c5
No related branches found
No related tags found
No related merge requests found
...@@ -17,19 +17,12 @@ from events.permission_utils import is_external ...@@ -17,19 +17,12 @@ from events.permission_utils import is_external
from events.query import filter_for_labels from events.query import filter_for_labels
from events.shortcuts import is_event from events.shortcuts import is_event
from superevents.shortcuts import is_superevent from superevents.shortcuts import is_superevent
from userprofile.models import Contact
from .phone import issue_phone_alerts
from .xmpp import issue_xmpp_alerts from .xmpp import issue_xmpp_alerts
# Set up logger # Set up logger
log = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def check_recips(recips_qs):
"""
Make sure only internal users are included. Assumes that the queryset's
model has a foreign key to the user object.
"""
LVC_GROUP = Group.objects.get(name=settings.LVC_GROUP)
return recips_qs.filter(user__groups=LVC_GROUP)
def get_alert_recips(event_or_superevent): def get_alert_recips(event_or_superevent):
...@@ -39,18 +32,20 @@ def get_alert_recips(event_or_superevent): ...@@ -39,18 +32,20 @@ def get_alert_recips(event_or_superevent):
pass pass
elif is_event(event_or_superevent): elif is_event(event_or_superevent):
event = event_or_superevent event = event_or_superevent
triggers = event.pipeline.trigger_set.filter(labels=None) \ # Queryset of all triggers for this pipeline
.prefetch_related('contacts') triggers = event.pipeline.trigger_set.filter(labels=None)
email_recips = [c for t in triggers for c in # Filter on FAR threshold requirements
t.contacts.all().select_related('user') query = Q(farThresh__isnull=True)
if ((not t.farThresh or (event.far and event.far < t.farThresh)) if event.far:
and r.email)] query |= Q(farThresh__lt=event.far)
phone_recips = [c for t in triggers for c in triggers = triggers.filter(query)
t.contacts.all().select_related('user') # Contacts for all triggers, make sure user is in LVC group (safeguard)
if ((not t.farThresh or (event.far and event.far < t.farThresh)) contacts = Contact.objects.filter(trigger__in=triggers,
and r.phone)] user__groups__name=settings.LVC_GROUP).select_related('user')
email_recips = contacts.exclude(email="")
return check_recips(email_recips), check_recips(phone_recips) phone_recips = contacts.exclude(phone="")
return email_recips, phone_recips
def get_alert_recips_for_label(event_or_superevent, label): def get_alert_recips_for_label(event_or_superevent, label):
...@@ -60,7 +55,8 @@ def get_alert_recips_for_label(event_or_superevent, label): ...@@ -60,7 +55,8 @@ def get_alert_recips_for_label(event_or_superevent, label):
# Construct a queryset containing only this object; needed for # Construct a queryset containing only this object; needed for
# call to filter_for_labels # call to filter_for_labels
qs = event_or_superevent.model.objects.filter(id=event_or_superevent.id) qs = event_or_superevent._meta.model.objects.filter(
pk=event_or_superevent.pk)
# Triggers on given label matching pipeline OR with no pipeline; # Triggers on given label matching pipeline OR with no pipeline;
# no pipeline indicates that pipeline is irrelevant # no pipeline indicates that pipeline is irrelevant
...@@ -78,7 +74,7 @@ def get_alert_recips_for_label(event_or_superevent, label): ...@@ -78,7 +74,7 @@ def get_alert_recips_for_label(event_or_superevent, label):
# Idea: have filter_for_labels return a Q object generated from the # Idea: have filter_for_labels return a Q object generated from the
# label query # label query
triggers = label.trigger_set.filter(query).prefetch_related('contacts') triggers = label.trigger_set.filter(query).prefetch_related('contacts')
for trigger in triggers.related(): for trigger in triggers:
if len(trigger.label_query) > 0: if len(trigger.label_query) > 0:
qs_out = filter_for_labels(qs, trigger.label_query) qs_out = filter_for_labels(qs, trigger.label_query)
...@@ -88,13 +84,14 @@ def get_alert_recips_for_label(event_or_superevent, label): ...@@ -88,13 +84,14 @@ def get_alert_recips_for_label(event_or_superevent, label):
if not qs_out.exists(): if not qs_out.exists():
continue continue
# Compile a list of recipients from the trigger's contacts # Compile a list of recipients from the trigger's contacts.
email_recips |= trigger.contacts.exclude(email="") \ # Require that the user is in the LVC group as a safeguard
.select_related('user') contacts = trigger.contacts.filter(user__groups__name=
phone_recips |= trigger.contacts.exclude(phone="") \ settings.LVC_GROUP)
.select_related('user') email_recips |= contacts.exclude(email="").select_related('user')
phone_recips |= contacts.exclude(phone="").select_related('user')
return check_recips(email_recips), check_recips(phone_recips) return email_recips, phone_recips
def issue_alerts(event_or_superevent, alert_type, serialized_object, def issue_alerts(event_or_superevent, alert_type, serialized_object,
......
...@@ -7,7 +7,7 @@ from django_twilio.client import twilio_client ...@@ -7,7 +7,7 @@ from django_twilio.client import twilio_client
from events.permission_utils import is_external from events.permission_utils import is_external
# Set up logger # Set up logger
log = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# TODO: generalize to superevents # TODO: generalize to superevents
...@@ -75,43 +75,29 @@ def issue_phone_alerts(event, contacts, label=None): ...@@ -75,43 +75,29 @@ def issue_phone_alerts(event, contacts, label=None):
msg_body = TWILIO_MSG_CONTENT[alert_type].format(**msg_params) msg_body = TWILIO_MSG_CONTENT[alert_type].format(**msg_params)
# Loop over recipients and make calls and/or texts. # Loop over recipients and make calls and/or texts.
for contact in twilio_recips: for contact in contacts:
if is_external(recip.user): if is_external(contact.user):
# Only make calls to LVC members (non-LVC members # Only make calls to LVC members (non-LVC members
# shouldn't even be able to sign up for phone alerts, # shouldn't even be able to sign up for phone alerts,
# but this is another safety measure. # but this is another safety measure.
log.warning("External user {0} is somehow signed up for" logger.warning("External user {0} is somehow signed up for"
" phone alerts".format(recip.user.username)) " phone alerts".format(contact.user.username))
continue continue
try: try:
# POST to TwiML bin to make voice call. # POST to TwiML bin to make voice call.
if recip.call_phone: if contact.call_phone:
log.debug("Calling {0} at {1}".format(recip.user.username, logger.debug("Calling {0} at {1}".format(contact.user.username,
recip.phone)) contact.phone))
twilio_client.calls.create(to=recip.phone, from_=from_, twilio_client.calls.create(to=contact.phone, from_=from_,
url=twiml_url, method='GET') url=twiml_url, method='GET')
# Create Twilio message. # Create Twilio message.
if recip.text_phone: if contact.text_phone:
log.debug("Texting {0} at {1}".format(recip.user.username, logger.debug("Texting {0} at {1}".format(contact.user.username,
recip.phone)) contact.phone))
twilio_client.messages.create(to=recip.phone, from_=from_, twilio_client.messages.create(to=contact.phone, from_=from_,
body=msg_body) body=msg_body)
except Exception as e: except Exception as e:
log.exception("Failed to contact {0} at {1}.".format( logger.exception("Failed to contact {0} at {1}.".format(
recip.user.username, recip.phone)) contact.user.username, contact.phone))
# TODO: update for superevents
def get_phone_recips(event):
triggers = event.pipeline.trigger_set.filter(labels=None) \
.prefetch_related('contacts')
phone_recips = [c for t in triggers for c in
t.contacts.all().select_related('user')
if ((not t.farThresh or (event.far and event.far < t.farThresh)) and
r.phone)]
return phone_recips
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment