Repository: sipgate/sipgate.io Branch: master Commit: 3be2eefa7110 Files: 57 Total size: 53.4 KB Directory structure: gitextract_d8juig4m/ ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── README_CONNECT.md └── examples/ ├── c++/ │ └── nuria/ │ ├── reject/ │ │ ├── reject.cpp │ │ └── reject.pro │ └── simple/ │ ├── simple.cpp │ └── simple.pro ├── clojure/ │ ├── project.clj │ └── src/ │ └── sipgateio/ │ └── server.clj ├── commonlisp/ │ └── server.lisp ├── go/ │ └── server.go ├── java/ │ ├── dial.java │ ├── play.java │ ├── reject.java │ └── server.java ├── nodejs/ │ ├── express/ │ │ ├── .gitignore │ │ ├── dial-number.js │ │ ├── dial-voicemail.js │ │ ├── on-hangup.js │ │ ├── package.json │ │ ├── play-url.js │ │ ├── reject.js │ │ └── server.js │ └── plain/ │ ├── dial.js │ ├── log_calls.js │ ├── reject.js │ ├── server.js │ └── server_ssl.js ├── perl/ │ └── mojolicious/ │ ├── cpanfile │ ├── dial-number.pl │ ├── dial-voicemail.pl │ ├── play-url.pl │ ├── reject.pl │ └── server.pl ├── php/ │ ├── dial_callerId.php │ ├── dial_callerId_switch.php │ ├── dial_number.php │ ├── dial_voicemail.php │ ├── log_call-beginning-answer-end.php │ ├── log_call-beginnings.php │ ├── play_url.php │ ├── reject.php │ └── set_onAnswer-onHangup.php ├── prolog/ │ └── server.pl ├── python/ │ ├── dial-number.py │ ├── dial-voicemail.py │ ├── play-url.py │ ├── reject.py │ └── server.py ├── ruby/ │ └── sinatra/ │ ├── dial-number.rb │ ├── dial-voicemail.rb │ ├── play-url.rb │ ├── reject.rb │ └── server.rb └── scala/ └── Server.scala ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ **/node_modules ================================================ FILE: CHANGELOG.md ================================================ sipgate.io Changelog ==================== 1.6.0 Noah (2015-05-08) ----------------------- ***Features*** * sipgate.io available in basic * sipgate.io available in team (beta) * POST request for end of call 1.5.0 Emil (2014-11-27) ----------------------- ***Features*** * Set a custom caller id 1.4.0 Frida (2014-11-20) ----------------------- ***Features*** * POST request for outgoing calls 1.3.0 Phil (2014-11-18) ----------------------- ***Features*** * Play WAV file from a given URL * `````` `````` example XML in README.md * Hang up calls * `````` example XML in README.md * Update examples ***Resolved issues*** * Client doesn't support compression, despite it being advertised in Accept-Encoding ([#11](https://github.com/sipgate/sipgate.io/issues/11)) 1.2.0 Levi (2014-10-22) ----------------------- ***Features*** * Send call to voicemail or external number * `````` `````` example XML in README.md * `````` `````` example XML in README.md * Update examples ***Resolved issues*** * XML response not understood by sipgate.io's server ([#6](https://github.com/sipgate/sipgate.io/issues/6)) * Content-Type: text/xml support ([#7](https://github.com/sipgate/sipgate.io/issues/7)) * Chunked encoded response is not processed ([#8](https://github.com/sipgate/sipgate.io/issues/8)) * ```from``` and ```to``` not always correct ([#9](https://github.com/sipgate/sipgate.io/issues/9)) 1.1.0 Nico (2014-10-14) ----------------------- ***Features*** * Reject calls with ```Reject``` * ```Reject``` example XML in README.md * Update examples * Add this cool CHANGELOG.md * C++ example from [Papierkorb](https://github.com/Papierkorb) 1.0.0 Brienne (2014-10-06) -------------------------- ***Features*** * First release * POST request with ```from``` and ```to``` * Perl example from [fuglu](https://github.com/fuglu) * Ruby example from [fuglu](https://github.com/fuglu) * Python example from [scgitsip](https://github.com/scgitsip) * PHP example from [tpxtron](https://github.com/tpxtron) * Java example from [scgitsip](https://github.com/scgitsip) * Go example from [vileda](https://github.com/vileada) * Common Lisp example from [olivermg](https://github.com/olivermg) * Clojure example from [olivermg](https://github.com/olivermg) * Prolog example from [kr1schan](https://github.com/kr1schan) * Scala example from [fnordian](https://github.com/fnordian) ================================================ FILE: LICENSE ================================================ Copyright (c) 2014, sipgate GmbH All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. ================================================ FILE: README.md ================================================ # sipgate.io This 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/). For more code samples in javascript, java or python visit [github.com/sipgate-io](https://github.com/sipgate-io). ## Table of Contents - [sipgate.io](#sipgateio) - [Requirements](#requirements) - [Usage with sipgate team](#usage-with-sipgate-team) - [Reference](#reference) - [Help us make it better](#help-us-make-it-better) ## Requirements ### Usage with sipgate team - [x] Book sipgate.io in your team account (incurs monthly cost) or [request access to our developer program (free!)](http://goo.gl/forms/8TS8kQj6kx) - [x] [After receiving the confirmation mail enter an URL for incoming/outgoing calls in sipgate team settings](https://app.sipgate.com/io) ## Usage To find out how to use sipgate.io go to our [Developer Documentation portal](https://developer.sipgate.io/push-api/setup/). # Help us make it better Please 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. ================================================ FILE: README_CONNECT.md ================================================ sipgate.io connect ================== sipgate.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) Add the sipgate.io connect button to offer your customers this additional value in the easist way possible. This README shows how to integrate sipgate.io connect into your application: * Variables to pass into the signup process * Form template to get you started Please refer to the general [sipgate.io README](https://github.com/sipgate/sipgate.io/blob/master/README.md) to learn which information sipgate.io passes to your application and how. Feel free to check out the [sipgate.io connect demo page](https://demo.sipgate.io/connect) as well as the [sipgate.io demo page](https://demo.sipgate.io). Variables to pass in the GET request ================ Parameter | Description ---------- | ----------- url | sipgate.io will pass call meta data to this URL successUrl | After signup we offer your users a link to this URL to return to your application siteName | The name of your application. We refer to your application several times throughout signup Button and Form Template ================ You can copy+paste this form for calling sipgate.io connect: ```html

Connect this application with telephony so that calls are immediately displayed here


``` Please make sure to replace the values of the hidden fields with correct ones. Help us make it better ====================== Please 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! ================================================ FILE: examples/c++/nuria/reject/reject.cpp ================================================ /* This is an example on how to create a fully functional HTTP server for use * with the sipgate.io API based on the NuriaProject Framework. * See: https://github.com/NuriaProject/Framework */ #include #include #include #include #include #include void mySlot (Nuria::HttpClient *client) { Nuria::HttpPostBodyReader *reader = client->postBodyReader (); if (!reader) { client->killConnection (400); return; } nLog() << "Rejecting call" << reader->fieldValue ("from") << "->" << reader->fieldValue ("to"); client->setResponseHeader (Nuria::HttpClient::HeaderContentType, "application/xml"); QXmlStreamWriter stream (client); stream.writeStartDocument (); stream.writeStartElement ("Response"); stream.writeStartElement ("Reject"); stream.writeEndElement (); // /Reject stream.writeEndElement (); // /Response stream.writeEndDocument (); } int main (int argc, char *argv[]) { QCoreApplication a (argc, argv); Nuria::HttpServer server; server.root ()->connectSlot ("index", mySlot); if (!server.listen (QHostAddress::Any, 3000)) { nError() << "Failed to listen on port 3000."; return 1; } nLog() << "Listening on all interfaces on port 3000."; return a.exec (); } ================================================ FILE: examples/c++/nuria/reject/reject.pro ================================================ # Example project file for a sipgate.io HTTP server TEMPLATE = app TARGET = reject INCLUDEPATH += . # Dependency to the NuriaProject Framework # See https://github.com/NuriaProject/Framework CONFIG += nuria NURIA += core network # SOURCES += reject.cpp ================================================ FILE: examples/c++/nuria/simple/simple.cpp ================================================ /* This is an example on how to create a fully functional HTTP server for use * with the sipgate.io API based on the NuriaProject Framework. * See: https://github.com/NuriaProject/Framework */ #include #include #include #include #include void mySlot (Nuria::HttpClient *client) { Nuria::HttpPostBodyReader *reader = client->postBodyReader (); if (!reader) { client->killConnection (400); return; } nLog() << "Incoming call" << reader->fieldValue ("from") << "->" << reader->fieldValue ("to"); } int main (int argc, char *argv[]) { QCoreApplication a (argc, argv); Nuria::HttpServer server; server.root ()->connectSlot ("index", mySlot); if (!server.listen (QHostAddress::Any, 3000)) { nError() << "Failed to listen on port 3000."; return 1; } nLog() << "Listening on all interfaces on port 3000."; return a.exec (); } ================================================ FILE: examples/c++/nuria/simple/simple.pro ================================================ # Example project file for a sipgate.io HTTP server TEMPLATE = app TARGET = simple INCLUDEPATH += . # Dependency to the NuriaProject Framework # See https://github.com/NuriaProject/Framework CONFIG += nuria NURIA += core network # SOURCES += simple.cpp ================================================ FILE: examples/clojure/project.clj ================================================ (defproject sipgateio "0.1.0-SNAPSHOT" :description "simple sipgate.io example" :url "https://github.com/sipgate/sipgate.io/tree/master/examples/clojure" :dependencies [[org.clojure/clojure "1.6.0"] [ring "1.3.1"]] :main sipgateio.server) ================================================ FILE: examples/clojure/src/sipgateio/server.clj ================================================ ;; ;; This assumes you are using leiningen (http://leiningen.org/) ;; You can then run this project via ;; $ lein run ;; ;; For complete example (including project file) please look at ;; https://github.com/sipgate/sipgate.io/tree/master/examples/clojure ;; (ns sipgateio.server (:gen-class)) (use 'ring.adapter.jetty 'ring.middleware.params) (defn handler [{params :params}] (println (str "Call from " (params "from") " to " (params "to"))) {:status 200 :body "I love the JVM" }) (defn -main [& args] (run-jetty (wrap-params handler) {:port 3000})) ================================================ FILE: examples/commonlisp/server.lisp ================================================ ;; This example uses hunchentoot as webserver. ;; You can obtain it from http://weitz.de/hunchentoot/ ;; ;; If you use quicklisp, you can simply install it by evaluating ;; (ql:quickload "hunchentoot") (require :hunchentoot) (use-package :hunchentoot) (define-easy-handler (incoming-handler :uri "/") (from to) (log-message* :info "got call from ~a to ~a~%" from to) "girls just wanna defun!") (defparameter *server* (start (make-instance 'easy-acceptor :port 3000))) ;; to stop server: (stop *server*) ================================================ FILE: examples/go/server.go ================================================ package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, r *http.Request) { r.ParseForm() from := r.Form.Get("from") to := r.Form.Get("to") direction := r.Form.Get("direction") fmt.Printf("from: %s\n", from) fmt.Printf("to: %s\n", to) fmt.Printf("direction: %s\n", direction) fmt.Fprintf(w, "So Long, and Thanks for All the Fish!") } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":3000", nil) } ================================================ FILE: examples/java/dial.java ================================================ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringWriter; import java.net.InetSocketAddress; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class dial { public static void main(String[] args) throws Exception { HttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0); httpServer.createContext("/", new AwesomeRejectHandler()); httpServer.setExecutor(null); httpServer.start(); System.out.println("Server running...."); System.out.println("Press CTRL+C to stop the server"); } static class AwesomeRejectHandler implements HttpHandler { public void handle(HttpExchange httpExchange) throws IOException { InputStream inputStream = httpExchange.getRequestBody(); int charValue; ArrayList chars = new ArrayList(); while ((charValue = inputStream.read()) != -1) { chars.add((char) charValue); } StringBuilder stringBuilder = new StringBuilder(chars.size()); for (Character character : chars) { stringBuilder.append(character); } // Print from, to and direction System.err.println("INFO: DATA: " + stringBuilder.toString()); String XMLResponse = ""; XMLBuilder xmlBuilder; try { xmlBuilder = new XMLBuilder(); if (stringBuilder.toString().contains("from=4915799912345")) { XMLResponse = xmlBuilder.dial("4915791234567"); } else if (stringBuilder.toString().contains("from=491579987654")) { XMLResponse = xmlBuilder.send2voicemail(); } else { XMLResponse = xmlBuilder.reject("busy"); } } catch (ParserConfigurationException e) { e.printStackTrace(); } // Print XML System.err.println("INFO: XML-Response: " + XMLResponse); Headers headers = httpExchange.getResponseHeaders(); headers.set("Content-Type", "application/xml"); headers.set("Accept-Encoding", "gzip"); httpExchange.sendResponseHeaders(200, XMLResponse.length()); OutputStream outputStream = httpExchange.getResponseBody(); outputStream.write(XMLResponse.getBytes()); outputStream.close(); } } static class XMLBuilder { private Document document; private Element root; public XMLBuilder() throws ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.newDocument(); document.setXmlStandalone(true); // is the root tag this.root = document.createElement("Response"); document.appendChild(this.root); this.document = document; } private String dial(String number) { Element xmlNodeDial = document.createElement("Dial"); root.appendChild(xmlNodeDial); Element xmlNodeNumber = document.createElement("Number"); xmlNodeDial.appendChild(xmlNodeNumber); xmlNodeNumber.setTextContent(number); return build(); } private String send2voicemail() { Element xmlNodeDial = document.createElement("Dial"); root.appendChild(xmlNodeDial); Element xmlNodeVoicemail = document.createElement("Voicemail"); xmlNodeDial.appendChild(xmlNodeVoicemail); return build(); } private String reject(String reason) { Element xmlNodeDial = document.createElement("Reject"); root.appendChild(xmlNodeDial); Attr xmlAttribute = document.createAttribute("reason"); xmlAttribute.setValue(reason); xmlNodeDial.setAttributeNode(xmlAttribute); return build(); } private String build() { String XMLResponse = ""; try { // Write the document into XMl format and return it TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(document); StringWriter stringWriter = new StringWriter(); StreamResult streamResult = new StreamResult(stringWriter); transformer.transform(domSource, streamResult); XMLResponse = stringWriter.toString(); } catch (TransformerException tranformerException) { tranformerException.printStackTrace(); } return XMLResponse; } } } ================================================ FILE: examples/java/play.java ================================================ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringWriter; import java.net.InetSocketAddress; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class play { public static void main(String[] args) throws Exception { HttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0); httpServer.createContext("/", new AwesomeRejectHandler()); httpServer.setExecutor(null); httpServer.start(); System.out.println("Server running...."); System.out.println("Press CTRL+C to stop the server"); } static class AwesomeRejectHandler implements HttpHandler { public void handle(HttpExchange httpExchange) throws IOException { InputStream inputStream = httpExchange.getRequestBody(); int charValue; ArrayList chars = new ArrayList(); while ((charValue = inputStream.read()) != -1) { chars.add((char) charValue); } StringBuilder stringBuilder = new StringBuilder(chars.size()); for (Character character : chars) { stringBuilder.append(character); } // Print from, to and direction System.err.println("INFO: DATA: " + stringBuilder.toString()); String XMLResponse = ""; XMLBuilder xmlBuilder; try { xmlBuilder = new XMLBuilder(); if (stringBuilder.toString().contains("from=4915799912345")) { XMLResponse = xmlBuilder.play("http://yourawesomewavfile.wav"); } } catch (ParserConfigurationException e) { e.printStackTrace(); } // Print XML System.err.println("INFO: XML-Response: " + XMLResponse); Headers headers = httpExchange.getResponseHeaders(); headers.set("Content-Type", "application/xml"); headers.set("Accept-Encoding", "gzip"); httpExchange.sendResponseHeaders(200, XMLResponse.length()); OutputStream outputStream = httpExchange.getResponseBody(); outputStream.write(XMLResponse.getBytes()); outputStream.close(); } } static class XMLBuilder { private Document document; private Element root; public XMLBuilder() throws ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.newDocument(); document.setXmlStandalone(true); // is the root tag this.root = document.createElement("Response"); document.appendChild(this.root); this.document = document; } private String dial(String number) { Element xmlNodeDial = document.createElement("Dial"); root.appendChild(xmlNodeDial); Element xmlNodeNumber = document.createElement("Number"); xmlNodeDial.appendChild(xmlNodeNumber); xmlNodeNumber.setTextContent(number); return build(); } private String send2voicemail() { Element xmlNodeDial = document.createElement("Dial"); root.appendChild(xmlNodeDial); Element xmlNodeVoicemail = document.createElement("Voicemail"); xmlNodeDial.appendChild(xmlNodeVoicemail); return build(); } private String reject(String reason) { Element xmlNodeDial = document.createElement("Reject"); root.appendChild(xmlNodeDial); Attr xmlAttribute = document.createAttribute("reason"); xmlAttribute.setValue(reason); xmlNodeDial.setAttributeNode(xmlAttribute); return build(); } private String play(String path) { Element xmlNodePlay = document.createElement("Play"); root.appendChild(xmlNodePlay); Element xmlNodeUrl = document.createElement("Url"); xmlNodePlay.appendChild(xmlNodeUrl); xmlNodeUrl.setTextContent(path); return build(); } private String build() { String XMLResponse = ""; try { // Write the document into XMl format and return it TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(document); StringWriter stringWriter = new StringWriter(); StreamResult streamResult = new StreamResult(stringWriter); transformer.transform(domSource, streamResult); XMLResponse = stringWriter.toString(); } catch (TransformerException tranformerException) { tranformerException.printStackTrace(); } return XMLResponse; } } } ================================================ FILE: examples/java/reject.java ================================================ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.StringWriter; import java.net.InetSocketAddress; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class reject { public static void main(String[] args) throws Exception { HttpServer httpServer = HttpServer.create(new InetSocketAddress(3000),0); httpServer.createContext("/", new AwesomeRejectHandler()); httpServer.setExecutor(null); httpServer.start(); System.out.println("Server running...."); System.out.println("Press CTRL+C to stop the server"); } static class AwesomeRejectHandler implements HttpHandler { public void handle(HttpExchange httpExchange) throws IOException { InputStream inputStream = httpExchange.getRequestBody(); int charValue; ArrayList chars = new ArrayList(); while ((charValue = inputStream.read()) != -1) { chars.add((char) charValue); } StringBuilder stringBuilder = new StringBuilder(chars.size()); for (Character character : chars) { stringBuilder.append(character); } // Print from, to and direction System.err.println("INFO: DATA: " + stringBuilder.toString()); String XMLResponse = ""; if (stringBuilder.toString().contains("from=4915799912345")) { XMLResponse = createXML("busy"); // sent busy signal } else { XMLResponse = createXML(""); // default reason value for reject } // Print XML System.err.println("INFO: XML-Response: " + XMLResponse); Headers headers = httpExchange.getResponseHeaders(); headers.set("Content-Type", "application/xml"); httpExchange.sendResponseHeaders(200, XMLResponse.length()); OutputStream outputStream = httpExchange.getResponseBody(); outputStream.write(XMLResponse.getBytes()); outputStream.close(); } // Build XML with DOM and return as string public String createXML(String reason) throws IOException { String XMLResult = ""; try { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); // First node Document document = documentBuilder.newDocument(); document.setXmlStandalone(true); Element xmlNodeResponse = document.createElement("Response"); document.appendChild(xmlNodeResponse); // Second node Element xmlNodeReject = document.createElement("Reject"); xmlNodeResponse.appendChild(xmlNodeReject); // Second node attribute if (!reason.isEmpty()) { Attr xmlAttribute = document.createAttribute("reason"); xmlAttribute.setValue(reason); xmlNodeReject.setAttributeNode(xmlAttribute); } // Write the content into XMl format TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource domSource = new DOMSource(document); StringWriter stringWriter = new StringWriter(); StreamResult streamResult = new StreamResult(stringWriter); transformer.transform(domSource, streamResult); XMLResult = stringWriter.toString(); } catch (ParserConfigurationException parserConfigurationException) { parserConfigurationException.printStackTrace(); } catch (TransformerException tranformerException) { tranformerException.printStackTrace(); } return XMLResult.toString(); } } } ================================================ FILE: examples/java/server.java ================================================ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.util.ArrayList; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; public class server { public static void main(String[] args) throws Exception { // Create server with port 3000 HttpServer httpserver = HttpServer.create(new InetSocketAddress(3000), 0); httpserver.createContext("/", new MyHandler()); // creates a default executor httpserver.setExecutor(null); httpserver.start(); System.out.println("Server running...."); System.out.println("Press CTRL+C to stop the server"); } static class MyHandler implements HttpHandler { public void handle(HttpExchange httpexchange) throws IOException { //Read HTTP header InputStream is = httpexchange.getRequestBody(); int charValue; ArrayList chars = new ArrayList(); // Print data from header while ((charValue = is.read()) != -1) { chars.add((char) charValue); System.out.print((char) charValue); } StringBuilder builder = new StringBuilder(chars.size()); //Build string from characters for (Character ch : chars) { builder.append(ch); } //Check which number is calling if (builder.toString().contains("from=491234567890")) System.out.println("\nDo something here"); System.out.println("\n200 OK"); OutputStream os = httpexchange.getResponseBody(); os.close(); } } } ================================================ FILE: examples/nodejs/express/.gitignore ================================================ node_modules ================================================ FILE: examples/nodejs/express/dial-number.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); var xml = require('xml'); app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; console.log("from: " + from); console.log("to: " + to); console.log("direction: " + direction); response.set('Content-Type', 'application/xml'); response.send( xml({ Response: [ { Dial: [ { Number: "4915799912345" } ] }, ] }) ); }); app.listen(3000); ================================================ FILE: examples/nodejs/express/dial-voicemail.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); var xml = require('xml'); app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; console.log("from: " + from); console.log("to: " + to); console.log("direction: " + direction); response.set('Content-Type', 'application/xml'); response.send( xml({ Response: [ { Dial: [ { Voicemail: null } ] }, ] }) ); }); app.listen(3000); ================================================ FILE: examples/nodejs/express/on-hangup.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); var xml = require('xml'); var calls = {}; app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; var callId = request.body.callId; calls[callId] = { "from": from, "to": to }; console.log("call from: " + from + " to: " + to + " direction: " + direction); response.set('Content-Type', 'application/xml'); response.send( xml({ Response: [ {_attr: { onHangup: 'http://' + request.headers.host + '/hangup' }} ] }) ); }); app.post("/hangup", function (request, response) { var callId = request.body.callId; var from = calls[callId]["from"] var to = calls[callId]["to"] console.log("hang up call from: " + from + " to: " + to + "with cause: " + request.body.cause); response.send(); }); app.listen(3000); ================================================ FILE: examples/nodejs/express/package.json ================================================ { "name": "sipgate.io", "description": "sipgate.io node.js example", "version": "0.0.1", "private": true, "engines": { "node": "0.10.x" }, "dependencies": { "express": "~4.9.2", "body-parser": "~1.8.2", "xml": "~1.0.0" } } ================================================ FILE: examples/nodejs/express/play-url.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); var xml = require('xml'); app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; console.log("from: " + from); console.log("to: " + to); console.log("direction: " + direction); response.set('Content-Type', 'application/xml'); response.send( xml({ Response: [ { Play: [ { Url: "http://www.example.com/example.wav" } ] }, ] }) ); }); app.listen(3000); ================================================ FILE: examples/nodejs/express/reject.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); var xml = require('xml'); app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; console.log("from: " + from); console.log("to: " + to); console.log("direction: " + direction); response.set('Content-Type', 'application/xml'); response.send( xml({ Response: [ { Reject: { _attr: { reason: "busy" } } }, // { Reject: null }, ] }) ); }); app.listen(3000); ================================================ FILE: examples/nodejs/express/server.js ================================================ var app = require('express')(); var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: false })); app.post("/", function (request, response) { var from = request.body.from; var to = request.body.to; var direction = request.body.direction; console.log("from: " + from); console.log("to: " + to); console.log("direction: " + direction); response.send("So Long, and Thanks for All the Fish!"); }); app.listen(3000); ================================================ FILE: examples/nodejs/plain/dial.js ================================================ // dial example - forwards all calls to voicemail var http = require('http'); // requires xmlbuilder: npm install xmlbuilder var builder = require('xmlbuilder'); http.createServer(function (req, res) { // create XML root tree called "response" var response = builder.create('Response',{version: '1.0', encoding: 'UTF-8'},{}) .ele('Dial') // add "dial" child .ele('Voicemail') // add "voicemail" child // .ele('Number','49211000000') // if you want, you could also redirect to a phone number .end({ pretty: true}); var body = response.toString(); res.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'application/xml' }); res.write(body); res.end(); }).listen(3000); ================================================ FILE: examples/nodejs/plain/log_calls.js ================================================ // example that shows how to tell sipgate.io to also push answer and end of the call var http = require('http'); var queryString = require('querystring'); // requires xmlbuilder: npm install xmlbuilder var builder = require('xmlbuilder'); function formatUserOrGroup(users) { return Array.isArray(users) ? ("group(" + users + ")") : ("user " + users); } function newCallToString(newCall) { var s = (newCall['direction'] === "in") ? (formatUserOrGroup(newCall['user[]']) + ' receives call ') : newCall['user[]'] + ' makes call '; s += newCall['from'] + " -> " + newCall['to'] return s; } http.createServer(function (req, res) { if (req.method == 'POST') { var data = ''; req.on('data', function (currentData) { data += currentData; }); req.on('end', function () { var post = queryString.parse(data); if (post['event'] == 'newCall') { console.log("Call " + post['callId'] + ' created: ' + newCallToString(post)); var response = builder.create('Response', {version: '1.0', encoding: 'UTF-8'}, {}); response.att('onAnswer', 'http://' + req.headers.host + '/'); response.att('onHangup', 'http://' + req.headers.host + '/'); var body = response.toString(); res.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'application/xml' }); res.write(body); res.end(); } else if (post['event'] == 'answer') { var logRow = 'Call with id ' + post['callId'] + ' was answered'; if (post['user']) { // Only incoming calls can have a user logRow += ' by ' + post['user']; } console.log(logRow); res.writeHead(200); res.end(); } else if (post['event'] == 'hangup') { console.log('Call ' + post['callId'] + ' ended with cause: ' + post['cause']); res.writeHead(200); res.end(); } }); } }).listen(3000); ================================================ FILE: examples/nodejs/plain/reject.js ================================================ // Reject example - rejects all calls with reason "busy" var http = require('http'); // requires xmlbuilder: npm install xmlbuilder var builder = require('xmlbuilder'); http.createServer(function (req, res) { // create XML root tree called "response" var response = builder.create('Response',{version: '1.0', encoding: 'UTF-8'},{}) .ele('Reject', {'reason': 'busy'}) // add "reject" with reason "busy" .end({ pretty: true}); var body = response.toString(); res.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'application/xml' }); res.write(body); res.end(); }).listen(3000); ================================================ FILE: examples/nodejs/plain/server.js ================================================ var http = require('http'); http.createServer(function (req, res) { req.on('data', function(d) { process.stdout.write(d); }); res.writeHead(200); res.end("Node-JS-HTTP-Server"); }).listen(3000); ================================================ FILE: examples/nodejs/plain/server_ssl.js ================================================ var https = require('https'); var fs = require('fs'); var options = { path: '/', method: 'POST', key: fs.readFileSync('server-key.pem'), cert: fs.readFileSync('server-cert.pem') }; https.createServer(options, function (req, res) { req.on('data', function(d) { process.stdout.write(d); }); res.writeHead(200); res.end("Node-JS-HTTPS-Server"); }).listen(3000); ================================================ FILE: examples/perl/mojolicious/cpanfile ================================================ requires 'Mojolicious'; # requires 'IO::Socket::SSL'; # requires 'Mojolicious::Plugin::BasicAuth'; requires 'XML::Simple'; ================================================ FILE: examples/perl/mojolicious/dial-number.pl ================================================ #!/usr/bin/env perl use Mojolicious::Lite; use XML::Simple; post '/' => sub { my $c = shift; my $from = $c->param('from'); my $to = $c->param('to'); app->log->debug("from: '$from'"); app->log->debug("to: '$to'"); $c->render( format => "xml", data => XMLout( { Dial => [ { Number => [ "4915799912345" ] } ] }, RootName => "Response"), ); }; app->start(); ================================================ FILE: examples/perl/mojolicious/dial-voicemail.pl ================================================ #!/usr/bin/env perl use Mojolicious::Lite; use XML::Simple; post '/' => sub { my $c = shift; my $from = $c->param('from'); my $to = $c->param('to'); app->log->debug("from: '$from'"); app->log->debug("to: '$to'"); $c->render( format => "xml", data => XMLout( { Dial => [ { Voicemail => [ { } ] } ] }, RootName => "Response"), ); }; app->start(); ================================================ FILE: examples/perl/mojolicious/play-url.pl ================================================ #!/usr/bin/env perl use Mojolicious::Lite; use XML::Simple; post '/' => sub { my $c = shift; my $from = $c->param('from'); my $to = $c->param('to'); app->log->debug("from: '$from'"); app->log->debug("to: '$to'"); $c->render( format => "xml", data => XMLout( { Play => [ { Url => [ "http://www.example.com/example.wav" ] } ] }, RootName => "Response"), ); }; app->start(); ================================================ FILE: examples/perl/mojolicious/reject.pl ================================================ #!/usr/bin/env perl use Mojolicious::Lite; use XML::Simple; post '/' => sub { my $c = shift; my $from = $c->param('from'); my $to = $c->param('to'); app->log->debug("from: '$from'"); app->log->debug("to: '$to'"); $c->render( format => "xml", data => XMLout( { Reject => [ { reason => "busy" } ] }, RootName => "Response"), # data => XMLout( { Reject => [ { } ] }, RootName => "Response"), ); }; app->start(); ================================================ FILE: examples/perl/mojolicious/server.pl ================================================ #!/usr/bin/env perl use Mojolicious::Lite; post '/' => sub { my $c = shift; my $from = $c->param('from'); my $to = $c->param('to'); app->log->debug("from: '$from'"); app->log->debug("to: '$to'"); $c->render(text => 'We ♥ perl!'); }; app->start(); ================================================ FILE: examples/php/dial_callerId.php ================================================ createElement('Response'); $dom->appendChild($response); // Add dial command as child in response $dial = $dom->createElement('Dial'); // Create a new attribute for the callerId element $callerId = $dom->createAttribute('callerId'); //$anonymous = $dom->createAttribute('anonymous'); // set callerId - you should change that to your desired number $callerId->value = '4915799912345'; //$anonymous->value = 'true'; // Add a number target and append it to the dial command, we're calling '+49211000000' - you should maybe change that... ;-) $number = $dom->createElement('Number','49211000000'); $dial->appendChild($callerId); //$dial->appendChild($anonymous); $dial->appendChild($number); $response->appendChild($dial); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/dial_callerId_switch.php ================================================ createElement('Response'); $dom->appendChild($response); // Add dial command as child in response $dial = $dom->createElement('Dial'); // Create a new attribute for the callerId element $callerId = $dom->createAttribute('callerId'); //$anonymous = $dom->createAttribute('anonymous'); // RegEx the dialed number, you should maybe change that for you ;-) preg_match("/(..)([1-9])[0-9]*/", $toNumber, $number_array); // Check if it's an international call (assuming Germany here) if ($number_array[1] != '49') { // Set callerId for international calls, please edit your number $sendId = '49211000000'; } // For a national call, check if it's a landline or mobile call elseif ($number_array[2] > '1') { // Set landline callerId, please edit your number $sendId = '49211000000'; } else { // Set mobile callerId as default, please edit your number $sendId = '4915799912345'; } // apply to callerId $callerId->value = $sendId; //$anonymous->value = 'true'; // the number is derived from the 'to' parameter in the URI "dial_callerId_switch.php?from=492111234567&to=4915791234567&direction=out" $number = $dom->createElement('Number', $toNumber); $dial->appendChild($callerId); $dial->appendChild($number); $response->appendChild($dial); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/dial_number.php ================================================ createElement('Response'); $dom->appendChild($response); // Add dial command as child in response $dial = $dom->createElement('Dial'); // Add a number target and append it to the dial command, we're calling '+49211000000' - you should maybe change that... ;-) $number = $dom->createElement('Number','49211000000'); $dial->appendChild($number); $response->appendChild($dial); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/dial_voicemail.php ================================================ createElement('Response'); $dom->appendChild($response); // Add dial command as child in response $dial = $dom->createElement('Dial'); // Add a voicemail target and append it to the dial command $voicemail = $dom->createElement('Voicemail'); $dial->appendChild($voicemail); $response->appendChild($dial); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/log_call-beginning-answer-end.php ================================================ createElement('Response'); $dom->appendChild($response); $response->setAttribute('onAnswer', $scriptUrl); $response->setAttribute('onHangup', $scriptUrl); header('Content-type: application/xml'); echo $dom->saveXML(); } ================================================ FILE: examples/php/log_call-beginnings.php ================================================ createElement('Response'); $dom->appendChild($response); // Add play command as child in response $play = $dom->createElement('Play'); // Add a url target and append it to the play command $url = $dom->createElement('Url','http://www.example.com/example.wav'); $play->appendChild($url); $response->appendChild($play); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/reject.php ================================================ createElement('Response'); $dom->appendChild($response); // Only reject calls from a certain number, e.g. your mother-in-law if($fromNumber == "49190666666") { // Add hangup command as child in response $hangup = $dom->createElement('Reject'); // Create a new attribute for the hangup element and assign "busy" as value, so that the caller hears a busy-tone $hangupReason = $dom->createAttribute('reason'); $hangupReason->value = 'busy'; $hangup->appendChild($hangupReason); $response->appendChild($hangup); } header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/php/set_onAnswer-onHangup.php ================================================ createElement('Response'); $dom->appendChild($response); $response->setAttribute('onAnswer', 'http://localhost:3000/onAnswer'); $response->setAttribute('onHangup', 'http://localhost:3000/hangup'); header('Content-type: application/xml'); echo $dom->saveXML(); ================================================ FILE: examples/prolog/server.pl ================================================ :- use_module(library(http/thread_httpd)). :- use_module(library(http/http_dispatch)). :- use_module(library(http/http_client)). :- http_handler('/', process_request, []). server :- http_server(http_dispatch, [port(3000)]). process_request(Request) :- member(method(post), Request), !, http_read_data(Request, Data, []), Data = [From|[To|[Direction]]], print_message(informational, From), print_message(informational, To), print_message(informational, Direction), answer. answer :- format('Content-type: text/plain~n~n', []), print('Over and out\n'). ================================================ FILE: examples/python/dial-number.py ================================================ #!/usr/bin/env python from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urlparse import logging from xml.dom.minidom import Document logging.basicConfig(level=logging.DEBUG) class MegaAwesomePythonServer(BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.getheader('Content-Length')) data = urlparse.parse_qs(self.rfile.read(length)) logging.debug("from: " + data.get("from")[0]) logging.debug("to: " + data.get("to")[0]) logging.debug("direction: " + data.get("direction")[0]) doc = Document() response = doc.createElement('Response') dial = doc.createElement('Dial') number = doc.createElement('Number') numberString = doc.createTextNode('4915799912345') number.appendChild(numberString) dial.appendChild(number) response.appendChild(dial) doc.appendChild(response) self.send_response(200) self.send_header('Content-Type', 'application/xml') self.end_headers() self.wfile.write(doc.toxml()) server = HTTPServer(('', 3000), MegaAwesomePythonServer) server.serve_forever() ================================================ FILE: examples/python/dial-voicemail.py ================================================ #!/usr/bin/env python from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urlparse import logging from xml.dom.minidom import Document logging.basicConfig(level=logging.DEBUG) class MegaAwesomePythonServer(BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.getheader('Content-Length')) data = urlparse.parse_qs(self.rfile.read(length)) logging.debug("from: " + data.get("from")[0]) logging.debug("to: " + data.get("to")[0]) logging.debug("direction: " + data.get("direction")[0]) doc = Document() response = doc.createElement('Response') dial = doc.createElement('Dial') voicemail = doc.createElement('Voicemail') dial.appendChild(voicemail) response.appendChild(dial) doc.appendChild(response) self.send_response(200) self.send_header('Content-Type', 'application/xml') self.end_headers() self.wfile.write(doc.toxml()) server = HTTPServer(('', 3000), MegaAwesomePythonServer) server.serve_forever() ================================================ FILE: examples/python/play-url.py ================================================ #!/usr/bin/env python from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urlparse import logging from xml.dom.minidom import Document logging.basicConfig(level=logging.DEBUG) class MegaAwesomePythonServer(BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.getheader('Content-Length')) data = urlparse.parse_qs(self.rfile.read(length)) logging.debug("from: " + data.get("from")[0]) logging.debug("to: " + data.get("to")[0]) logging.debug("direction: " + data.get("direction")[0]) doc = Document() response = doc.createElement('Response') play = doc.createElement('Play') url = doc.createElement('Url') urlString = doc.createTextNode('http://www.example.com/example.wav') url.appendChild(urlString) play.appendChild(url) response.appendChild(play) doc.appendChild(response) self.send_response(200) self.send_header('Content-Type', 'application/xml') self.end_headers() self.wfile.write(doc.toxml()) server = HTTPServer(('', 3000), MegaAwesomePythonServer) server.serve_forever() ================================================ FILE: examples/python/reject.py ================================================ #!/usr/bin/env python from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urlparse import logging from xml.dom.minidom import Document logging.basicConfig(level=logging.DEBUG) class MegaAwesomePythonServer(BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.getheader('Content-Length')) data = urlparse.parse_qs(self.rfile.read(length)) logging.debug("from: " + data.get("from")[0]) logging.debug("to: " + data.get("to")[0]) logging.debug("direction: " + data.get("direction")[0]) doc = Document() response = doc.createElement('Response') reject = doc.createElement('Reject') reject.setAttribute('reason', 'busy') response.appendChild(reject) doc.appendChild(response) self.send_response(200) self.send_header('Content-Type', 'application/xml') self.end_headers() self.wfile.write(doc.toxml()) server = HTTPServer(('', 3000), MegaAwesomePythonServer) server.serve_forever() ================================================ FILE: examples/python/server.py ================================================ #!/usr/bin/env python from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import urlparse import logging logging.basicConfig(level=logging.DEBUG) class MegaAwesomePythonServer(BaseHTTPRequestHandler): def do_POST(self): length = int(self.headers.getheader('Content-Length')) data = urlparse.parse_qs(self.rfile.read(length)) logging.debug("from: " + data.get("from")[0]) logging.debug("to: " + data.get("to")[0]) logging.debug("direction: " + data.get("direction")[0]) self.send_response(200) self.end_headers() self.wfile.write("http://xkcd.com/353/") server = HTTPServer(('', 3000), MegaAwesomePythonServer) server.serve_forever() ================================================ FILE: examples/ruby/sinatra/dial-number.rb ================================================ require 'sinatra' require 'builder' set :port, 3000 post '/' do logger.info "from: #{params[:from]}" logger.info "to: #{params[:to]}" logger.info "direction: #{params[:direction]}" headers 'Content-Type' => "application/xml" xml = Builder::XmlMarkup.new(:indent => 2) xml.instruct! xml.Response{xml.Dial{xml.Number("4915799912345")}} end ================================================ FILE: examples/ruby/sinatra/dial-voicemail.rb ================================================ require 'sinatra' require 'builder' set :port, 3000 post '/' do logger.info "from: #{params[:from]}" logger.info "to: #{params[:to]}" logger.info "direction: #{params[:direction]}" headers 'Content-Type' => "application/xml" xml = Builder::XmlMarkup.new(:indent => 2) xml.instruct! xml.Response{xml.Dial{xml.Voicemail}} end ================================================ FILE: examples/ruby/sinatra/play-url.rb ================================================ require 'sinatra' require 'builder' set :port, 3000 post '/' do logger.info "from: #{params[:from]}" logger.info "to: #{params[:to]}" logger.info "direction: #{params[:direction]}" headers 'Content-Type' => "application/xml" xml = Builder::XmlMarkup.new(:indent => 2) xml.instruct! xml.Response{xml.Play{xml.Url("http://www.example.com/example.wav")}} end ================================================ FILE: examples/ruby/sinatra/reject.rb ================================================ require 'sinatra' require 'builder' set :port, 3000 post '/' do logger.info "from: #{params[:from]}" logger.info "to: #{params[:to]}" logger.info "direction: #{params[:direction]}" headers 'Content-Type' => "application/xml" xml = Builder::XmlMarkup.new(:indent => 2) xml.instruct! xml.Response{xml.Reject("reason" => "busy")} # xml.Response{xml.Reject} end ================================================ FILE: examples/ruby/sinatra/server.rb ================================================ require 'sinatra' set :port, 3000 post '/' do logger.info "from: #{params[:from]}" logger.info "to: #{params[:to]}" logger.info "direction: #{params[:direction]}" end ================================================ FILE: examples/scala/Server.scala ================================================ import org.http4s.server.blaze.BlazeServer import org.http4s.server.HttpService import org.http4s.dsl._ import java.net.URLDecoder object Server extends App { def parseBody(body: String) = { body.split("&").map( s => { val m = s.split("=", 2).map(s => URLDecoder.decode(s, "UTF-8")) m(0) -> m(1) }).toMap } val service: HttpService = { case req @ POST -> Root => val data = parseBody(text(req).run) println("from: " + data.getOrElse("from", "")) println("to: " + data.getOrElse("to", "")) println("direction: " + data.getOrElse("direction", "")) Ok("roger that") } BlazeServer.newBuilder.mountService(service, "/").run() }