Posted by & filed under Blog, News, Tech, Testimonial.

This article tells the story how I created a mobile application for an existing web API using the Rogerthat platform.

Intro

A while ago, Toon Vanagt -a former colleague- introduced me to his new startup data.be. His goal is to lower the barriers for businesses to access accurate data of other businesses. See http://data.be for more information on his product. Recently they also opened up their database via a REST api (http://api.data.be). I told Toon (Toon Vanagt, co-founder of data.be) that creating a service for Rogerthat that uses his API, would be very simple. The next day he sent me an API key for his cloud based service, so I could hack something together as soon as I had some time to spend. Last sunday evening at 8pm that time had come.

Ready, Set, Go: Service homescreen

November 25, 2012 8:00:05 pm
I started with having a look at the API documentation of data.be (https://api.data.be/) to examine what functionality the service should contain.
Their api currently offers three services: validate a VAT number, check the status of a company & get some basic information (name, foundationdate, address, status, …) about a company.
Okay this meant I had to create a homescreen with three icons.

I needed about 10 minutes to identify the functionality and to add matching homescreen icons as displayed in the screenshot on the left.

References:
How to create a homescreen

Look & feel: we need a screen branding

November 25, 2012 8:10:35 pm
To give the data.be service the same look & feel as the data.be website, I had to create a screen branding. A screen branding is a reusable definition for look and feel which you can create in HTML. The HTML together with the related css files and images can be uploaded as a zip into the Rogerthat service configuration panels.
To get started, I opened the data.be website in the chrome browser. Using inspect I removed some content in the data.be website so I could take a nice screenshot of 320 pixels wide containing logo and the background they use.

The width of the screenshot (320px) is important because lots of devices have a screen width of 320 pixels or a multiple of it (iPhone 640px).

To complete the screen branding, I created the HTML in which I configured how the screen branding should behave:

<html> 
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 
 <meta property="rt:style:background-color" content="#285a7d"/>
 <meta property="rt:style:show-header" content="false"/>
 <meta property="rt:style:color-scheme" content="dark"/>
 <style type="text/css"> 
  body { padding: 0px; margin: 0px; background-color: #285a7d;}
  #background img { width: 100% }
  #background { width: 100%; text-align: center; margin-bottom: 5px; }
  #message { margin: 0.5em; }
  #message span { font-family: Arial; font-size: 1.2em; color: white; }
</style> 
</head> 
<body>
<div id="background"><img src="data.be.header.png" /></div>
<div id="message"><span><nuntiuz_message/></span></div>
</body> 
</html>

Notice the meta tags which define how Rogerthat displays the screen branding.
Creating the screenshots, writing the HTML and packaging them together into a zip took me another 20 minutes. Off course the fact that I had done this before, and that I had a couple of other screen brandings laying around was actually an advantage.

After uploading the screen branding, I configured the home screen to use it. You can see the result on the left.

References:
How to create a Rogerthat screen branding

Finally, it is coding time!

November 25, 2012 8:30:35 pm
All right, as a developer this is the part I like the most. Now I had to add code somewhere, so that the user gets some screens after he presses the icons in his homescreen. This can be done through integrating with our api. The last few years I started using Google App Engine to create online services. So I created the integration between the APIs of Rogerthat and data.be in a Google App Engine app using Python.
First created a request handler that handles callbacks originating from the Rogerthat cloud when the user uses the data.be service in his Rogerthat app.

# Service identifier key, blanked out with stars for the example because this is a secret
SIK = "******"
# Key of the branding, also blanked out
BRANDING = "******"

class DATADOTBEServiceHandler(webapp2.RequestHandler):

    def post(self):
        self.response.headers['Content-Type'] = 'application/json'

        # Check whether the request can be authenticated as coming from the Rogerthat cloud 
        # regarding activity of the data.be Rogerthat service
        sik = self.request.headers.get("X-Nuntiuz-Service-Key", None)
        if sik != SIK:
            logging.info("Denying request with SIK " + sik)
            self.response.set_status(401)
            return

        call_json = json.loads(self.request.body)
        method = call_json["method"].replace(".", "_")
        error = None
        result = None
        if hasattr(self, method):
            try:
                result = getattr(self, method)(call_json)
            except Exception, e:
                logging.exception("Error occured while processing request.")
                error = str(e)

        json.dump({'id': call_json['id'], 'result': result, 'error': error}, self.response.out)

    def test_test(self, call_json):
        # Is called by Rogerthat to test if the callback apis are reachable and function as expected. 
        # See http://www.rogerthat.net/developers/getting-started/#How_to_test_your_service
        return call_json["params"]["value"]

This is the basic setup I use in all my Rogerthat integration processes. It actually automates my integration with the Rogerthat callback apis so that I only need to focus on the implementing the methods that I need to implement for a specific service.
Creating an application on Google App Engine, adding this first request handler, deploying it to Google, and validating the setup from the Rogerthat service panels took me another 20 minutes.

November 25, 2012 8:51:15 pm
When the user presses the icons in the service home screen, I get a poke callback (see poke api callback documentation), so in order to react on this with a form in which the user can enter a VAT number, I need to implement this method:

class DATADOTBEServiceHandler(webapp2.RequestHandler):

...

    def messaging_poke(self, call_json):
        tag = call_json["params"]["tag"]
        email = call_json["params"]["email"]
        logging.info("Received poke from %s with tag %s" % (email, tag))
        if tag in ("is_vat_valid", "company_status", "company_info"):
            return get_vat(tag)


def get_vat(tag):
    return dict(type='form',
                value=dict(message="Voer het BTW nummer in dat u wil controleren:",
                           form=dict(type="text_line", positive_button="Valideer", 
                                     positive_button_ui_flags=1, negative_button="Annuleren", 
                                     widget=dict(max_chars=15, 
                                                 place_holder="BTW nummer",
                                                 value=None)), 
                           flags=64, alert_flags=1, branding=BRANDING, tag=tag))

The result of this method looks like this:
This took me 30 minutes to get right.

Note: this example shows API usage which is at the time of writing not yet documented in our reference documentation but will be very soon.

 

November 25, 2012 9:21:05 pm
At this time the functionality to validate a Belgian VAT number was 50% finished. When the user presses the icon in the menu, the callback handling this request results in a screen asking the user to the enter the VAT number. The next step is to accept the input of the user, validate the VAT number and send back a screen with the results of the validation. To implement this, I added the next piece of code:

class DATADOTBEServiceHandler(webapp2.RequestHandler):

...

    def messaging_form_update(self, call_json):
        logging.info(json.dumps(call_json, indent=4).encode('utf8'))
        answerid = call_json["params"]["answer_id"]
        tag = call_json["params"]["tag"]
        if not answerid == "positive":
            # The user pressed the cancel button
            return
        if tag == "is_vat_valid":
            # The user entered the VAT number after pressing the icon to validate a VAT number
            return validate_vat(call_json)

def validate_vat(call_json):
    vat_orig = call_json["params"]["form_result"]["result"]["value"]
    if not vat_orig:
        # nothing was entered, send screen to enter VAT again
        return get_vat(call_json["params"]["tag"])
    # sanitize input
    vat = "".join((c for c in vat_orig if c in "0123456789"))
    # callout to the data.be API to validate the VAT number
    result = urlfetch.fetch("https://api.data.be/1.0/vat/%s/validity?api_id=***&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;api_key=****" % vat)
    # validate result of the API call
    if result.status_code != 200:
        logging.error("Failed to validate vat:\nstatus=%s\nerror=%s" % (result.status_code, result.content))
        return dict(type='message',
                value=dict(message="%s is GEEN geldig BTW nummer." % vat_orig,
                           answers=[], flags=1, alert_flags=1, branding=BRANDING, tag=None))
    logging.info(result.content)
    # parse result of API call
    result = json.loads(result.content)
    if not result["success"]:
        return dict(type='message',
                value=dict(message="%s is GEEN geldig BTW nummer." % vat_orig,
                           answers=[], flags=1, alert_flags=1, branding=BRANDING, tag=None))
    # prepare result screen
    if result["data"]["valid"]:
        message = "%s is een GELDIG BTW nummer." % result["data"]["vat-formatted"]
    else:
        message = "%s is GEEN geldig BTW nummer." % result["data"]["input"]
    # return result screen
    return dict(type='message',
                value=dict(message=message, answers=[], flags=1, alert_flags=1, 
                           branding=BRANDING, tag=None))

Adding this piece of code took me another 25 minutes.

November 25, 2012 9:45:15 pm
After 1 hour and 45 minutes I was ready with the first functionality. Luckily the two remaining features were very similar, so I could reuse quite some code to implement them as well.
The 1 hour and 15 minutes remaining, I used to add those 2 remaining features as well as adding a nice description for the data.be Rogerthat® service, and do some testing, before declaring it ready.

At the end I was really proud of my accomplishment, creating a mobile application on Sunday eve, which was functional, looked nice and works very good.

November 25, 2012 11:05:08 pm
Done.

To try data.be Rogerthat service I made, just search for data.be in the services tab of the Rogerthat app on your iPhone or Android app or via the Rogerthat web version accessible at https://rogerth.at

Leave a Reply