[
  {
    "path": ".gitignore",
    "content": "**/node_modules\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "sipgate.io Changelog\n====================\n\n1.6.0 Noah (2015-05-08)\n-----------------------\n***Features***\n* sipgate.io available in basic\n* sipgate.io available in team (beta)\n* POST request for end of call\n\n1.5.0 Emil (2014-11-27)\n-----------------------\n***Features***\n* Set a custom caller id\n\n1.4.0 Frida (2014-11-20)\n-----------------------\n***Features***\n* POST request for outgoing calls\n\n1.3.0 Phil (2014-11-18)\n-----------------------\n***Features***\n* Play WAV file from a given URL\n* ```<Play>``` ```<Url>``` example XML in README.md\n* Hang up calls\n* ```<Hangup>``` example XML in README.md\n* Update examples\n\n***Resolved issues***\n* Client doesn't support compression, despite it being advertised in Accept-Encoding ([#11](https://github.com/sipgate/sipgate.io/issues/11))\n\n1.2.0 Levi (2014-10-22)\n-----------------------\n***Features***\n* Send call to voicemail or external number\n* ```<Dial>``` ```<Number>``` example XML in README.md\n* ```<Dial>``` ```<Voicemail>``` example XML in README.md\n* Update examples\n\n***Resolved issues***\n* XML response not understood by sipgate.io's server ([#6](https://github.com/sipgate/sipgate.io/issues/6))\n* Content-Type: text/xml support ([#7](https://github.com/sipgate/sipgate.io/issues/7))\n* Chunked encoded response is not processed ([#8](https://github.com/sipgate/sipgate.io/issues/8))\n* ```from``` and ```to``` not always correct ([#9](https://github.com/sipgate/sipgate.io/issues/9))\n\n1.1.0 Nico (2014-10-14)\n-----------------------\n***Features***\n* Reject calls with ```Reject```\n* ```Reject``` example XML in README.md\n* Update examples\n* Add this cool CHANGELOG.md\n* C++ example from  [Papierkorb](https://github.com/Papierkorb)\n\n1.0.0 Brienne (2014-10-06)\n--------------------------\n***Features***\n* First release\n* POST request with ```from``` and ```to```\n* Perl example from [fuglu](https://github.com/fuglu)\n* Ruby example from [fuglu](https://github.com/fuglu)\n* Python example from [scgitsip](https://github.com/scgitsip)\n* PHP example from [tpxtron](https://github.com/tpxtron)\n* Java example from [scgitsip](https://github.com/scgitsip)\n* Go example from [vileda](https://github.com/vileada)\n* Common Lisp example from [olivermg](https://github.com/olivermg)\n* Clojure example from [olivermg](https://github.com/olivermg)\n* Prolog example from [kr1schan](https://github.com/kr1schan)\n* Scala example from [fnordian](https://github.com/fnordian)\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2014, sipgate GmbH\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer. \n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nThe views and conclusions contained in the software and documentation are those\nof the authors and should not be interpreted as representing official policies, \neither expressed or implied, of the FreeBSD Project.\n"
  },
  {
    "path": "README.md",
    "content": "# sipgate.io\n\nThis README documents [sipgate.io](https://www.sipgate.io), a real-time telephony API by [sipgate](http://www.sipgate.de). There's a [demo page](https://demo.sipgate.io), [code examples](https://github.com/sipgate/sipgate.io/tree/master/examples), and a [newsletter](http://mailing.sipgate.de/f/42695-161642/).\n\nFor more code samples in javascript, java or python visit [github.com/sipgate-io](https://github.com/sipgate-io).\n\n## Table of Contents\n\n- [sipgate.io](#sipgateio)\n- [Requirements](#requirements)\n  - [Usage with sipgate team](#usage-with-sipgate-team)\n- [Reference](#reference)\n- [Help us make it better](#help-us-make-it-better)\n\n## Requirements\n\n### Usage with sipgate team\n\n- [x] Book sipgate.io in your team account (incurs monthly cost) or [request access to our developer program (free!)](http://goo.gl/forms/8TS8kQj6kx)\n- [x] [After receiving the confirmation mail enter an URL for incoming/outgoing calls in sipgate team settings](https://app.sipgate.com/io)\n\n## Usage\n\nTo find out how to use sipgate.io go to our [Developer Documentation portal](https://developer.sipgate.io/push-api/setup/).\n\n# Help us make it better\n\nPlease tell us how we can improve sipgate.io. If you have a specific feature request, found a bug or would like to add an example, please use [GitHub Issues](https://github.com/sipgate/sipgate.io/issues) or fork these docs and send a [pull request](https://github.com/sipgate/sipgate.io/pulls) with your improvements.\n"
  },
  {
    "path": "README_CONNECT.md",
    "content": "sipgate.io connect\n==================\n\nsipgate.io extends your web application with real-time telephony data: We push call meta data to your web server for each call to a sipgate.io phone number. That way your application can display a caller's contact info and history, among other things. [See more information and use cases](https://www.sipgate.io)\n\nAdd the sipgate.io connect button to offer your customers this additional value in the easist way possible. \n\nThis README shows how to integrate sipgate.io connect into your application:\n* Variables to pass into the signup process\n* Form template to get you started\n\nPlease refer to the general [sipgate.io README](https://github.com/sipgate/sipgate.io/blob/master/README.md)\nto learn which information sipgate.io passes to your application and how.\n\nFeel free to check out the [sipgate.io connect demo page](https://demo.sipgate.io/connect) as well as the\n[sipgate.io demo page](https://demo.sipgate.io).\n\n\nVariables to pass in the GET request\n================\n\nParameter  | Description\n---------- | -----------\nurl        | sipgate.io will pass call meta data to this URL\nsuccessUrl | After signup we offer your users a link to this URL to return to your application\nsiteName   | The name of your application. We refer to your application several times throughout signup\n\n\nButton and Form Template\n================\n\nYou can copy+paste this form for calling sipgate.io connect:\n\n```html\n<form method=\"GET\" action=\"https://sipgate.io/de/connect\">\n    <p>\n\t    Connect this application with telephony so that calls are immediately displayed here\n\t</p>\n\t<input type=\"hidden\" name=\"url\" value=\"https://example.com/io-target/\">\n\t<input type=\"hidden\" name=\"successUrl\" value=\"https://example.com/connected-to-io\">\n\t<input type=\"hidden\" name=\"siteName\" value=\"YourAwesomeApplication\">\n    <br>\n    <button class=\"btn btn-primary btn-lg\">Connect with telephony</button>\n</form>\n```\n\nPlease make sure to replace the values of the hidden fields with correct ones.\n\nHelp us make it better\n======================\n\nPlease tell us how we can improve sipgate.io connect. If you have a specific feature request, found a bug or would like to add an example, please use contact support@sipgate.io. Thank you!\n"
  },
  {
    "path": "examples/c++/nuria/reject/reject.cpp",
    "content": "/* This is an example on how to create a fully functional HTTP server for use\n * with the sipgate.io API based on the NuriaProject Framework.\n * See: https://github.com/NuriaProject/Framework\n */\n\n#include <QCoreApplication>\n#include <QXmlStreamWriter>\n#include <nuria/httpclient.hpp>\n#include <nuria/httpserver.hpp>\n#include <nuria/httpnode.hpp>\n#include <nuria/debug.hpp>\n\nvoid mySlot (Nuria::HttpClient *client) {\n\tNuria::HttpPostBodyReader *reader = client->postBodyReader ();\n\tif (!reader) {\n\t\tclient->killConnection (400);\n\t\treturn;\n\t}\n\n\tnLog() << \"Rejecting call\" << reader->fieldValue (\"from\") << \"->\" << reader->fieldValue (\"to\");\n\tclient->setResponseHeader (Nuria::HttpClient::HeaderContentType, \"application/xml\");\n\t\n\tQXmlStreamWriter stream (client);\n\tstream.writeStartDocument ();\n\tstream.writeStartElement (\"Response\");\n\tstream.writeStartElement (\"Reject\");\n\tstream.writeEndElement (); // /Reject\n\tstream.writeEndElement (); // /Response\n\tstream.writeEndDocument ();\n}\n\nint main (int argc, char *argv[]) {\n\tQCoreApplication a (argc, argv);\n\tNuria::HttpServer server;\n\n\tserver.root ()->connectSlot (\"index\", mySlot);\n\n\tif (!server.listen (QHostAddress::Any, 3000)) {\n\t\tnError() << \"Failed to listen on port 3000.\";\n\t\treturn 1;\n\t}\n\n\tnLog() << \"Listening on all interfaces on port 3000.\";\n\treturn a.exec ();\n}\n"
  },
  {
    "path": "examples/c++/nuria/reject/reject.pro",
    "content": "# Example project file for a sipgate.io HTTP server\nTEMPLATE = app\nTARGET = reject\nINCLUDEPATH += .\n\n# Dependency to the NuriaProject Framework\n# See https://github.com/NuriaProject/Framework\nCONFIG += nuria\nNURIA += core network\n\n# \nSOURCES += reject.cpp\n"
  },
  {
    "path": "examples/c++/nuria/simple/simple.cpp",
    "content": "/* This is an example on how to create a fully functional HTTP server for use\n * with the sipgate.io API based on the NuriaProject Framework.\n * See: https://github.com/NuriaProject/Framework\n */\n\n#include <QCoreApplication>\n#include <nuria/httpclient.hpp>\n#include <nuria/httpserver.hpp>\n#include <nuria/httpnode.hpp>\n#include <nuria/debug.hpp>\n\nvoid mySlot (Nuria::HttpClient *client) {\n\tNuria::HttpPostBodyReader *reader = client->postBodyReader ();\n\tif (!reader) {\n\t\tclient->killConnection (400);\n\t\treturn;\n\t}\n\n\tnLog() << \"Incoming call\" << reader->fieldValue (\"from\") << \"->\" << reader->fieldValue (\"to\");\n}\n\nint main (int argc, char *argv[]) {\n\tQCoreApplication a (argc, argv);\n\tNuria::HttpServer server;\n\n\tserver.root ()->connectSlot (\"index\", mySlot);\n\n\tif (!server.listen (QHostAddress::Any, 3000)) {\n\t\tnError() << \"Failed to listen on port 3000.\";\n\t\treturn 1;\n\t}\n\n\tnLog() << \"Listening on all interfaces on port 3000.\";\n\treturn a.exec ();\n}\n"
  },
  {
    "path": "examples/c++/nuria/simple/simple.pro",
    "content": "# Example project file for a sipgate.io HTTP server\nTEMPLATE = app\nTARGET = simple\nINCLUDEPATH += .\n\n# Dependency to the NuriaProject Framework\n# See https://github.com/NuriaProject/Framework\nCONFIG += nuria\nNURIA += core network\n\n# \nSOURCES += simple.cpp\n"
  },
  {
    "path": "examples/clojure/project.clj",
    "content": "(defproject sipgateio \"0.1.0-SNAPSHOT\"\n  :description \"simple sipgate.io example\"\n  :url \"https://github.com/sipgate/sipgate.io/tree/master/examples/clojure\"\n  :dependencies [[org.clojure/clojure \"1.6.0\"]\n                 [ring \"1.3.1\"]]\n  :main sipgateio.server)\n"
  },
  {
    "path": "examples/clojure/src/sipgateio/server.clj",
    "content": ";;\n;; This assumes you are using leiningen (http://leiningen.org/)\n;; You can then run this project via\n;; $ lein run\n;;\n;; For complete example (including project file) please look at\n;; https://github.com/sipgate/sipgate.io/tree/master/examples/clojure\n;;\n\n(ns sipgateio.server\n  (:gen-class))\n\n(use 'ring.adapter.jetty\n     'ring.middleware.params)\n\n(defn handler [{params :params}]\n  (println (str \"Call from \" (params \"from\") \" to \" (params \"to\")))\n  {:status 200 :body \"I love the JVM\" })\n\n(defn -main\n  [& args]\n  (run-jetty (wrap-params handler) {:port 3000}))\n\n"
  },
  {
    "path": "examples/commonlisp/server.lisp",
    "content": ";; This example uses hunchentoot as webserver.\n;; You can obtain it from http://weitz.de/hunchentoot/\n;;\n;; If you use quicklisp, you can simply install it by evaluating\n;; (ql:quickload \"hunchentoot\")\n\n(require :hunchentoot)\n(use-package :hunchentoot)\n\n(define-easy-handler (incoming-handler :uri \"/\") (from to)\n  (log-message* :info \"got call from ~a to ~a~%\" from to)\n  \"girls just wanna defun!\")\n\n(defparameter *server* (start (make-instance 'easy-acceptor\n\t\t\t\t\t     :port 3000)))\n\n;; to stop server: (stop *server*)\n"
  },
  {
    "path": "examples/go/server.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tr.ParseForm()\n\n\tfrom := r.Form.Get(\"from\")\n\tto := r.Form.Get(\"to\")\n\tdirection := r.Form.Get(\"direction\")\n\n\tfmt.Printf(\"from: %s\\n\", from)\n\tfmt.Printf(\"to: %s\\n\", to)\n\tfmt.Printf(\"direction: %s\\n\", direction)\n\n\tfmt.Fprintf(w, \"So Long, and Thanks for All the Fish!\")\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/\", handler)\n\thttp.ListenAndServe(\":3000\", nil)\n}\n"
  },
  {
    "path": "examples/java/dial.java",
    "content": "import java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.StringWriter;\nimport java.net.InetSocketAddress;\nimport java.util.ArrayList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerConfigurationException;\nimport javax.xml.transform.TransformerException;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\n\nimport org.w3c.dom.Attr;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\n\nimport com.sun.net.httpserver.Headers;\nimport com.sun.net.httpserver.HttpExchange;\nimport com.sun.net.httpserver.HttpHandler;\nimport com.sun.net.httpserver.HttpServer;\n\npublic class dial\n{\n\tpublic static void main(String[] args) throws Exception\n\t{\n\t\tHttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0);\n\t\thttpServer.createContext(\"/\", new AwesomeRejectHandler());\n\t\thttpServer.setExecutor(null);\n\t\thttpServer.start();\n\n\t\tSystem.out.println(\"Server running....\");\n\t\tSystem.out.println(\"Press CTRL+C to stop the server\");\n\t}\n\n\tstatic class AwesomeRejectHandler implements HttpHandler\n\t{\n\t\tpublic void handle(HttpExchange httpExchange) throws IOException\n\t\t{\n\t\t\tInputStream inputStream = httpExchange.getRequestBody();\n\t\t\tint charValue;\n\t\t\tArrayList<Character> chars = new ArrayList<Character>();\n\n\t\t\twhile ((charValue = inputStream.read()) != -1)\n\t\t\t{\n\t\t\t\tchars.add((char) charValue);\n\t\t\t}\n\n\t\t\tStringBuilder stringBuilder = new StringBuilder(chars.size());\n\n\t\t\tfor (Character character : chars)\n\t\t\t{\n\t\t\t\tstringBuilder.append(character);\n\t\t\t}\n\t\t\t// Print from, to and direction\n\t\t\tSystem.err.println(\"INFO: DATA: \" + stringBuilder.toString());\n\n\t\t\tString XMLResponse = \"\";\n\t\t\tXMLBuilder xmlBuilder;\n\t\t\ttry\n\t\t\t{\n\t\t\t\txmlBuilder = new XMLBuilder();\n\t\t\t\tif (stringBuilder.toString().contains(\"from=4915799912345\"))\n\t\t\t\t{\n\t\t\t\t\tXMLResponse = xmlBuilder.dial(\"4915791234567\");\n\t\t\t\t}\n\t\t\t\telse if (stringBuilder.toString().contains(\"from=491579987654\"))\n\t\t\t\t{\n\t\t\t\t\tXMLResponse = xmlBuilder.send2voicemail();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tXMLResponse = xmlBuilder.reject(\"busy\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (ParserConfigurationException e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\n\t\t\t// Print XML\n\t\t\tSystem.err.println(\"INFO: XML-Response: \" + XMLResponse);\n\n\t\t\tHeaders headers = httpExchange.getResponseHeaders();\n\t\t\theaders.set(\"Content-Type\", \"application/xml\");\n\t\t\theaders.set(\"Accept-Encoding\", \"gzip\");\n\t\t\thttpExchange.sendResponseHeaders(200, XMLResponse.length());\n\t\t\tOutputStream outputStream = httpExchange.getResponseBody();\n\t\t\toutputStream.write(XMLResponse.getBytes());\n\t\t\toutputStream.close();\n\t\t}\n\t}\n\n\tstatic class XMLBuilder\n\t{\n\t\tprivate Document document;\n\t\tprivate Element root;\n\n\t\tpublic XMLBuilder() throws ParserConfigurationException\n\t\t{\n\t\t\tDocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();\n\t\t\tDocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();\n\n\t\t\tDocument document = documentBuilder.newDocument();\n\t\t\tdocument.setXmlStandalone(true);\n\t\t\t//<Response> is the root tag \n\t\t\tthis.root = document.createElement(\"Response\");\n\t\t\tdocument.appendChild(this.root);\n\t\t\tthis.document = document;\n\t\t}\n\n\t\tprivate String dial(String number)\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Dial\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tElement xmlNodeNumber = document.createElement(\"Number\");\n\t\t\txmlNodeDial.appendChild(xmlNodeNumber);\n\t\t\txmlNodeNumber.setTextContent(number);\n\t\t\treturn build();\n\t\t}\n\n\t\tprivate String send2voicemail()\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Dial\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tElement xmlNodeVoicemail = document.createElement(\"Voicemail\");\n\t\t\txmlNodeDial.appendChild(xmlNodeVoicemail);\n\t\t\treturn build();\n\t\t}\n\t\t\n\t\tprivate String reject(String reason)\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Reject\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tAttr xmlAttribute = document.createAttribute(\"reason\");\n\t\t\txmlAttribute.setValue(reason);\n\t\t\txmlNodeDial.setAttributeNode(xmlAttribute);\n\t\t\treturn build();\n\t\t}\n\n\t\tprivate String build()\n\t\t{\n\t\t\tString XMLResponse = \"\";\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// Write the document into XMl format and return it\n\t\t\t\tTransformerFactory transformerFactory = TransformerFactory.newInstance();\n\t\t\t\tTransformer transformer = transformerFactory.newTransformer();\n\t\t\t\tDOMSource domSource = new DOMSource(document);\n\t\t\t\tStringWriter stringWriter = new StringWriter();\n\t\t\t\tStreamResult streamResult = new StreamResult(stringWriter);\n\t\t\t\ttransformer.transform(domSource, streamResult);\n\t\t\t\tXMLResponse = stringWriter.toString();\n\t\t\t}\n\t\t\tcatch (TransformerException tranformerException)\n\t\t\t{\n\t\t\t\ttranformerException.printStackTrace();\n\t\t\t}\n\t\t\treturn XMLResponse;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/java/play.java",
    "content": "import java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.StringWriter;\nimport java.net.InetSocketAddress;\nimport java.util.ArrayList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerConfigurationException;\nimport javax.xml.transform.TransformerException;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\n\nimport org.w3c.dom.Attr;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\n\nimport com.sun.net.httpserver.Headers;\nimport com.sun.net.httpserver.HttpExchange;\nimport com.sun.net.httpserver.HttpHandler;\nimport com.sun.net.httpserver.HttpServer;\n\npublic class play\n{\n\tpublic static void main(String[] args) throws Exception\n\t{\n\t\tHttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0);\n\t\thttpServer.createContext(\"/\", new AwesomeRejectHandler());\n\t\thttpServer.setExecutor(null);\n\t\thttpServer.start();\n\n\t\tSystem.out.println(\"Server running....\");\n\t\tSystem.out.println(\"Press CTRL+C to stop the server\");\n\t}\n\n\tstatic class AwesomeRejectHandler implements HttpHandler\n\t{\n\t\tpublic void handle(HttpExchange httpExchange) throws IOException\n\t\t{\n\t\t\tInputStream inputStream = httpExchange.getRequestBody();\n\t\t\tint charValue;\n\t\t\tArrayList<Character> chars = new ArrayList<Character>();\n\n\t\t\twhile ((charValue = inputStream.read()) != -1)\n\t\t\t{\n\t\t\t\tchars.add((char) charValue);\n\t\t\t}\n\n\t\t\tStringBuilder stringBuilder = new StringBuilder(chars.size());\n\n\t\t\tfor (Character character : chars)\n\t\t\t{\n\t\t\t\tstringBuilder.append(character);\n\t\t\t}\n\t\t\t// Print from, to and direction\n\t\t\tSystem.err.println(\"INFO: DATA: \" + stringBuilder.toString());\n\n\t\t\tString XMLResponse = \"\";\n\t\t\tXMLBuilder xmlBuilder;\n\t\t\ttry\n\t\t\t{\n\t\t\t\txmlBuilder = new XMLBuilder();\n\t\t\t\tif (stringBuilder.toString().contains(\"from=4915799912345\"))\n\t\t\t\t{\n\t\t\t\t\tXMLResponse = xmlBuilder.play(\"http://yourawesomewavfile.wav\");\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tcatch (ParserConfigurationException e)\n\t\t\t{\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\n\t\t\t// Print XML\n\t\t\tSystem.err.println(\"INFO: XML-Response: \" + XMLResponse);\n\n\t\t\tHeaders headers = httpExchange.getResponseHeaders();\n\t\t\theaders.set(\"Content-Type\", \"application/xml\");\n\t\t\theaders.set(\"Accept-Encoding\", \"gzip\");\n\t\t\thttpExchange.sendResponseHeaders(200, XMLResponse.length());\n\t\t\tOutputStream outputStream = httpExchange.getResponseBody();\n\t\t\toutputStream.write(XMLResponse.getBytes());\n\t\t\toutputStream.close();\n\t\t}\n\t}\n\n\tstatic class XMLBuilder\n\t{\n\t\tprivate Document document;\n\t\tprivate Element root;\n\n\t\tpublic XMLBuilder() throws ParserConfigurationException\n\t\t{\n\t\t\tDocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();\n\t\t\tDocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();\n\n\t\t\tDocument document = documentBuilder.newDocument();\n\t\t\tdocument.setXmlStandalone(true);\n\t\t\t//<Response> is the root tag \n\t\t\tthis.root = document.createElement(\"Response\");\n\t\t\tdocument.appendChild(this.root);\n\t\t\tthis.document = document;\n\t\t}\n\n\t\tprivate String dial(String number)\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Dial\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tElement xmlNodeNumber = document.createElement(\"Number\");\n\t\t\txmlNodeDial.appendChild(xmlNodeNumber);\n\t\t\txmlNodeNumber.setTextContent(number);\n\t\t\treturn build();\n\t\t}\n\n\t\tprivate String send2voicemail()\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Dial\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tElement xmlNodeVoicemail = document.createElement(\"Voicemail\");\n\t\t\txmlNodeDial.appendChild(xmlNodeVoicemail);\n\t\t\treturn build();\n\t\t}\n\t\t\n\t\tprivate String reject(String reason)\n\t\t{\n\t\t\tElement xmlNodeDial = document.createElement(\"Reject\");\n\t\t\troot.appendChild(xmlNodeDial);\n\t\t\tAttr xmlAttribute = document.createAttribute(\"reason\");\n\t\t\txmlAttribute.setValue(reason);\n\t\t\txmlNodeDial.setAttributeNode(xmlAttribute);\n\t\t\treturn build();\n\t\t}\n        \n\t\tprivate String play(String path)\n\t\t{\n\t\t\tElement xmlNodePlay = document.createElement(\"Play\");\n\t\t\troot.appendChild(xmlNodePlay);\n\t\t\tElement xmlNodeUrl = document.createElement(\"Url\");\n\t\t\txmlNodePlay.appendChild(xmlNodeUrl);\n\t\t\txmlNodeUrl.setTextContent(path);\n\t\t\treturn build();\n\t\t}\n\n\t\tprivate String build()\n\t\t{\n\t\t\tString XMLResponse = \"\";\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// Write the document into XMl format and return it\n\t\t\t\tTransformerFactory transformerFactory = TransformerFactory.newInstance();\n\t\t\t\tTransformer transformer = transformerFactory.newTransformer();\n\t\t\t\tDOMSource domSource = new DOMSource(document);\n\t\t\t\tStringWriter stringWriter = new StringWriter();\n\t\t\t\tStreamResult streamResult = new StreamResult(stringWriter);\n\t\t\t\ttransformer.transform(domSource, streamResult);\n\t\t\t\tXMLResponse = stringWriter.toString();\n\t\t\t}\n\t\t\tcatch (TransformerException tranformerException)\n\t\t\t{\n\t\t\t\ttranformerException.printStackTrace();\n\t\t\t}\n\t\t\treturn XMLResponse;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/java/reject.java",
    "content": "import java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.StringWriter;\nimport java.net.InetSocketAddress;\nimport java.util.ArrayList;\n\nimport javax.xml.parsers.DocumentBuilder;\nimport javax.xml.parsers.DocumentBuilderFactory;\nimport javax.xml.parsers.ParserConfigurationException;\nimport javax.xml.transform.Transformer;\nimport javax.xml.transform.TransformerException;\nimport javax.xml.transform.TransformerFactory;\nimport javax.xml.transform.dom.DOMSource;\nimport javax.xml.transform.stream.StreamResult;\n\nimport org.w3c.dom.Attr;\nimport org.w3c.dom.Document;\nimport org.w3c.dom.Element;\n\nimport com.sun.net.httpserver.Headers;\nimport com.sun.net.httpserver.HttpExchange;\nimport com.sun.net.httpserver.HttpHandler;\nimport com.sun.net.httpserver.HttpServer;\n\npublic class reject\n{\n\n\tpublic static void main(String[] args) throws Exception\n\t{\n\n\t\tHttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0);\n\t\thttpServer.createContext(\"/\", new AwesomeRejectHandler());\n\t\thttpServer.setExecutor(null);\n\t\thttpServer.start();\n\n\t\tSystem.out.println(\"Server running....\");\n\t\tSystem.out.println(\"Press CTRL+C to stop the server\");\n\t}\n\n\tstatic class AwesomeRejectHandler implements HttpHandler\n\t{\n\n\t\tpublic void handle(HttpExchange httpExchange) throws IOException\n\t\t{\n\n\t\t\tInputStream inputStream = httpExchange.getRequestBody();\n\t\t\tint charValue;\n\t\t\tArrayList<Character> chars = new ArrayList<Character>();\n\n\t\t\twhile ((charValue = inputStream.read()) != -1)\n\t\t\t{\n\t\t\t\tchars.add((char) charValue);\n\t\t\t}\n\n\t\t\tStringBuilder stringBuilder = new StringBuilder(chars.size());\n\n\t\t\tfor (Character character : chars)\n\t\t\t{\n\t\t\t\tstringBuilder.append(character);\n\t\t\t}\n\t\t\t// Print from, to and direction\n\t\t\tSystem.err.println(\"INFO: DATA: \" + stringBuilder.toString());\n\n\t\t\tString XMLResponse = \"\";\n\n\t\t\tif (stringBuilder.toString().contains(\"from=4915799912345\"))\n\t\t\t{\n\t\t\t\tXMLResponse = createXML(\"busy\"); // sent busy signal\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tXMLResponse = createXML(\"\"); // default reason value for reject\n\t\t\t}\n\n\t\t\t// Print XML\n\t\t\tSystem.err.println(\"INFO: XML-Response: \" + XMLResponse);\n\n\t\t\tHeaders headers = httpExchange.getResponseHeaders();\n\t\t\theaders.set(\"Content-Type\", \"application/xml\");\n\t\t\thttpExchange.sendResponseHeaders(200, XMLResponse.length());\n\n\t\t\tOutputStream outputStream = httpExchange.getResponseBody();\n\t\t\toutputStream.write(XMLResponse.getBytes());\n\t\t\toutputStream.close();\n\t\t}\n\n\t\t// Build XML with DOM and return as string\n\t\tpublic String createXML(String reason) throws IOException\n\t\t{\n\t\t\tString XMLResult = \"\";\n\n\t\t\ttry\n\t\t\t{\n\t\t\t\tDocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();\n\t\t\t\tDocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();\n\n\t\t\t\t// First node\n\t\t\t\tDocument document = documentBuilder.newDocument();\n\t\t\t\tdocument.setXmlStandalone(true);\n\t\t\t\tElement xmlNodeResponse = document.createElement(\"Response\");\n\t\t\t\tdocument.appendChild(xmlNodeResponse);\n\n\t\t\t\t// Second node\n\t\t\t\tElement xmlNodeReject = document.createElement(\"Reject\");\n\t\t\t\txmlNodeResponse.appendChild(xmlNodeReject);\n\n\t\t\t\t// Second node attribute\n\t\t\t\tif (!reason.isEmpty())\n\t\t\t\t{\n\t\t\t\t\tAttr xmlAttribute = document.createAttribute(\"reason\");\n\t\t\t\t\txmlAttribute.setValue(reason);\n\t\t\t\t\txmlNodeReject.setAttributeNode(xmlAttribute);\n\t\t\t\t}\n\n\t\t\t\t// Write the content into XMl format\n\t\t\t\tTransformerFactory transformerFactory = TransformerFactory.newInstance();\n\t\t\t\tTransformer transformer = transformerFactory.newTransformer();\n\n\t\t\t\tDOMSource domSource = new DOMSource(document);\n\n\t\t\t\tStringWriter stringWriter = new StringWriter();\n\n\t\t\t\tStreamResult streamResult = new StreamResult(stringWriter);\n\n\t\t\t\ttransformer.transform(domSource, streamResult);\n\t\t\t\tXMLResult = stringWriter.toString();\n\n\t\t\t}\n\t\t\tcatch (ParserConfigurationException parserConfigurationException)\n\t\t\t{\n\t\t\t\tparserConfigurationException.printStackTrace();\n\t\t\t}\n\t\t\tcatch (TransformerException tranformerException)\n\t\t\t{\n\t\t\t\ttranformerException.printStackTrace();\n\t\t\t}\n\t\t\treturn XMLResult.toString();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/java/server.java",
    "content": "import java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.InetSocketAddress;\nimport java.util.ArrayList;\n\nimport com.sun.net.httpserver.HttpExchange;\nimport com.sun.net.httpserver.HttpHandler;\nimport com.sun.net.httpserver.HttpServer;\n\npublic class server {\n\n\tpublic static void main(String[] args) throws Exception {\n\t\t// Create server with port 3000\n\t\tHttpServer httpserver = HttpServer.create(new InetSocketAddress(3000), 0);\n\t\thttpserver.createContext(\"/\", new MyHandler());\n\t\t// creates a default executor\n\t\thttpserver.setExecutor(null);\n\t\thttpserver.start();\n\n\t\tSystem.out.println(\"Server running....\");\n\t\tSystem.out.println(\"Press CTRL+C to stop the server\");\n\t}\n\n\tstatic class MyHandler implements HttpHandler {\n\t\tpublic void handle(HttpExchange httpexchange) throws IOException {\n\t\t\t//Read HTTP header\n\t\t\tInputStream is = httpexchange.getRequestBody();\n\t\t\tint charValue;\n\t\t\t\n\t\t\tArrayList<Character> chars = new ArrayList<Character>();\n\t\t\t\n\t\t\t// Print data from header\n\t\t\twhile ((charValue = is.read()) != -1) {\n\t\t\t\tchars.add((char) charValue);\n\t\t\t\tSystem.out.print((char) charValue);\n\t\t\t}\n\t\t\t\n\t\t\tStringBuilder builder = new StringBuilder(chars.size());\n\t\t\t\n\t\t\t//Build string from characters\n\t\t\tfor (Character ch : chars) {\n\t\t\t\tbuilder.append(ch);\n\t\t\t}\n\t\t\t\n\t\t\t//Check which number is calling\n\t\t\tif (builder.toString().contains(\"from=491234567890\"))\n\t\t\t\tSystem.out.println(\"\\nDo something here\");\n\n\t\t\tSystem.out.println(\"\\n200 OK\");\n\t\t\tOutputStream os = httpexchange.getResponseBody();\n\t\t\tos.close();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "examples/nodejs/express/.gitignore",
    "content": "node_modules\n"
  },
  {
    "path": "examples/nodejs/express/dial-number.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\nvar xml = require('xml');\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\n\tconsole.log(\"from: \" + from);\n\tconsole.log(\"to: \" + to);\n\tconsole.log(\"direction: \" + direction);\n\n\tresponse.set('Content-Type', 'application/xml');\n\tresponse.send(\n\t\txml({ Response: [\n\t\t\t{ Dial: [\n\t\t\t\t{ Number: \"4915799912345\" }\n\t\t\t] },\n\t\t] })\n\t);\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/express/dial-voicemail.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\nvar xml = require('xml');\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\n\tconsole.log(\"from: \" + from);\n\tconsole.log(\"to: \" + to);\n\tconsole.log(\"direction: \" + direction);\n\n\tresponse.set('Content-Type', 'application/xml');\n\tresponse.send(\n\t\txml({ Response: [\n\t\t\t{ Dial: [\n\t\t\t\t{ Voicemail: null }\n\t\t\t] },\n\t\t] })\n\t);\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/express/on-hangup.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\nvar xml = require('xml');\n\nvar calls = {};\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\tvar callId = request.body.callId;\n\n\tcalls[callId] = { \"from\": from, \"to\": to };\n\n\tconsole.log(\"call from: \" + from + \" to: \" + to + \" direction: \" + direction);\n\n\tresponse.set('Content-Type', 'application/xml');\n\tresponse.send(\n\t\txml({ Response: [\n\t\t\t{_attr: { onHangup: 'http://' + request.headers.host + '/hangup' }}\n\t\t] })\n\t);\n});\n\napp.post(\"/hangup\", function (request, response) {\n\tvar callId = request.body.callId;\n\n\tvar from = calls[callId][\"from\"]\n\tvar to = calls[callId][\"to\"]\n\n\tconsole.log(\"hang up call from: \" + from + \" to: \" + to + \"with cause: \" + request.body.cause);\n\n\tresponse.send();\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/express/package.json",
    "content": "{\n\t\"name\": \"sipgate.io\",\n\t\"description\": \"sipgate.io node.js example\",\n\t\"version\": \"0.0.1\",\n\t\"private\": true,\n\t\"engines\": {\n\t\t\"node\": \"0.10.x\"\n\t},\n\t\"dependencies\": {\n\t\t\"express\": \"~4.9.2\",\n\t\t\"body-parser\": \"~1.8.2\",\n\t\t\"xml\": \"~1.0.0\"\n\t}\n}\n"
  },
  {
    "path": "examples/nodejs/express/play-url.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\nvar xml = require('xml');\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\n\tconsole.log(\"from: \" + from);\n\tconsole.log(\"to: \" + to);\n\tconsole.log(\"direction: \" + direction);\n\n\tresponse.set('Content-Type', 'application/xml');\n\tresponse.send(\n\t\txml({ Response: [\n\t\t\t{ Play: [\n\t\t\t\t{ Url: \"http://www.example.com/example.wav\" }\n\t\t\t] },\n\t\t] })\n\t);\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/express/reject.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\nvar xml = require('xml');\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\n\tconsole.log(\"from: \" + from);\n\tconsole.log(\"to: \" + to);\n\tconsole.log(\"direction: \" + direction);\n\n\tresponse.set('Content-Type', 'application/xml');\n\tresponse.send(\n\t\txml({ Response: [\n\t\t\t{ Reject: { _attr: { reason: \"busy\" } } },\n\t\t\t// { Reject: null },\n\t\t] })\n\t);\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/express/server.js",
    "content": "var app = require('express')();\nvar bodyParser = require('body-parser');\n\napp.use(bodyParser.urlencoded({ extended: false }));\n\napp.post(\"/\", function (request, response) {\n\tvar from = request.body.from;\n\tvar to = request.body.to;\n\tvar direction = request.body.direction;\n\n\tconsole.log(\"from: \" + from);\n\tconsole.log(\"to: \" + to);\n\tconsole.log(\"direction: \" + direction);\n\n\tresponse.send(\"So Long, and Thanks for All the Fish!\");\n});\n\napp.listen(3000);\n"
  },
  {
    "path": "examples/nodejs/plain/dial.js",
    "content": "// dial example - forwards all calls to voicemail\n\nvar http = require('http');\n\n// requires xmlbuilder: npm install xmlbuilder\nvar builder = require('xmlbuilder');\n\nhttp.createServer(function (req, res) {\n\n\t// create XML root tree called \"response\"\n\tvar response = builder.create('Response',{version: '1.0', encoding: 'UTF-8'},{})\n\t\t.ele('Dial')\t\t\t\t\t// add \"dial\" child\n\t\t.ele('Voicemail')\t\t\t\t// add \"voicemail\" child\n//\t\t.ele('Number','49211000000')\t\t\t// if you want, you could also redirect to a phone number\n\t\t.end({ pretty: true});\n\n\tvar body = response.toString();\n\n\tres.writeHead(200, {\n\t\t  'Content-Length': body.length,\n\t\t  'Content-Type': 'application/xml'\n\t});\n\n\tres.write(body);\n\n\tres.end();\n}).listen(3000);\n\n"
  },
  {
    "path": "examples/nodejs/plain/log_calls.js",
    "content": "// example that shows how to tell sipgate.io to also push answer and end of the call\n\nvar http = require('http');\nvar queryString = require('querystring');\n\n// requires xmlbuilder: npm install xmlbuilder\nvar builder = require('xmlbuilder');\n\n\nfunction formatUserOrGroup(users) {\n    return Array.isArray(users)\n        ? (\"group(\" + users + \")\")\n        : (\"user \" + users);\n}\n\nfunction newCallToString(newCall) {\n    var s = (newCall['direction'] === \"in\") \n        ? (formatUserOrGroup(newCall['user[]']) + ' receives call ')\n        : newCall['user[]'] + ' makes call ';\n\n    s += newCall['from'] + \" -> \" + newCall['to']\n\n    return s;\n}\n\nhttp.createServer(function (req, res) {\n\n    if (req.method == 'POST') {\n        var data = '';\n\n        req.on('data', function (currentData) {\n            data += currentData;\n        });\n\n        req.on('end', function () {\n            var post = queryString.parse(data);\n\n            if (post['event'] == 'newCall') {\n                console.log(\"Call \" + post['callId'] + ' created: ' + newCallToString(post));\n\n                var response = builder.create('Response', {version: '1.0', encoding: 'UTF-8'}, {});\n                response.att('onAnswer', 'http://' + req.headers.host + '/');\n                response.att('onHangup', 'http://' + req.headers.host + '/');\n\n                var body = response.toString();\n\n                res.writeHead(200, {\n                    'Content-Length': body.length,\n                    'Content-Type': 'application/xml'\n                });\n\n                res.write(body);\n                res.end();\n            }\n            else if (post['event'] == 'answer') {\n                \n                var logRow = 'Call with id ' + post['callId'] + ' was answered';\n\n                if (post['user']) { // Only incoming calls can have a user\n                    logRow += ' by ' + post['user'];\n                }\n                console.log(logRow);\n\n                res.writeHead(200);\n                res.end();\n            }\n            else if (post['event'] == 'hangup') {\n                console.log('Call ' + post['callId'] + ' ended with cause: ' + post['cause']);\n\n                res.writeHead(200);\n                res.end();\n            }\n        });\n    }\n\n}).listen(3000);\n\n"
  },
  {
    "path": "examples/nodejs/plain/reject.js",
    "content": "// Reject example - rejects all calls with reason \"busy\"\n\nvar http = require('http');\n\n// requires xmlbuilder: npm install xmlbuilder\nvar builder = require('xmlbuilder');\n\nhttp.createServer(function (req, res) {\n\n\t// create XML root tree called \"response\"\n\tvar response = builder.create('Response',{version: '1.0', encoding: 'UTF-8'},{})\n\t\t.ele('Reject', {'reason': 'busy'})\t\t\t// add \"reject\" with reason \"busy\"\n\t\t.end({ pretty: true});\n\n\tvar body = response.toString();\n\n\tres.writeHead(200, {\n\t\t  'Content-Length': body.length,\n\t\t  'Content-Type': 'application/xml'\n\t});\n\n\tres.write(body);\n\n\tres.end();\n}).listen(3000);\n\n"
  },
  {
    "path": "examples/nodejs/plain/server.js",
    "content": "var http = require('http');\n\nhttp.createServer(function (req, res) {\n\treq.on('data', function(d) {\n\t\tprocess.stdout.write(d);\n\t});\n\n\tres.writeHead(200);\n\tres.end(\"Node-JS-HTTP-Server\");\n}).listen(3000);\n\n"
  },
  {
    "path": "examples/nodejs/plain/server_ssl.js",
    "content": "var https = require('https');\nvar fs = require('fs');\n\nvar options = {\n\tpath: '/',\n\tmethod: 'POST',\n\tkey: fs.readFileSync('server-key.pem'),\n\tcert: fs.readFileSync('server-cert.pem')\n};\n\nhttps.createServer(options, function (req, res) {\n\n\treq.on('data', function(d) {\n\t\tprocess.stdout.write(d);\n\t});\n\n\tres.writeHead(200);\n\tres.end(\"Node-JS-HTTPS-Server\");\n}).listen(3000);\n"
  },
  {
    "path": "examples/perl/mojolicious/cpanfile",
    "content": "requires 'Mojolicious';\n# requires 'IO::Socket::SSL';\n# requires 'Mojolicious::Plugin::BasicAuth';\nrequires 'XML::Simple';\n"
  },
  {
    "path": "examples/perl/mojolicious/dial-number.pl",
    "content": "#!/usr/bin/env perl\n\nuse Mojolicious::Lite;\nuse XML::Simple;\n\npost '/' => sub {\n\tmy $c = shift;\n\n\tmy $from = $c->param('from');\n\tmy $to   = $c->param('to');\n\n\tapp->log->debug(\"from: '$from'\");\n\tapp->log->debug(\"to: '$to'\");\n\n\t$c->render(\n\t\tformat => \"xml\",\n\t\tdata => XMLout( { Dial => [ { Number => [ \"4915799912345\" ] } ] }, RootName => \"Response\"),\n\t);\n};\n\napp->start();\n"
  },
  {
    "path": "examples/perl/mojolicious/dial-voicemail.pl",
    "content": "#!/usr/bin/env perl\n\nuse Mojolicious::Lite;\nuse XML::Simple;\n\npost '/' => sub {\n\tmy $c = shift;\n\n\tmy $from = $c->param('from');\n\tmy $to   = $c->param('to');\n\n\tapp->log->debug(\"from: '$from'\");\n\tapp->log->debug(\"to: '$to'\");\n\n\t$c->render(\n\t\tformat => \"xml\",\n\t\tdata => XMLout( { Dial => [ { Voicemail => [ { } ] } ] }, RootName => \"Response\"),\n\t);\n};\n\napp->start();\n"
  },
  {
    "path": "examples/perl/mojolicious/play-url.pl",
    "content": "#!/usr/bin/env perl\n\nuse Mojolicious::Lite;\nuse XML::Simple;\n\npost '/' => sub {\n\tmy $c = shift;\n\n\tmy $from = $c->param('from');\n\tmy $to   = $c->param('to');\n\n\tapp->log->debug(\"from: '$from'\");\n\tapp->log->debug(\"to: '$to'\");\n\n\t$c->render(\n\t\tformat => \"xml\",\n\t\tdata => XMLout( { Play => [ { Url => [ \"http://www.example.com/example.wav\" ] } ] }, RootName => \"Response\"),\n\t);\n};\n\napp->start();\n"
  },
  {
    "path": "examples/perl/mojolicious/reject.pl",
    "content": "#!/usr/bin/env perl\n\nuse Mojolicious::Lite;\nuse XML::Simple;\n\npost '/' => sub {\n\tmy $c = shift;\n\n\tmy $from = $c->param('from');\n\tmy $to   = $c->param('to');\n\n\tapp->log->debug(\"from: '$from'\");\n\tapp->log->debug(\"to: '$to'\");\n\n\t$c->render(\n\t\tformat => \"xml\",\n\t\tdata => XMLout( { Reject => [ { reason => \"busy\" } ] }, RootName => \"Response\"),\n\t\t# data => XMLout( { Reject => [ { } ] }, RootName => \"Response\"),\n\t);\n};\n\napp->start();\n"
  },
  {
    "path": "examples/perl/mojolicious/server.pl",
    "content": "#!/usr/bin/env perl\n\nuse Mojolicious::Lite;\n\npost '/' => sub {\n\tmy $c = shift;\n\n\tmy $from = $c->param('from');\n\tmy $to   = $c->param('to');\n\n\tapp->log->debug(\"from: '$from'\");\n\tapp->log->debug(\"to: '$to'\");\n\n\t$c->render(text => 'We ♥ perl!');\n};\n\napp->start();\n"
  },
  {
    "path": "examples/php/dial_callerId.php",
    "content": "<?php\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Add dial command as child in response\n$dial = $dom->createElement('Dial');\n\n// Create a new attribute for the callerId element\n$callerId = $dom->createAttribute('callerId');\n//$anonymous = $dom->createAttribute('anonymous');\n\n// set callerId - you should change that to your desired number\n$callerId->value = '4915799912345';\n//$anonymous->value = 'true';\n\n// Add a number target and append it to the dial command, we're calling '+49211000000' - you should maybe change that... ;-)\n$number = $dom->createElement('Number','49211000000');\n\n$dial->appendChild($callerId);\n//$dial->appendChild($anonymous);\n$dial->appendChild($number);\n\n$response->appendChild($dial);\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/dial_callerId_switch.php",
    "content": "<?php\n// Basic code is from danielberlin\n\n// Prepare variables for easier handling\n$toNumber = $_POST['to'];\t  // the number you dialed\n\n// Create new DOM document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Add dial command as child in response\n$dial = $dom->createElement('Dial');\n\n// Create a new attribute for the callerId element\n$callerId = $dom->createAttribute('callerId');\n//$anonymous = $dom->createAttribute('anonymous');\n\n// RegEx the dialed number, you should maybe change that for you ;-)\npreg_match(\"/(..)([1-9])[0-9]*/\", $toNumber, $number_array);\n\n// Check if it's an international call (assuming Germany here)\nif ($number_array[1] != '49') {\n  // Set callerId for international calls, please edit your number\n  $sendId = '49211000000';\n}\n// For a national call, check if it's a landline or mobile call\nelseif ($number_array[2] > '1') {\n  // Set landline callerId, please edit your number\n  $sendId = '49211000000';\n}\nelse {\n  // Set mobile callerId as default, please edit your number\n  $sendId = '4915799912345';\n}\n// apply to callerId\n$callerId->value = $sendId;\n//$anonymous->value = 'true';\n\n// the number is derived from the 'to' parameter in the URI \"dial_callerId_switch.php?from=492111234567&to=4915791234567&direction=out\"\n$number = $dom->createElement('Number', $toNumber);\n\n$dial->appendChild($callerId);\n$dial->appendChild($number);\n\n$response->appendChild($dial);\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/dial_number.php",
    "content": "<?php\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Add dial command as child in response\n$dial = $dom->createElement('Dial');\n\n// Add a number target and append it to the dial command, we're calling '+49211000000' - you should maybe change that... ;-)\n$number = $dom->createElement('Number','49211000000');\n\n$dial->appendChild($number);\n\n$response->appendChild($dial);\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/dial_voicemail.php",
    "content": "<?php\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Add dial command as child in response\n$dial = $dom->createElement('Dial');\n\n// Add a voicemail target and append it to the dial command\n$voicemail = $dom->createElement('Voicemail');\n$dial->appendChild($voicemail);\n\n$response->appendChild($dial);\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/log_call-beginning-answer-end.php",
    "content": "<?php\n/* Log the beginnings and ends of calls\n */\n\n$event = $_POST['event'];           // \"newCall\" (beginning), \"answer\" or \"hangup\" (end)\n$callId = $_POST['callId'];         // unique Id of this call\n$timestamp = date(\"d.m.Y H:i:s\");   // a timestamp for the log so that calls can be identified\n\n\nif ($event == 'newCall') {\n\n    $fromNumber = $_POST['from'];     // the number of the caller\n    $toNumber = $_POST['to'];         // the number on which the call was received on\n    $direction = $_POST['direction'];   // the direction of the call (either \"in\" or \"out\")\n\t$users = $_POST['user'];\t\t\t\t// contains an array, because group calls can have several users\n\n    // build the log row, example:\n    // 23456123 - 17.09.2014 10:05:25 - from 4921100000000 to 4921100000000 - direction: in - user: Anna Mayer - user: Marcus Satt\n    $logRow = $callId . \" - \" . $timestamp .\n        \" - from \" . $fromNumber . \" to \" . $toNumber .\n        \" - direction: \" . $direction;\n\n\tforeach ($users as $user) {\n\t\t$logRow .= \" - user: \" . urldecode($user);\n\t}\n\n\t$logRow .= PHP_EOL;\n\n    set_onAnswer_onHangup('http://localhost:3000/log_call-beginning-answer-end.php'); // Call this script again on hangup\n\n} else if ($event == 'answer') {\n\n    if ($_POST['user']) { // Only incoming calls have a user\n        $user = \" - \" . urldecode($_POST['user']);\n    }\n\n    // build the log row, example:\n    // Incoming call: 23456123 - 17.09.2014 10:05:25 - Anna Mayer\n    // Outgoing call: 23456123 - 17.09.2014 10:05:25\n    $logRow = $callId . \" - \" . $timestamp . $user . PHP_EOL;\n\n} else if ($event == 'hangup') {\n\n    $cause = $_POST['cause'];\n\n    // build the log row, example:\n    // 23456123 - cancel - 17.09.2014 10:05:25\n    $logRow = $callId . \" - \" . $cause . \" - \" . $timestamp . PHP_EOL;\n\n}\n\n// append the log row to the callog.txt file, make sure this file is writeable (e.g. create the file and chmod 777 it)\nfile_put_contents(\"callog.txt\", $logRow, FILE_APPEND);\n\ndie(\"Thanks - here's a motivational squirrel for you! https://www.youtube.com/watch?v=m3d03-sSiBE\");\n\n// Create XML Response that sets Url to be called when call ends (hangup)\nfunction set_onAnswer_onHangup($scriptUrl)\n{\n// Create new DOM Document for the response\n    $dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n    $response = $dom->createElement('Response');\n    $dom->appendChild($response);\n\n    $response->setAttribute('onAnswer', $scriptUrl);\n    $response->setAttribute('onHangup', $scriptUrl);\n\n    header('Content-type: application/xml');\n    echo $dom->saveXML();\n}\n"
  },
  {
    "path": "examples/php/log_call-beginnings.php",
    "content": "<?php\n\n// Prepare variables for easier handling\n$fromNumber = $_POST['from'];     // the number of the caller\n$toNumber = $_POST['to'];         // the number on which the call was received on\n$direction = $_POST['direction']; // the direction of the call (either \"in\" or \"out\")\n$timestamp = date(\"d.m.Y H:i:s\"); // a timestamp for the log so that calls can be uniquely identified\n\n// build the log row, example:\n// 17.09.2014 10:05:25 - from 4921100000000 to 4921100000000 - direction: in\n$logRow = $timestamp . \" - from \" . $fromNumber . \" to \" . $toNumber . \" - direction: \" . $direction . PHP_EOL;\n\n// append the log row to the callog.txt file, make sure this file is writeable (e.g. create the file and chmod 777 it)\nfile_put_contents(\"callog.txt\",$logRow,FILE_APPEND);\n\ndie(\"Thanks - here's a motivational squirrel for you! https://www.youtube.com/watch?v=m3d03-sSiBE\");\n"
  },
  {
    "path": "examples/php/play_url.php",
    "content": "<?php\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Add play command as child in response\n$play = $dom->createElement('Play');\n\n// Add a url target and append it to the play command\n$url = $dom->createElement('Url','http://www.example.com/example.wav');\n\n$play->appendChild($url);\n\n$response->appendChild($play);\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/reject.php",
    "content": "<?php\n\n// Prepare variables for easier handling\n$fromNumber = $_POST['from'];     // the number of the caller\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n// Only reject calls from a certain number, e.g. your mother-in-law\nif($fromNumber == \"49190666666\") {\n\t// Add hangup command as child in response\n\t$hangup = $dom->createElement('Reject');\n\n\t// Create a new attribute for the hangup element and assign \"busy\" as value, so that the caller hears a busy-tone\n\t$hangupReason = $dom->createAttribute('reason');\n\t$hangupReason->value = 'busy';\n\t$hangup->appendChild($hangupReason);\n\n\t$response->appendChild($hangup);\n}\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/php/set_onAnswer-onHangup.php",
    "content": "<?php\n\n// Create new DOM Document for the response\n$dom = new DOMDocument('1.0', 'UTF-8');\n\n// Add response child\n$response = $dom->createElement('Response');\n$dom->appendChild($response);\n\n$response->setAttribute('onAnswer', 'http://localhost:3000/onAnswer');\n$response->setAttribute('onHangup', 'http://localhost:3000/hangup');\n\nheader('Content-type: application/xml');\necho $dom->saveXML();\n"
  },
  {
    "path": "examples/prolog/server.pl",
    "content": ":- use_module(library(http/thread_httpd)).\n:- use_module(library(http/http_dispatch)).\n:- use_module(library(http/http_client)).\n\n:- http_handler('/', process_request, []).\n\nserver :- http_server(http_dispatch, [port(3000)]).\n\nprocess_request(Request) :-\n\tmember(method(post), Request), !,\n\thttp_read_data(Request, Data, []),\n\tData = [From|[To|[Direction]]],\n\tprint_message(informational, From),\n\tprint_message(informational, To),\n\tprint_message(informational, Direction),\n\tanswer.\n\nanswer :-\n\tformat('Content-type: text/plain~n~n', []),\n\tprint('Over and out\\n').\n"
  },
  {
    "path": "examples/python/dial-number.py",
    "content": "#!/usr/bin/env python\n\nfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\nimport urlparse\nimport logging\nfrom xml.dom.minidom import Document\n\nlogging.basicConfig(level=logging.DEBUG)\n\nclass MegaAwesomePythonServer(BaseHTTPRequestHandler):\n\n    def do_POST(self):\n        length = int(self.headers.getheader('Content-Length'))\n        data = urlparse.parse_qs(self.rfile.read(length))\n\n        logging.debug(\"from: \" + data.get(\"from\")[0])\n        logging.debug(\"to: \" + data.get(\"to\")[0])\n        logging.debug(\"direction: \" + data.get(\"direction\")[0])\n\n        doc = Document()\n        response = doc.createElement('Response')\n        dial = doc.createElement('Dial')\n        number = doc.createElement('Number')\n        numberString = doc.createTextNode('4915799912345')\n        number.appendChild(numberString)\n        dial.appendChild(number)\n        response.appendChild(dial)\n        doc.appendChild(response)\n\n        self.send_response(200)\n        self.send_header('Content-Type', 'application/xml')\n        self.end_headers()\n        self.wfile.write(doc.toxml())\n\n\nserver = HTTPServer(('', 3000), MegaAwesomePythonServer)\nserver.serve_forever()\n"
  },
  {
    "path": "examples/python/dial-voicemail.py",
    "content": "#!/usr/bin/env python\n\nfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\nimport urlparse\nimport logging\nfrom xml.dom.minidom import Document\n\nlogging.basicConfig(level=logging.DEBUG)\n\nclass MegaAwesomePythonServer(BaseHTTPRequestHandler):\n\n    def do_POST(self):\n        length = int(self.headers.getheader('Content-Length'))\n        data = urlparse.parse_qs(self.rfile.read(length))\n\n        logging.debug(\"from: \" + data.get(\"from\")[0])\n        logging.debug(\"to: \" + data.get(\"to\")[0])\n        logging.debug(\"direction: \" + data.get(\"direction\")[0])\n\n        doc = Document()\n        response = doc.createElement('Response')\n        dial = doc.createElement('Dial')\n        voicemail = doc.createElement('Voicemail')\n        dial.appendChild(voicemail)\n        response.appendChild(dial)\n        doc.appendChild(response)\n\n        self.send_response(200)\n        self.send_header('Content-Type', 'application/xml')\n        self.end_headers()\n        self.wfile.write(doc.toxml())\n\n\nserver = HTTPServer(('', 3000), MegaAwesomePythonServer)\nserver.serve_forever()\n"
  },
  {
    "path": "examples/python/play-url.py",
    "content": "#!/usr/bin/env python\n\nfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\nimport urlparse\nimport logging\nfrom xml.dom.minidom import Document\n\nlogging.basicConfig(level=logging.DEBUG)\n\nclass MegaAwesomePythonServer(BaseHTTPRequestHandler):\n\n    def do_POST(self):\n        length = int(self.headers.getheader('Content-Length'))\n        data = urlparse.parse_qs(self.rfile.read(length))\n\n        logging.debug(\"from: \" + data.get(\"from\")[0])\n        logging.debug(\"to: \" + data.get(\"to\")[0])\n        logging.debug(\"direction: \" + data.get(\"direction\")[0])\n\n        doc = Document()\n        response = doc.createElement('Response')\n        play = doc.createElement('Play')\n        url = doc.createElement('Url')\n        urlString = doc.createTextNode('http://www.example.com/example.wav')\n        url.appendChild(urlString)\n        play.appendChild(url)\n        response.appendChild(play)\n        doc.appendChild(response)\n\n        self.send_response(200)\n        self.send_header('Content-Type', 'application/xml')\n        self.end_headers()\n        self.wfile.write(doc.toxml())\n\n\nserver = HTTPServer(('', 3000), MegaAwesomePythonServer)\nserver.serve_forever()\n"
  },
  {
    "path": "examples/python/reject.py",
    "content": "#!/usr/bin/env python\n\nfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\nimport urlparse\nimport logging\nfrom xml.dom.minidom import Document\n\nlogging.basicConfig(level=logging.DEBUG)\n\nclass MegaAwesomePythonServer(BaseHTTPRequestHandler):\n\n    def do_POST(self):\n        length = int(self.headers.getheader('Content-Length'))\n        data = urlparse.parse_qs(self.rfile.read(length))\n\n        logging.debug(\"from: \" + data.get(\"from\")[0])\n        logging.debug(\"to: \" + data.get(\"to\")[0])\n        logging.debug(\"direction: \" + data.get(\"direction\")[0])\n\n        doc = Document()\n        response = doc.createElement('Response')\n        reject = doc.createElement('Reject')\n        reject.setAttribute('reason', 'busy')\n        response.appendChild(reject)\n        doc.appendChild(response)\n\n        self.send_response(200)\n        self.send_header('Content-Type', 'application/xml')\n        self.end_headers()\n        self.wfile.write(doc.toxml())\n\n\nserver = HTTPServer(('', 3000), MegaAwesomePythonServer)\nserver.serve_forever()\n"
  },
  {
    "path": "examples/python/server.py",
    "content": "#!/usr/bin/env python\n\nfrom BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer\nimport urlparse\nimport logging\n\nlogging.basicConfig(level=logging.DEBUG)\n\nclass MegaAwesomePythonServer(BaseHTTPRequestHandler):\n\n    def do_POST(self):\n        length = int(self.headers.getheader('Content-Length'))\n        data = urlparse.parse_qs(self.rfile.read(length))\n\n        logging.debug(\"from: \" + data.get(\"from\")[0])\n        logging.debug(\"to: \" + data.get(\"to\")[0])\n        logging.debug(\"direction: \" + data.get(\"direction\")[0])\n\n        self.send_response(200)\n        self.end_headers()\n        self.wfile.write(\"http://xkcd.com/353/\")\n\n\nserver = HTTPServer(('', 3000), MegaAwesomePythonServer)\nserver.serve_forever()\n"
  },
  {
    "path": "examples/ruby/sinatra/dial-number.rb",
    "content": "require 'sinatra'\nrequire 'builder'\n\nset :port, 3000\n\npost '/' do\n  logger.info \"from: #{params[:from]}\"\n  logger.info \"to: #{params[:to]}\"\n  logger.info \"direction: #{params[:direction]}\"\n\n  headers 'Content-Type' => \"application/xml\"\n  xml = Builder::XmlMarkup.new(:indent => 2)\n  xml.instruct!\n  xml.Response{xml.Dial{xml.Number(\"4915799912345\")}}\n\n\nend\n\n"
  },
  {
    "path": "examples/ruby/sinatra/dial-voicemail.rb",
    "content": "require 'sinatra'\nrequire 'builder'\n\nset :port, 3000\n\npost '/' do\n  logger.info \"from: #{params[:from]}\"\n  logger.info \"to: #{params[:to]}\"\n  logger.info \"direction: #{params[:direction]}\"\n\n  headers 'Content-Type' => \"application/xml\"\n  xml = Builder::XmlMarkup.new(:indent => 2)\n  xml.instruct!\n  xml.Response{xml.Dial{xml.Voicemail}}\n\nend\n\n"
  },
  {
    "path": "examples/ruby/sinatra/play-url.rb",
    "content": "require 'sinatra'\nrequire 'builder'\n\nset :port, 3000\n\npost '/' do\n  logger.info \"from: #{params[:from]}\"\n  logger.info \"to: #{params[:to]}\"\n  logger.info \"direction: #{params[:direction]}\"\n\n  headers 'Content-Type' => \"application/xml\"\n  xml = Builder::XmlMarkup.new(:indent => 2)\n  xml.instruct!\n  xml.Response{xml.Play{xml.Url(\"http://www.example.com/example.wav\")}}\n\n\nend\n\n"
  },
  {
    "path": "examples/ruby/sinatra/reject.rb",
    "content": "require 'sinatra'\nrequire 'builder'\n\nset :port, 3000\n\npost '/' do\n  logger.info \"from: #{params[:from]}\"\n  logger.info \"to: #{params[:to]}\"\n  logger.info \"direction: #{params[:direction]}\"\n\n  headers 'Content-Type' => \"application/xml\"\n  xml = Builder::XmlMarkup.new(:indent => 2)\n  xml.instruct!\n  xml.Response{xml.Reject(\"reason\" => \"busy\")}\n# xml.Response{xml.Reject}\n\nend\n\n"
  },
  {
    "path": "examples/ruby/sinatra/server.rb",
    "content": "require 'sinatra'\n\nset :port, 3000\n\npost '/' do\n  logger.info \"from: #{params[:from]}\"\n  logger.info \"to: #{params[:to]}\"\n  logger.info \"direction: #{params[:direction]}\"\nend\n\n"
  },
  {
    "path": "examples/scala/Server.scala",
    "content": "import org.http4s.server.blaze.BlazeServer\nimport org.http4s.server.HttpService\nimport org.http4s.dsl._\nimport java.net.URLDecoder\n\nobject Server extends App {\n  def parseBody(body: String) = {\n    body.split(\"&\").map( s => {\n      val m =  s.split(\"=\", 2).map(s => URLDecoder.decode(s, \"UTF-8\"))\n      m(0) -> m(1)\n    }).toMap\n  }\n\n  val service: HttpService = {\n    case req @ POST -> Root =>\n      val data = parseBody(text(req).run)\n      println(\"from: \" + data.getOrElse(\"from\", \"\"))\n      println(\"to: \" + data.getOrElse(\"to\", \"\"))\n      println(\"direction: \" + data.getOrElse(\"direction\", \"\"))\n      Ok(\"roger that\")\n  }\n\n  BlazeServer.newBuilder.mountService(service, \"/\").run()\n}\n"
  }
]