diff --git a/gracedb/alert.py b/gracedb/alert.py
index a49175f89a5f9065ee76e2cdb48ee49537cda46b..a6ec2d79decc29289f7eb88858116c1047601891 100644
--- a/gracedb/alert.py
+++ b/gracedb/alert.py
@@ -50,6 +50,9 @@ def make_twilio_calls(event, twilio_recips, alert_type, **kwargs):
     # Get server name.
     hostname = socket.gethostname()
 
+    # Base URL for TwiML bins
+    twiml_base_url = settings.TWIML_BASE_URL
+
     if (alert_type == "create"):
         # twiml_base_url is the URL of a TwiML Bin
         # (https://support.twilio.com/hc/en-us/articles/230878368)
@@ -65,7 +68,7 @@ def make_twilio_calls(event, twilio_recips, alert_type, **kwargs):
         #     https://gracedb-test.ligo.org/events/view/{{graceid}}
         #     </Sms>
         #     </Response>
-        twiml_base_url = 'https://handler.twilio.com/twiml/' + settings.TWILIO_CREATE_KEY
+        twiml_base_url += settings.TWILIO_CREATE_KEY
         twiml_url = '{0}?pipeline={1}&graceid={2}&server={3}'.format(
             twiml_base_url, event.pipeline.name, event.graceid(), hostname)
     elif (alert_type == "label"):
@@ -83,7 +86,7 @@ def make_twilio_calls(event, twilio_recips, alert_type, **kwargs):
         #     https://gracedb-test.ligo.org/events/view/{{graceid}}
         #     </Sms>
         #     </Response>
-        twiml_base_url = 'https://handler.twilio.com/twiml/' + settings.TWILIO_LABEL_KEY
+        twiml_base_url += settings.TWILIO_LABEL_KEY
         label = kwargs['label']
         twiml_url = '{0}?pipeline={1}&graceid={2}&label={3}&label_lower={4}&server={5}'.format(
             twiml_base_url, event.pipeline.name, event.graceid(), label.name,
diff --git a/settings/default.py b/settings/default.py
index a6e6c9c99884feac0189aceff70af8251fdd09a1..2d6e665e2339be65120643e0841ca3d004ca15ab 100644
--- a/settings/default.py
+++ b/settings/default.py
@@ -18,6 +18,9 @@ ADMINS = (
     ('Tanner Prestegard', 'prestega@uwm.edu'),
 )
 
+# Base URL for TwiML bins
+TWIML_BASE_URL = 'https://handler.twilio.com/twiml/'
+
 SERVER_EMAIL = 'GraceDB <gracedb@gracedb.cgca.uwm.edu>'
 
 MANAGERS = ADMINS
diff --git a/templates/profile/notifications.html b/templates/profile/notifications.html
index 00a86fbe22b946075d03dce72e63b288505e579e..ffa5f317df6199340c212fea52346a98c3a4f9ae 100644
--- a/templates/profile/notifications.html
+++ b/templates/profile/notifications.html
@@ -11,6 +11,7 @@
     <ul>
         <li>
             <!-- <a href="{% url "userprofile-edit-contact" contact.id %}">Edit</a> -->
+            <a href="{% url "userprofile-test-contact" contact.id %}">Test</a>
             <a href="{% url "userprofile-delete-contact" contact.id %}">Delete</a>
             {{ contact.desc }} / {{ contact.email }} {{ contact.phone }}
         </li>
diff --git a/userprofile/urls.py b/userprofile/urls.py
index 21d3bd4c54246235c63f55a00a1272a372f14736..ebb627235a086471476e4e1d46403d43253c7509 100644
--- a/userprofile/urls.py
+++ b/userprofile/urls.py
@@ -4,15 +4,27 @@
 from django.conf.urls import patterns, url
 
 urlpatterns = patterns('userprofile.views',
-    url (r'^$', 'index', name="userprofile-home"),
-    url (r'^contact/create$', 'createContact', name="userprofile-create-contact"),
-    url (r'^contact/delete/(?P<id>[\d]+)$', 'deleteContact', name="userprofile-delete-contact"),
-    url (r'^contact/edit/(?P<id>[\d]+)$', 'editContact', name="userprofile-edit-contact"),
+    # Base /options/ URL
+    url(r'^$', 'index', name="userprofile-home"),
 
-    url (r'^trigger/create$', 'create', name="userprofile-create"),
-    url (r'^trigger/delete/(?P<id>[\d]+)$', 'delete', name="userprofile-delete"),
-    url (r'^trigger/edit/(?P<id>[\d]+)$', 'edit', name="userprofile-edit"),
+    # /options/contact/
+    url(r'^contact/create$', 'createContact',
+        name="userprofile-create-contact"),
+    url(r'^contact/delete/(?P<id>[\d]+)$', 'deleteContact',
+        name="userprofile-delete-contact"),
+    url(r'^contact/test/(?P<id>[\d]+)$', 'testContact',
+        name="userprofile-test-contact"),
+    url(r'^contact/edit/(?P<id>[\d]+)$', 'editContact',
+        name="userprofile-edit-contact"),
 
-    url (r'^manage_password$', 'managePassword', name="userprofile-manage-password"),
+    # /options/trigger/
+    url(r'^trigger/create$', 'create', name="userprofile-create"),
+    url(r'^trigger/delete/(?P<id>[\d]+)$', 'delete',
+        name="userprofile-delete"),
+    url(r'^trigger/edit/(?P<id>[\d]+)$', 'edit', name="userprofile-edit"),
+
+    # /options/manage_password
+    url(r'^manage_password$', 'managePassword',
+        name="userprofile-manage-password"),
 
 )
diff --git a/userprofile/views.py b/userprofile/views.py
index 65fcbaac8d8481bdf9c3125ace70db91bd2bc16a..24ab56fb469df583a3b0956c729db1c1b9ef2dcd 100644
--- a/userprofile/views.py
+++ b/userprofile/views.py
@@ -1,25 +1,25 @@
 
-from django.http import HttpResponse
-from django.http import HttpResponseRedirect, HttpResponseNotFound
-from django.http import Http404, HttpResponseForbidden
-from django.http import HttpResponseBadRequest
-
+from django.http import (HttpResponse, HttpResponseRedirect, 
+    HttpResponseNotFound, Http404, HttpResponseForbidden,
+    HttpResponseBadRequest)
+from django.conf import settings
 from django.core.urlresolvers import reverse 
+from django.core.mail import EmailMessage
 from django.contrib.auth.models import User
 from django.template import RequestContext
 from django.shortcuts import render_to_response
+from django.utils import timezone
+from django.db.models import Q
 
-from models import Trigger, Contact
-
-from forms import ContactForm, triggerFormFactory
+from django_twilio.client import twilio_client
+import socket
 
+from .models import Trigger, Contact
+from .forms import ContactForm, triggerFormFactory
 from gracedb.permission_utils import internal_user_required, lvem_user_required
-
-from django.utils import timezone
-
 from gracedb.query import labelQuery
 from gracedb.models import Label
-from django.db.models import Q
+from gracedb.alert import get_twilio_from
 
 # Let's let everybody onto the index view.
 #@internal_user_required
@@ -157,6 +157,43 @@ def createContact(request):
                               },
                               context_instance=RequestContext(request))
 
+@internal_user_required
+def testContact(request, id):
+    """Users can test their Contacts through the web interface"""
+    try:
+        c = Contact.objects.get(id=id)
+    except Contact.DoesNotExist:
+        raise Http404
+    if request.user != c.user:
+        return HttpResponseForbidden("NO!")
+    else:
+        flash_msg = "Testing contact %s." % c.desc
+        hostname = socket.gethostname()
+        if c.email:
+            # Send test e-mail
+            try:
+                subject = "Test of contact %s from %s" % (c.desc, hostname)
+                message = ("This is test of contact %s on server %s," 
+                           " e-mailed to %s") % (c.desc, hostname, c.email) 
+                email = EmailMessage(subject, message, settings.SERVER_EMAIL, 
+                                     [c.email], [])
+                email.send()
+            except:
+                flash_msg += " Error sending test e-mail to %s." % c.email
+        if c.phone:
+            # Send test phone alert
+            try:
+                from_ = get_twilio_from()
+                twiml_url = settings.TWIML_BASE_URL + settings.TWILIO_TEST_KEY
+                twiml_url += '?server={0}&type={1}'.format(
+                    hostname,hostname.split('-')[1])
+                twilio_client.calls.create(c.phone, from_, twiml_url,
+                                           method='GET')
+            except Exception as e:
+                flash_msg += " Error calling %s." % e
+
+        request.session['flash_msg'] = flash_msg
+        return index(request)
 
 @internal_user_required
 def editContact(request, id):
@@ -164,6 +201,8 @@ def editContact(request, id):
 
 @internal_user_required
 def deleteContact(request, id):
+    """Users can delete their Contacts through the web interface"""
+
     try:
         c = Contact.objects.get(id=id)
     except Contact.DoesNotExist: