This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Initial Commit

  • Loading branch information...
kyleconroy committed Feb 23, 2011
0 parents commit e44a7191538b2d1a1fc43a4828c4a20409556351
130 Makefile
@@ -0,0 +1,130 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/TwilioAPI.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/TwilioAPI.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/TwilioAPI"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/TwilioAPI"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+"""
+ sphinx.domains.ruby
+ ~~~~~~~~~~~~~~~~~~~
+
+ The Ruby domain.
+
+ :copyright: Copyright 2010 by SHIBUKAWA Yoshiki
+ :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+
+from sphinx import addnodes
+from sphinx.roles import XRefRole
+from sphinx.locale import l_, _
+from sphinx.domains import Domain, ObjType, Index
+from sphinx.directives import ObjectDescription
+from sphinx.util.compat import Directive
+from sphinx.util.docfields import Field, GroupedField, TypedField
+
+
+class RestObject(ObjectDescription):
+ """
+ Description of a general Rest object.
+ """
+ has_arguments = False
+
+
+class RestResource(RestObject):
+ """
+ Description of a Rest Reosource
+ """
+ has_arguments = True
+
+
+class RestXRefRole(XRefRole):
+ pass
+
+
+class RestDomain(Domain):
+ """Rest language domain."""
+ name = 'rest'
+ label = 'REST'
+ object_types = {
+ 'attribute': ObjType(l_('attribute'), 'attr'),
+ 'resource': ObjType(l_('resource'), 'resc'),
+ }
+
+ directives = {
+ 'resource': RestResource,
+ 'attribute': RestObject,
+ }
+
+ roles = {
+ 'resc': RestXRefRole(),
+ }
+
+ initial_data = {
+ 'resources': {}, # fullname -> docname, objtype
+ }
+
+def setup(app):
+ app.add_domain(RestDomain)
Binary file not shown.
@@ -0,0 +1,44 @@
+============================
+Availability and Reliability
+============================
+
+Fallback URLs
+---------------
+
+Twilio maintains a redundant, clustered architecture designed to ensure reliable high availability service. This is only half of the challenge. Because of the distributed nature of a Twilio application, your web application must be reliable and highly available as well. To aid you in this task, Twilio allows the configuration of "Fallback" URLs on incoming phone numbers via your Account Portal or the REST API's IncomingPhoneNumbers resource.
+
+A Fallback URL is a URL that Twilio requests in the event of a fatal error while executing your call. If Twilio is unable to retrieve or execute TwiML from your web server, a request is immediately made to the appropriate Fallback URL. Twilio will submit the 'ErrorCode' and 'ErrorUrl' parameters, indicating the error code of the failure and what URL the failure occurred on. You can reply to the fallback URL request with more TwiML, returning a custom application error message, or attempting to recover and continue your call or SMS session.
+
+Example Use Cases
+>>>>>>>>>>>>>>>>>>
+
+Primary Web Server Failover
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Problem**: you want to make sure your Twilio application continues to accept calls, even if
+your primary web server goes down.
+
+**Solution**: Configure your incoming phone number's Voice URL to ``http://www.mysite.com/index`` and Voice Fallback URL to ``http://fallback.mysite.com/index``. If Twilio requests ``http://www.mysite.com/index`` and receives an HTTP error or connection failure, it will then request ``http://fallback.mysite.com/index``. If the fallback URL responds with valid TwiML, Twilio will use it to continue the call as if there was no problem.
+
+Custom Error Message
+~~~~~~~~~~~~~~~~~~~~~~~
+**Problem**: You do not want your callers to hear the default Twilio application error message.
+
+**Solution**: Create an error TwiML document to <Say> or <Play> a custom error message. Configure the Voice Fallback URL for your phone number to point at this document's URL. If Twilio encounters a fatal error, callers will hear your custom failure message instead of Twilio's.
+
+.. code-block:: xml
+
+ <?xml version="1.0" encoding="UTF-8" ?>
+ <Response>
+ <Say>
+ An application error has occured.
+ Please call back later
+ </Say>
+ </Response>
+
+Catching Errors
+~~~~~~~~~~~~~~~
+
+**Problem**: You want to be notified of errors as they occur.
+
+**Solution**: Configure your Fallback URL to point at a URL that looks for the 'ErrorCode' and 'ErrorUrl' parameters. Your application can log these errors, email you an alert, etc. You can respond to the request with TwiML containing an error message for the caller or attempt to recover and continue with the call.
@@ -0,0 +1,71 @@
+<?php
+ // This function calculates the HMAC hash of the data with the key passed in
+ // Note: hash_hmac requires PHP 5 >= 5.1.2 or PECL hash:1.1-1.5
+ // Or http://pear.php.net/package/Crypt_HMAC/
+ function calculate_twilio_signature($key, $data) {
+ $sig = base64_encode(hash_hmac("sha1", $data, $key, true));
+ return $sig;
+ }
+
+
+ // this function assembles the data to sign from the $_SERVER and $_POST superglobals
+ function build_twilio_data_string() {
+
+ // Our data string starts with the full URL
+
+ // Note, that if your URL uses an implied "index" document (index.php), then apache
+ // often adds a slash to the SCRIPT_URI while Twilio's original request will not have a slash
+ // Example: if Twilio requested http://mycompany.com/twilio
+ // and that url is handled by an index.php script
+ // Apache/PHP will report the URI as being: http://mycompany.com/twilio/
+ // But the hash should be calculated without the trailing slash
+
+ // Also note, if you're using URL rewriting, then you should check to see that
+ // PHP is reporting your SCRIPT_URI and QUERY_STRING correctly.
+
+ $string_to_sign = $_SERVER['SCRIPT_URI'];
+
+ // if there's a query string, add it here along with the question mark
+ if(strlen($_SERVER['QUERY_STRING']))
+ $string_to_sign .= "?{$_SERVER['QUERY_STRING']}";
+
+ // Now, if it's a POST, then we need to add the POST parameters
+ // alphabetized to the data string
+ if(isset($_POST)) {
+
+ // copy the post data
+ $data = $_POST;
+
+ // sort the array by keys
+ ksort($data);
+
+ // append them to the data string in order with no delimiters
+ foreach($data AS $key=>$value)
+ $string_to_sign .= "$key$value";
+
+ }
+
+ return $string_to_sign;
+
+ }
+
+ // Use your Twilio AuthToken here. Case matters.
+ $MY_KEY = "1234567890ABCDEF";
+
+ // Get the signature sent by twilio in the HTTP Headers
+ // PHP exposes HTTP headers in the $_SERVER superglobal array
+ // in all upper case, with underscores instead of dashes, with the word "HTTP_" prefixed
+ $expected_signature = $_SERVER["HTTP_X_TWILIO_SIGNATURE"];
+
+ // Build the data string to sign
+ $data_to_sign = build_twilio_data_string();
+
+ // sign it
+ $calculated_signature = calculate_twilio_signature($MY_KEY, $data_to_sign);
+
+ // if signatures match, then it's authenticated
+ if($calculated_signature == $expected_signature)
+ echo "Match!";
+ else
+ echo "Uh oh";
+ ?>
@@ -0,0 +1,7 @@
+<?php
+ header("content-type: text/xml");
+ echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+?>
+<Response>
+ <Say>Hello Monkey</Say>
+</Response>
@@ -0,0 +1,22 @@
+<?php
+
+ // make an associative array of callers we know, indexed by phone number
+ $people = array(
+ "+14158675309"=>"Curious George",
+ "+14158675310"=>"Boots",
+ "+14158675311"=>"Virgil",
+ "+14158675312"=>"Marcel"
+ );
+
+ // if the caller is known, then greet them by name
+ // otherwise, consider them just another monkey
+ if(!$name = $people[$_REQUEST['From']])
+ $name = "Monkey";
+
+ // now greet the caller
+ header("content-type: text/xml");
+ echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+?>
+<Response>
+ <Say>Hello <?php echo $name ?>.</Say>
+</Response>
@@ -0,0 +1,23 @@
+<?php
+
+ // make an associative array of callers we know, indexed by phone number
+ $people = array(
+ "+14158675309"=>"Curious George",
+ "+14158675310"=>"Boots",
+ "+14158675311"=>"Virgil",
+ "+14158675312"=>"Marcel"
+ );
+
+ // if the caller is known, then greet them by name
+ // otherwise, consider them just anohter monkey
+ if(!$name = $people[$_REQUEST['From']])
+ $name = "Monkey";
+
+ // now greet the caller
+ header("content-type: text/xml");
+ echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+?>
+<Response>
+ <Say>Hello <?php echo $name ?>.</Say>
+ <Play>http://demo.twilio.com/hellomonkey/monkey.mp3</Play>
+</Response>
@@ -0,0 +1,16 @@
+<?php
+
+ // if the caller pressed anything but 1 send them back
+ if($_REQUEST['Digits'] != '1') {
+ header("Location: hello-monkey.php");
+ die;
+ }
+
+ // the user pressed 1, connect the call to 310-555-1212
+ header("content-type: text/xml");
+ echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+?>
+<Response>
+ <Dial>+13105551212</Dial>
+ <Say>The call failed or the remote party hung up. Goodbye.</Say>
+</Response>
Oops, something went wrong.

0 comments on commit e44a719

Please sign in to comment.