diff --git a/README.md b/README.md new file mode 100644 index 0000000..abb43e8 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Trigger a PagerDuty incident from a phone call + +This is not an officially supported PagerDuty product, and not covered by our SLA. But I do work for PagerDuty, so feel free to [email me](mailto:dave@pagerduty.com) about it. + +# Requirements + +1. Set up a [PagerDuty account](http://www.pagerduty.com/pricing) if you don't already have one, and create a Generic API service. We'll use the Service API key. +2. You'll need to set up a Google App Engine account, and create an application. We'll use the application identifier. +3. Change the "application: pdtestthrough" line in app.yaml to your application identifier, and the SERVICE_KEY = "6f4d18600a9b012f6a9722000a9040cf" line in main.py to your service API key +4. Deploy to [Google App Engine](https://appengine.google.com) +5. Create a [Twilio](http://twilio.com) account, and set up an incoming phone number to point to http://[your-application-identifier].appspot.com/call +6. Call that number and leave a message. + +# Walkthrough + +!(help/TwilioConfig.png) + diff --git a/help/AppEngineApplication.png b/help/AppEngineApplication.png new file mode 100644 index 0000000..7f99140 Binary files /dev/null and b/help/AppEngineApplication.png differ diff --git a/help/PagerDutyAPI.png b/help/PagerDutyAPI.png new file mode 100644 index 0000000..c45f72f Binary files /dev/null and b/help/PagerDutyAPI.png differ diff --git a/help/TwilioConfig.png b/help/TwilioConfig.png new file mode 100644 index 0000000..22a7f5c Binary files /dev/null and b/help/TwilioConfig.png differ diff --git a/main.py b/main.py index 7ece9e1..2d7a81b 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,14 @@ - +# PagerDuty incidents triggered by phone: import logging from urllib2 import Request, urlopen, URLError, HTTPError import urllib from django.utils import simplejson as json - from google.appengine.ext import webapp from google.appengine.ext.webapp import util +SERVICE_KEY = "6f4d18600a9b012f6a9722000a9040cf" +#Half of the code is just dedicated to URL shortening, so that we can fit the MP3's URL in an SMS: def shorten(url): gurl = 'http://goo.gl/api/url?url=%s' % urllib.unquote(url) req = Request(gurl, data='') @@ -17,13 +18,14 @@ def shorten(url): res = urlopen(req) results = json.load(res) logging.info( res.code ) - except HTTPError, e: #triggers on code 201 + except HTTPError, e: #triggers on HTTP code 201 logging.info( e.code ) error_content = e.read() results = json.JSONDecoder().decode(error_content) return results['short_url'] +# Outbput the TwilML to record a message and pass it to /record class CallHandler(webapp.RequestHandler): def get(self): response = ("" @@ -32,24 +34,22 @@ def get(self): "I did not receive a recording") self.response.out.write(response) logging.info('Recieved CALL ' + self.request.query_string) + +# Shorten the URL and trigger a PD incident with it class RecordHandler(webapp.RequestHandler): def get(self): response = ("Thanks. Directing your message to the agent on call.") self.response.out.write(response) - logging.info('Recieved RECORDING0 ' + self.request.query_string) + logging.info('Recieved RECORDING: ' + self.request.query_string) recUrl = self.request.get("RecordingUrl") phonenumber = self.request.get("From") - - - logging.info('Recieved RECORDING1 ' + recUrl) + + logging.info('Recieved RECORDING ' + recUrl) if(recUrl): logging.info('Found recording!') else: recUrl = "http%3A%2F%2Fwww.pagerduty.com%2F" phonenumber = "" - - logging.info('Recieved RECORDING2 ' + recUrl) - shrten = "Error" try: @@ -64,21 +64,32 @@ def get(self): logging.info('Shortened to: ' + shrten) # Obviously use your own key: - incident = '{"service_key": "6f4d18600a9b012f6a9722000a9040cf","incident_key": "%s","event_type": "trigger","description": "%s %s"}'%(shrten,shrten,phonenumber) + incident = '{"service_key": "%s","incident_key": "%s","event_type": "trigger","description": "%s %s"}'%(SERVICE_KEY,shrten,shrten,phonenumber) try: r = Request("http://events.pagerduty.com/generic/2010-04-15/create_event.json", incident) #Note according to the API this should be retried on failure results = urlopen(r) + logging.info(incident) logging.info(results) except HTTPError, e: logging.warn( e.code ) except URLError, e: logging.warn(e.reason) +class IndexHandler(webapp.RequestHandler): + def get(self): + response = ("

Trigger a PagerDuty incident from a phone call

Remember to change the application identifier and the service API key, or else you'll just alert me :)") + self.response.out.write(response) def main(): application = webapp.WSGIApplication([ ('/call', CallHandler), - ('/record', RecordHandler)], + ('/record', RecordHandler), + ('/', IndexHandler)], debug=True) util.run_wsgi_app(application)