Articles & Information.

Tutorial 4: Saying hello to our users

Select a topic:

Choose from one of the topics below to browse other articles

Last updated by Rudolph Keown on September 02, 2013 15:00

At the end of Tutorial 3, we had successfully set up a Mongo database service on AppFog that will be available to our running app. We also connected to it via a tunnel to check that all was working. This tutorial is all about connecting to our database and doing something useful with it every time a Mxit user visits our app. Let’s get started!


A word on Mongo

Before we do start inserting records into our database, a word on Mongo is in order. Mongo is the latest generation of what is called NoSQL databases. In Mongo, instead of records being inserted into rows of a table, documents are inserted into collections which are part of a database. If you’ve spent your life doing SQL and queries, then Mongo can seem a little strange. But it’s not very difficult and as we’ll see, PHP’s built-in Mongo API makes the details very straightforward. Here’s a reminder of what we did last time with Mongo:

> u = { mxitid: 'a-mxit-user' }{ "mxitid" : "a-mxit-user" }
> db.mxitusers.insert(u)
> v = {mxitid: 'another-mxit-user'}
{ "mxitid" : "another-mxit-user" }
> db.mxitusers.insert(v)
> show collections
mxitusers
system.indexes
system.users
> db.mxitusers.find()
{ "_id" : ObjectId("515e3b27c54c33504dbcb9f4"), "mxitid" : "a-mxit-user" }
{ "_id" : ObjectId("515e3b4bc54c33504dbcb9f5"), "mxitid" : "another-mxit-user" }
>


u and v are called documents, mxitusers is the collection and db is the database. The values of documents are simply JSON key-value pairs and we’ve set the key to be ‘mxitid.’ And I have to confess, I’ve made a mistake with the data I’ve put into the collection. The mxitid that we can retrieve from a user visiting our application is actually an internal representation and looks something like ‘m123457890’ - not the human friendly “a-mixit-user.” No matter - we’ll be inserting the correct information in our PHP program and it will work with the messaging API. If you want to learn more about Mongo, its excellent tutorial starts here.


Step 1- Connecting via PHP

We’ll be editing our standard index.php as usual. The first thing our app needs to do is to connect to the Mongo service when it loads. That looks like this:

$services_json = json_decode(getenv("VCAP_SERVICES"),true);$mongo_config = $services_json["mongodb-1.8"][0]["credentials"];
$username = $mongo_config["username"];
$password = $mongo_config["password"];
$hostname = $mongo_config["hostname"];
$port = $mongo_config["port"];
$db = $mongo_config["db"];
$name = $mongo_config["name"];
$connect = "mongodb://${username}:${password}@${hostname}:${port}/${db}";
$m = new Mongo($connect);
$db = $m->selectDB($db);
$collection = $db->mxitusers;

The first line grabs some content out of an environment variable that is set server side when an AppFog app loads. We then extract the mongo configuration details from it and assign them to some useful variables. Finally we connect to the Mongo service through PHP’s API and select the database we’ve been given by AppFog.  Then we assign a handle to our collection called mxitusers.  

$visitor = $_SERVER['HTTP_X_MXIT_USERID_R'];
$document = array("mxitid" => $visitor);
$collection->insert($document);

These three lines get the mxitid of the visitor to our page through the server headers and save them into $visitor. We then create a new document and insert it into our collection. Now every time someone visits us as a contact in Mxit, their mxitid (that long string I described earlier) will be added to the Mongo collection. Try it! Upload this code as your index.php - remember to surround it with correct php tags - and then visit your app from within Mxit. If you then tunnel through to the Mongo database and issue a: 

> db.mxitusers.find()

you’ll see it’s adding your mxitid to the collection each time.


Step 2 - Messaging 

So now that we can save each user who visits us in a database, let’s send them a message each time they land. We’re going to be using Ashley Kleynhans’ excellent Mxit API for PHP that’s available here. You will need to get the MxitAPI.php from this site - either via git or as a normal download - and then place the file MxitAPI.php in the same directory as your app (in our case testappmxit). Let’s edit index.php some more:

require_once ('MxitAPI.php');
$key = 'f00ff00fabcdabcdabcdg00f';
$secret = 'deadfoofabcd12abcdgoof';
$api = new MxitAPI($key, $secret);


These lines load the API and initialise it with the key and secret. I’ve put in placeholder values - you will need to put in your real key and secret that Mxit gave you in tutorial 1 - it’s shown on the App Dashboard as Client ID and Secret like so: 


Figure 1: Obtaining your Client Id and Secret for your app


/* Set up the message */
$message = "Thanks for visiting!";
$contains_markup = 'false';
$app = "testappmxt";
$access_token = NULL;

Then we set up some parameters for the API function send_message. 

while (is_null($access_token))
{        /* We are sending a message so request access to the message/send scope */
$api->get_app_token('message/send');
$token = $api->get_token();
$access_token = $token['access_token'];        // Only attempt to send a message if we have a valid auth token
 if (!is_null($access_token))
   {
    $api->send_message($app,$visitor,$message,$contains_markup);  
   }
}

Finally we send the message. First we attempt to get authorisation to send a message. If we get it (the token is not NULL) then we send the message to our user. The $contains_markup flag tells the API that the message contains Mxit markup - we’re not doing that this time so it’s false. If a user adds testappmxt as a contact and opens a conversation, they’ll see something like this: 



Figure 2: A look at your use of the Messaging API from within your app! 

Step 3 - The Final Program

<?php
require_once ('MxitAPI.php');
$services_json = json_decode(getenv("VCAP_SERVICES"),true);
$mongo_config = $services_json["mongodb-1.8"][0]["credentials"];
$username = $mongo_config["username"];
$password = $mongo_config["password"];
$hostname = $mongo_config["hostname"];
$port = $mongo_config["port"];
$db = $mongo_config["db"];
$name = $mongo_config["name"];
$connect = "mongodb://${username}:${password}@${hostname}:${port}/${db}";
$m = new Mongo($connect);
$db = $m->selectDB($db);
$collection = $db->mxitusers;
$visitor = $_SERVER['HTTP_X_MXIT_USERID_R'];
if ($visitor == '') {
 $visitor = "Web user";
}
$document = array("mxitid" => $visitor);
$collection->insert($document);
/* Instantiate the Mxit API */
$key = 'f00ff00fabcdabcdabcdg00f';
$secret = 'deadfoofabcd12abcdgoof';
$api = new MxitAPI($key, $secret);
/* Set up the message */ $message = "Thanks for visiting!";
$contains_markup = 'false';
$app = "testappmxt";
$access_token = NULL;
while (is_null($access_token))
     { /* We are sending a message so request access to the message/send scope */ $api->get_app_token('message/send');
$token = $api->get_token();
$access_token = $token['access_token']; // Only attempt to send a message if we have a valid auth token
if (!is_null($access_token))
  {
    $api->send_message($app, $visitor, $message, $contains_markup);
  }
}

Troubleshooting

During the course of testing this program, I ran into some problems which aren’t particularly obvious to solve so I present the answers here. If you issue an ‘af update testappmxit’, visit your page and AppFog complains like so: 



 Figure 3: Error message seen if your update command goes wrong. 

then you need to restart your PHP app from the AppFog console. Of course, check also that you haven’t got stuck in an endless loop!

If you issue an af update testappmxt command and get an error like:

Uploading Application
No such file or directory:  -work/mxit/testappmxt/user@host.3458:1365044373

then there is a rogue file left in your application directory that shouldn’t be there. It’s a symbolic link left over from an ‘af’ operation that hasn’t been deleted. Delete it by hand and your update should succeed. 


What's next?

In Tutorial 5, we’ll be using the Billing API to integrate billing into our app. See you then!