Skip to content
This repository has been archived by the owner on Nov 10, 2017. It is now read-only.

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kyleconroy committed Feb 23, 2011
0 parents commit e44a719
Show file tree
Hide file tree
Showing 29 changed files with 1,302 additions and 0 deletions.
130 changes: 130 additions & 0 deletions 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."
67 changes: 67 additions & 0 deletions _exts/restdomain.py
@@ -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 added _exts/restdomain.pyc
Binary file not shown.
44 changes: 44 additions & 0 deletions availability.rst
@@ -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.
71 changes: 71 additions & 0 deletions code/api/signature-validation.php
@@ -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";
?>
7 changes: 7 additions & 0 deletions code/quickstart/twiml/1.0/hello-monkey.php
@@ -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>
22 changes: 22 additions & 0 deletions code/quickstart/twiml/1.1/hello-monkey.php
@@ -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>
23 changes: 23 additions & 0 deletions code/quickstart/twiml/1.2/hello-monkey.php
@@ -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>
16 changes: 16 additions & 0 deletions code/quickstart/twiml/1.3/hello-monkey-handle-key.php
@@ -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>

0 comments on commit e44a719

Please sign in to comment.