Friday 24 July 2015

Developing USSD apps: ussdmenuserver-2.0.jar

NB: You can now read this post at my new site

Hey there, hope your Friday is good. Just as promised in the last post, today we shall navigate a very useful library for you who desires to build meaningful USSD apps.


ussdmenuserver.jar

After developing about 2 non-trivial USSD apps, I got a bit overwhelmed by the sheer amount of repetitive code I needed to write.

Repetitive code should be abstracted, and that's how I came up with ussdmenuserver.jar, yeah i built it, now go buy me a beer (it's Friday remember!!!)


Am yet to host the code on github so that some of you out there may contribute to it with ease, I thoroughly recommend you do.


Lets do this!!!!!


Now power up you IDE and open the UssdTestApp project. Head to the UssdReceiver.java servlet and make it extend UssdReceiver instead of MchoiceUssdReceiver.

Well, you have to rename your servlet to something like MyUssdReceiver since the parent class has the same name. Don't forget to change the servlet class name in the web.xml deployment descriptor.

Your IDE should be flagging reds already, so you need to add ussdmenuserver-2.0.jar to your build path.

For those with whom I already shared the jar via mail, you may have to update it with a new one from me. Those who haven't got a copy you can send me mail and I will share it with you.

After adding it to build path, you'll get another red prompting you to implement some abstract methods. Please do so, now this is my servlet code:


package com.egima.ussd;

import com.egima.ussdmenuserver.UssdReceiver;
import com.egima.ussdmenuserver.UssdTree;

public class MyUssdReceiver extends UssdReceiver {

       /**
        *
        */
       private static final long serialVersionUID = 1L;

       @Override
       public String getAppShortCode() {
             // TODO Auto-generated method stub
             return null;
       }

       @Override
       public int getBufferLimit() {
             // TODO Auto-generated method stub
             return 0;
       }

       @Override
       public String getUssdAppId() {
             // TODO Auto-generated method stub
             return null;
       }

       @Override
       public String getUssdAppPassword() {
             // TODO Auto-generated method stub
             return null;
       }

       @Override
       public String getUssdClientUrl() {
             // TODO Auto-generated method stub
             return null;
       }

       @Override
       public UssdTree getUssdTree() {
             // TODO Auto-generated method stub
             return null;
       }


}



The appShortCode:
Short code the client will have to type on their handset in order to be routed to your app.

The buffer limit:
Maximum number of menu items you would like to send the client handset in a single message. It defaults to 4. You could change it to 5 in case your items are likely to be one-liners, otherwise if they span several lines each, you may have to bring it to 3 or less as you see fit.

If a menu has 6 items and your buffer limit is 4, then the first 4 items will be sent in a single message with a '00.more' item at the bottom, when the user selects this, the other 2 items will constitute another message.

Another consideration to make is that every menu comes with a '0.exit' option at the bottom. so the number of items in your menu message will always be extra by 1 or if buffered, '00.more' will be the second extra item.

I haven't put a '#.back' option yet, should be pretty easy to add soon, when i get some time.


The appid
This is the real identity of the app on the server, for our simulation, it defaults to 'appid'.

The password
Not any server/client will route a request to you app server, it must be authenticated with a password. For simulation, our app password will default to 'password'.

The clientUrl
This is the url of the handset making the USSD request. In our case we shall give the URL of the simulator, I defaulted it to "http://127.0.0.1:8000/ussd/"

The UssdTree
This is an abstract data type which takes all your menu items in a flat manner and then builds them into a tree structure/hierarchy for intuitive navigation.

All the magic of this library happens in UssdTree, it's where most of your code will be.

You pass to it UssdNodes using the addNode

(ussdnode)
method
The UssdNode
This is an object which wraps each item making up your USSD menu. The main node is the root, which is created by default in the UssdTree constructor.

Each UssdNode has a parent and may have children or not. It must also have a name for identity and a title for display.

Your menu items at the top of the hierarchy will register 'root' as their parent and when one of them is selected, UssdTree will return its children if available.

UssdPrompt
This is a sub-class of UssdNode and so you add it to UssdTree asa normal node.Most USSD menus require a client to press a number corresponding to a menu item.

However, usually at the end of the menu tree, you may need toask a client for a certain arbitrary data such as a pin for authentication of the transaction or an MSISDN (phone number) in case you are doing something like a send money transaction with mobile money app.

In this case therefore, you use a UssdPrompt instead of UssdNode like so:

  • It's title is used as a prompt message to display to the client
  •  write some validation rules for the input data, this may involve a database look up or basic regex.
  • Write an error message to display to client in case validation fails on your rules 


UserData
It would be pointless to let the user select several options down the menu tree and not save thieir selections.

So at run time, each data selected by the client is saved into a HashMap and you can access it at any point in the session.

How data is persisted!!!
Remember each UssdNode has a name and a parent. So when client selects an item, the item's name becomes the key for that data.

You send a message to the client to either select another option from the children of the earlier selected item, or to input some data if it's a prompt.The name of the selectedchild or the arbitrary data input on the prompt  becomes value of the map entry.

How do I access this data???
The UssdNode object has another non-abstract method called processNodeEndEvent(HashMap userData)

You can override it when creating a UssdNode or UssdPrompt object. It's single parameter contains all the prior data inputs. However, we assume you know the names of the data and their data types since 
you created the validation rules.

The return type of this method is a string which is usually the last message you send a client during the session e.g.


 you have sent 10,000 shillings to 0775504026, cost is 300, your balance is 12,700.

This method is called if a selected child has no children, the assumption is that the code you place here constitutes the last process you need to execute to complete the session, and that you are not supplying any more menus for selection.

The string you return constitutes the final session-end message to the client.



1 comment:

  1. Are you able to help with configuartion and connection of ussd app. Running into some issue connecting with telco gateway. having a feeling the issue might be with routing in the sample code. send me an email for more info: zanmi02136 at gmail.com

    ReplyDelete