.. _client-api-intro: ============ Introduction ============ .. contents:: :local: :depth: 3 Overview -------- Acrobits VoIP apps can be configured to call web services to add new features to the app. These web services are typically implemented by VoIP provider. Some typical examples are: - balance checker: returns current credit for the registered used, which is then shown in the app - web callback: tells the provider to call a local number and a destination number and connect those two calls - etc. .. _web-service-definition: Web Service Definition ---------------------- The apps need to know where the web service is located and how it should be called. The web service is typically defined using a group of XML nodes, whose names have common prefix followed by field specifier. The node names follow camelCase notation. The "Prefix" specifies the type of web service, for example ``genericRateCheck`` or ``genericMediaUpload``. The list of supported XML nodes follows: ``PrefixUrl`` ~~~~~~~~~~~~~ The URL of the web service, including the query string. The scheme of the URL must be either ``http`` or ``https``. Example: ``https://example.com/endpoint?username=%account[username]%&password=%account[password]%`` ``PrefixPostData`` ~~~~~~~~~~~~~~~~~~ Body of the web service request. It is not use in case ``GET`` request method is selected. The content type of the body should match the value specified in ``PrefixContentType`` parameter, which should always be set. Example: ``username=%account[username]%&password=%account[password]%`` ``PrefixContentType`` ~~~~~~~~~~~~~~~~~~~~~ The contents of Content-Type header which the app will use to send the request. If empty, ``application/x-www-form-urlencoded`` will be used by default. ``PrefixMethod`` ~~~~~~~~~~~~~~~~ HTTP method to use for this web service. Defaults to ``GET``. Possible values are ``GET``, ``POST``, ``PUT``, ``HEAD`` and ``DELETE``. In case the method is not specified, the app will use GET in case ``PrefixPostData`` are empty, otherwise it will use ``POST``. ``PrefixAuthUsername``, ``PrefixAuthPassword`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If set, the app will use Digest HTTP authentication with these credentials. ``PrefixCustomHeaders`` ~~~~~~~~~~~~~~~~~~~~~~~ Contains list of additional HTTP headers to be sent along with the request. Multiple headers may be specified, separated by a newline character (\n). Example: ``Header1: Value1\nHeader2: Value2`` ``PrefixTimeout`` ~~~~~~~~~~~~~~~~~ Specifies custom timeout. If the response does not arrive within this timeout, the request it terminated with failure. The default is 30 seconds. Note that only the ``PrefixUrl`` field is always required; it is sufficient to describe a basic ``GET`` request. Url, ContentType and PostData are enough to define a basic ``POST`` request. Parameters ---------- Parameters are passed to web services via template strings. These template strings contain variables enclosed in percent characters. The apps try to interpret these variables and replace them with actual values. The parameters have different scopes, described below. .. _global-params: Global parameters ~~~~~~~~~~~~~~~~~ These parameters are always available and can be used for any web service. Here is a list of them. ``%installid%`` A unique identifier of the app installation. This value is created when the app is ran for the first time on the given device and survives app updates. It is lost when the app is uninstalled. ``%appid%`` Application's identifier. It is the bundle id for iOS apps and package id for Android. Typically the reverse-domain is used for this identifier, like ``com.provider.appname.ios``. .. warning:: Starting iOS 16.4, the **MCC** and **MNC** parameters are no longer available. Devices running iOS 16.4 or later will report an empty string for these parameters. .. warning:: The **MCC** and **MNC** parameters are accessible on Android devices only after the user grants the Phone permission to the app. If the user denies the permission, the **MCC** and **MNC** parameters will be empty strings. ``%mcc%`` Mobile country code, read from the SIM card. In case of dual-sim phone, it is read from currently selected SIM. Empty string when the information is not available. See `Mobile Country Codes (MCC) and Mobile Network Codes (MNC) `_ for known values. ``%mnc%`` Mobile network code, read from the SIM card. It identifies network operator who issued the SIM. See the point above for link to documentation. ``%uniqueid%`` Device unique identifier. This identifier is bound to the device and should survive app updates and even removal / re-install of the app. Because of iOS privacy policy, this may not work reliably on iOS devices. ``%build%`` Build number of the app which sends the request. ``%platform%`` The platform of the client. For example, "iOS" or "Android". ``%platformversion%`` The version of platform. For example, "9.2.3". ``%version%`` The version of the app which is sending the request. ``%appname%`` The (possibly localized) name of the application. ``%locale%`` The current locale the app is using. For example: ``en-us``, ``de-de`` etc. ``%localTime%`` The local time of the user as reported by the OS. Formatted according to `RFC3339 `_. ``%utcTime%`` The Coordinated Universal Time as reported by the OS. Formatted according to `RFC3339 `_. ``%cpu%`` CPU type of the device where the app is running. ``%device%`` Identifier of the type of device where the app is running. This identifier is taken from the mobile OS, the values are for example ``iPhone6,2``, ``GT-I9100`` etc. ``%campaignTrackingUrl%`` Google campaign identifier. In case the user installed the app from an ad campaign, this variable will contain the campaign id. For technical details, see `Google Documentation `_. **Note**: this is only available on Android, iOS apps will always return empty string. ``%productionBuild%`` For Cloud Softphone white-label apps, this parameter will be ``1`` in case of production builds and ``0`` othwewise. This makes it possible to distinguish testing and production builds. Generic Cloud Softphone, as well as Softpohne and Groundwire apps will always have this parameter set to ``1``. .. _account-params: Account parameters ~~~~~~~~~~~~~~~~~~ Available for web services which are related to a SIP account (which is most of them). Account information is stored in account XML format and any node from this XML can be used as a parameter. These parameters are specified as ``%account[KEY]%``, where KEY is one of the identifiers described in :doc:`../../cloudsoftphone/account` document. .. code-block:: none https://example.com/script?user=%account[username]%&password=%account[password]% .. warning:: The apps will never send account password (``%account[password]%``) over unencrypted connection. You need to use HTTPS scheme in order to be able to pass the password parameter. If you can't use HTTPS for any reason, check the **sha1** and **nonce** :ref:`template-functions` with examples below. Service-specific parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~ These are defined per-web service and are used to provide the task-specific information the web service needs. They are described in detail in the specific web-service documentation. .. _template-functions: Functions --------- Parameters can be transformed using several builtin functions. The format to specify function in the parameter template string is: .. code-block:: none %function(parameter)% Supported functions are: ``lower`` Converts the argument to lowercase. .. code-block:: none %lower(%account[username]%)% ``upper`` Converts the argument to uppercase. .. code-block:: none %upper(%account[username]%)% ``store`` defines a new named parameter and stores its value for later use. This function generates no output into the final string - it's replaced by empty string. .. code-block:: none %store(name=%account[username]%)% ``load`` loads a previously stored parameter and puts its value to output, or uses it as an argument to another function. .. code-block:: none %load(name)% ``sha1`` Returns SHA-1 hash of the argument. The example below outputs SHA-1 hash of account password. .. code-block:: none %sha1(%account[password]%)% ``base64`` Returns the argument base64-encoded. The example below outputs Basic Authorization header: .. code-block:: none Authorization: Basic %base64(%account[username]%:%account[password]%)% ``nonce`` generates a random string of characters from the following alphabet: ``0123456789abcdefghijklmnopqrstuvwyz``. Length of the string is specified via parameter. .. code-block:: none %nonce(8)% The example below generates a salt and puts salted SHA-1 hash of account password into output string and demonstrates combined use of **store**, **load**, **nonce** and **sha1** functions. .. code-block:: none %store(salt=%nonce(8)%)%salt=%load(salt)%&hashedPassword=%sha1(%load(salt)%:%account[password]%)% Web Service Responses --------------------- The response is naturally web-service specific, but there are some common points. The apps will recognize responses in any of the following Content-Types: - application/xml - application/json - application/x-www-form-urlencoded In case no Content-Type header is present in the response, the app will try to parse the response body as XML document. The response is considered successful if the following conditions are met: - HTTP response code is ``2xx`` or ``304`` - The response body can be parsed from the format specified by Content-Type header In case the response code is not one of the success response codes mentioned above, the app will still try to parse the body and if it succeeds, it tries to find a field "message" in the body. If present, it will take the contents of this field and show it as an error message to the user. In case the "message" field is not found, the app takes first 100 characters of the raw response body and shows that to the user instead. .. note:: It's highly recommended to put "message" field into your error responses. In case you want to show localized messages, you can pass the current device language via %locale% parameter in your request and choose the localized version based on this information. Example Error Responses: ~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: http HTTP/1.1 403 Forbidden Date: Sun, 15 Mar 2015 00:46:17 GMT Server: Apache/2.4.7 (Ubuntu) Vary: Accept-Encoding Content-Length: 123 Content-Type: application/xml Keep-Alive: timeout=5, max=100 Connection: Keep-Alive You are not allowed to do this .. code-block:: http HTTP/1.1 403 Forbidden Date: Sun, 15 Mar 2015 00:46:17 GMT Server: Apache/2.4.7 (Ubuntu) Vary: Accept-Encoding Content-Length: 123 Content-Type: application/json Keep-Alive: timeout=5, max=100 Connection: Keep-Alive {"message" : "You are not allowed to do this"} .. code-block:: http HTTP/1.1 403 Forbidden Date: Sun, 15 Mar 2015 00:46:17 GMT Server: Apache/2.4.7 (Ubuntu) Vary: Accept-Encoding Content-Length: 123 Content-Type: application/x-www-form-urlencoded Keep-Alive: timeout=5, max=100 Connection: Keep-Alive message=You%20are%20not%20allowed%20to%20do%20this