A lightweight USSD application framework.
lib-ussd takes simple declarative UI concepts to USSD application developments.
UI behavior is defined in a XML file as <screen>
elements while handlers for screen actions are defined as methods in an injectable component (e.g CDI bean or EJB).
The easiest way to get started using lib-ussd is by using the ussd-app-archetype Maven archetype. Make sure you have Maven installed and type the following at the terminal.
mvn archetype:generate -DarchetypeGroupId=com.hextremelabs.ussd -DarchetypeArtifactId=ussd-app-archetype
This generates a sample Maven USSD project. Build the project and deploy the generated war
file on a Java EE application server.
As this is a Maven project, you can open it in your favorite IDE to start crafting your USSD app!
Alternatively, you can create the sample project from within your favorite IDE. On NetBeans for example:
Click File
-> New Project
Click Maven
-> Project from Archetype
Search for ussd-app-archetype
If however you would like to start your USSD application from scratch, you will need to create a Java EE Web Application with the following dependencies:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.hextremelabs.ussd</groupId>
<artifactId>lib-ussd</artifactId>
<version>1.0.1</version>
</dependency>
If you are using a build system that cannot resolve Maven dependencies (e.g Ant) you can grab the latest JAR dependency here.
If you build and deploy the genrated project to a Java EE server, publishes a HTTP endpoint at http://{server_address}:{port}/{context_root}/ussd/endpoint
This endpoint is able to receive HTTP GET and POST request. The endpoint extracts the following parameters from HTTP requests (as telcos typically send):
sessionid
(the telco-generated session ID)msisdn
(e.g2348021234567
)provider
(e.gairtel
)message
(e.g*559*3*4#
)
You don't need to create this endpoint, lib-ussd
automatically publishes it for you.
If you want to customize how these parameters are being extracted from the HTTP request please override UssdHandler
's parseRequest
method (see below).
There are two important files in the generated project:
src/main/resources/ussd-app.xml
src/main/java/path/to/your/package/Handler.java
The ussd-app.xml
file (which is backed by this schema) defines all screen interactions.
Most popular IDEs should offer you editing support (suggestions/autocomplete) for this XML file.
The Handler
class (which extends UssdHandler
) is where you define screen handlers.
For every <screen>
you create in the XML which has a callback
attribute, there should be a method in Handler
whose name matches the value of the callback
.
Such callback methods must have the following signature:
public String[] callbackName(Map<String, Object> data) {
// Do stuff and return string array result.
}
If no such method exists, an InvocationException
is thrown which results in the value of the errorMessage
attribute defined in the ussd-app
XML root tag being returned to the user.
If errorMessage
is not defined a default error message is returned.
If you want to customize how the handler dispatches calls to callbacks you can override UssdHandler
's invoke
method.
The elements of the String[]
returned by callbacks are used to inflate the template of the nextScreen
when rendering.
If a callback returns ["Sayo", "Oladeji"]
and nextScreen
targets a screen with content I am %s, son of %s
, the screen will be rendered as I am Sayo, son of Oladeji.
Rendered screens are cached and returned whenever the user requests to go back to the previous screen using the #
key.
<screen>
s with attribute type="textInput"
(see below) accept input from users (e.g "Please enter your account number").
All inputs received throughout a session are mapped as "screenId" -> input
. All results of callbacks are mapped as "screenId$Result" -> result
. Every time a callback is invoked, the entire mapping is passed to it.
It is the responsibility of the callback to pick the data it needs from this mapping (see the Handler.greetMe
method for example).
The UI framework is extremely simple. It's highly recommended that you play around with the XML in your IDE by invoking its intellisense to see the things it suggests. Even better is it that you read the well-documented schema backing the XML.
Anyway, if you've got no chill here's the gist:
-
ussd-app
: this is the root tag and it has the following attributes:name
: the name of this USSD application. This is used as the cache namespace when storing sessions. You can think of it as Angular'sng-app
:)lineSeparator
: the end-of-line character or character sequence used by the telco. Default is~
.errorMessage
: the response returned to the user if an error occurs while performing an operation. Such errors terminate the user's session. Default isOperation failed. Please try again later.
maxTextLength
: the maximum length of a USSD response supported by the telco. Default is 140 characters.
-
screen
: defines a screen as seen by the user. This element can have the following attributes:-
id
: the identifier of the screen. -
callback
: the handler method invoked when this screen is submitted. -
nextScreen
: the next screen displayed after this screen is submitted. -
type
: the screen type. Acceptable values are:options
: a list of options presented to the user. Usually this is a numbered list.textInput
: a screen that prompts the user for input.display
: a screen that displays a message to the user without expecting any input. This screen implicitly marks the end of a flow and therefore terminates the user session.
-
validation
: fortextInput
screens; the constraint imposed on the input text. Acceptable values are:free
: no validation is performed.numeric
: only numeric values (0 to 9) are allowed.alphanumeric
: only alphanumeric values (a to z, A to Z, 0 to 9) are allowed.regex
: the input is valudated against a specified regular expression.
Default is
free
-
regex
: for screens withvalidation="regex"
, the regular expression against with the input is validated.
A screen can have the following child elements:
header
: text rendered at the top of the screen.body
: text rendered at the middle of the screen.footer
: text rendered at the bottom of the screen.option
: for screens withtype="options"
. One or more instances of this element denoting each option.
The values of every of these elements can carry a placeholder
%s
. An attempt is made to sequentially inflate these placeholders using the result of the callback of the previous screen. -
-
option
: an option in an enumerated list of options. This element has the following attributes:trigger
: the character that selects this option. This should be unique in the list (it is recommended to be a sequence of numbers starting from 1).nextScreen
: the screen that selecting this option leads to.
- USSD session resumption is supported using the user's
msisdn
. - If the user doesn't reach the end of a flow, the session is invalidated after 5 minutes of inactivity.
- lib-ussd is just 53kb and only expects
javaee-web-api
,javax.enterprise.concurrent-api
andslf4j-api
to be available on the classpath at runtime. An application server like WildFly supplies these out of the box. - lib-ussd uses an in-memory key-value datastructure (local to a single host) for caching sessions. To supply a more sophisticated cache, provide an injectable bean implementing
com.hextremelabs.ussd.internal.Internal.Cache
.