Friday, September 5, 2014

Revisiting Bluemix with Twilio

This post walks you through the steps to use Twilio with IBM's Bluemix to send an SMS and also make a  voice call when you click a URL.  Twilio, is a cloud communications SaaS organization which allows you to use standard web languages to build voice, SMS and VOIP applications via a Web API.
Twilio provides the ability to build VOIP applications using APIs. Twilio itself resides in the cloud and is always available. It also provides SIP integration which means that it can be integrated with Soft switches. Twilio looks really interesting with its ability to combine the cloud, Web and VOIP, SMS and the like.
The steps given below allow you to use your app to perform 2 things by clicking the app's URL namely websmstest.bluemix.net
a) Send a SMS to your mobile phone
b) Make a voice call to your mobile phone
The code can be forked from Devops at websmstest
Connecting Twilio with Bluemix
  1. Fire-up a Node.js Webstarter application from the Bluemix dashboard. In my case I have named the application websmstest. Once this is up and running
fig1
2) Click Add a Service and under 'Web and Application' and choose Twilio.
3) Enter a name for the Twilio service. You will also need the Account SID and Authorization token
  1. For this go to http://www.twilio.com and sign up
5) Once you have registered, go to your Twilio Dashboard for the Account SID and Auth Token. If the Auth token is encrypted, you can click the 'lock' symbol to display the Auth token in plain text.
  1. Enter the Account SID and Auth Token in the Twilio service in Bluemix in the right hand panel shown in the picture below
fig2
  1. To get started click the link websmstest code from Devops.
  2. Next click the 'Edit Code' button at the top
  3. Then click 'Fork' and provide a suitable name for your project
fig6
  1. Check the option for a) Deploy to Bluemix. Uncheck the other options a) Make it private b) Add features for Scrum development
  2. On the left hand side navigate to the file you need to edit and make the changes with the Devops GUI editor. You will need to make the following changes
Setup the application
12) You will need to modify the following files
  1. manifest.yml
  2. app.js
13) In the manifest.yml make sure you enter the name of your application and the host
applications:
- host: websmstest
  disk: 1024M
  name: websmstest
  command: node app.js
  path: .
  domain: mybluemix.net
  mem: 128M
  instances: 1
14) Lastly make changes to your app.js.
var app = require('gopher'),
    twilio = require('twilio');

 
var config = JSON.parse(process.env.VCAP_SERVICES);
 
var twilioSid, twilioToken;
config['user-provided'].forEach(function(service) {
    if (service.name == 'Twilio') {
        twilioSid = service.credentials.accountSID;
        twilioToken = service.credentials.authToken;
    }
});
 

// URL 
app.get('/', function(request, response) {
    var client = new twilio.RestClient(twilioSid, twilioToken);
 
    /* To make a voice call to your mobile phone uncomment the next 2 lines */
   //client.calls.create({
   //url: "http://twimlets.com/message?Message%5B0%5D=Hello",
   
    
     //  to: Enter your mobile phone  for e.g.98765 43210
     // from: Enter the number Twilio alloted to your account
     // body: The message you would like to send
     client.sendMessage({
       to: '+919876543210',
         from: '+16305476427',
         body:'Twilio notification through Bluemix!'
        }, function(err, message) {
        response.send('Message sent! ID:'+message.sid);
    });
});
  1. Enter your mobile number in the 'to:' line.
  2. Enter the number provided to you in your Twilio account see below
fig3
  1. In the app.js code above in step 14) use the green highlighted line to send a SMS to your mobile phone
  2. If you uncomment the blue highlighted lines a voice call will be made to your mobile
  3. Finally 'Deploy' the application on to Bluemix (more details on Deploying to Bluemix) can be found at Getting started with IBM Bluemix and IBM Devops services using Node.js
Test the application
19) Now click on your application to open the details and then click the link adjacent to the Routes.
fig8
20) You should see that an SMS has been sent as shown
fig4
21) Your mobile should now display the message that was sent as shown below
Screenshot_2014-06-22-13-41-44
22) Uncomment the lines which deal with making voice call and you should receive a voice announcement (see below) (Remember to comment the green highlighted line client.sendMessage!)
1
23) Check the analytics in your Twilio dashboard
fig5
Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions
[polldaddy rating="7295683"]
Find me on Google+

Wednesday, September 3, 2014

Rock N' Roll with Bluemix, Cloudant and NodeExpress

In this post I create a  cloud application that is based on Bluemix, Cloudant DB and NodeExpress.  NodeExpress is used to perform DB operations on  CloudantDB
The code can be forked from Devops from bluemix-cloudant-exp. You can also clone the code from Github from bluemix-cloudant-exp
The following NodeExpress routes are created for performing the basic database operations
  1. a) Displaying the list of books
  2. b) Adding a book
  3. c) Updating a book and
  4. d) Deleting a book
1
Push the app to Bluemix
a) Push the app to Bluemix using
cf push bluemix-cloudant -p . -m 512M
b) In the Bluemix dashboard add the Cloudant service.
c) Double click the CloudantNoSQLDB
9
and then click the 'Launch' button. This will bring the WebSQL based version of Cloudant DB
10
c) Next click the link bluemix-cloudant.mybluemix.net
11
This will start the Webserver and also populate the database.
e) This can be seen in the Cloudant Dashboard for the 'test' database which has 3 records shown below
12
The setup for these routes in the NodeExpress are as follows
app.get('/', routes.index);
app.get('/booklist', booklist.list);
app.get('/newbook', newbook.list);
app.post('/addbook',addbook.list);
app.get('/changebook', changebook.list);
app.post('/updatebook', updatebook.list);
app.get('/rembook', rembook.list);
app.post('/deletebook',deletebook.list);
Setting up the environment for Cloudant's PouchDB
The first thing is to setup the environment for Cloudant's Pouch DB by parsing the process.env environment variables as shown below
//Parse the process.env for the port and host that we've been assigned
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);
Displaying the list of books
Cloudant responds to DB queries as JSON messages. Hence to display the list of books the fields of each document is stored as an array and then displayed using the Jade table in booklist.jade  This is shown below
  1. a) booklist.js
var docs = db.allDocs(function(err, response) {
val = response.total_rows;
var details = "";
j=0;
var booklist = new Array(val);
for(i=0; i < val; i++) {
db.get(response.rows[i].id, function (err,doc){
j++;
booklist[j] = new Array(3);
booklist[j][0] = doc._id;
booklist[j][1] = doc.Title;
booklist[j][2] = doc.author;
details= details + JSON.stringify(doc.Title) + "  " +  JSON.stringify(doc.author) + "\n";
// Kludge because of Node.js asynchronous handling. To be fixed - T V Ganesh
if(j == val) {
res.render('booklist', {
"booklist" : booklist
});
}
}); // End db.get
} //End for
}); // End db.allDocs
  1. b) booklist.jade
The jade template simply displays the each booklist as a row in a table
block content
h1= "Display the list of books"
p
strong DocId  Title   Author
table
each book, i in booklist
tr
td #{book}
p
p
a(href='/') Home
2
Adding a book 
To add a book the book details are obtained using the newbook.jade which display a form
block content
h1= "Add a book"
form#formAddBook(name="addbook",method="post",action="/addbook")
input#inputBookTitle(type="text", placeholder="Title", name="title")
input#inputBookAuthor(type="text", placeholder="Author", name="author")
button#btnSubmit(type="submit") submit
a(href='/') Home
With the values obtained from the form above a document is inserted into the books database as follows
// Get our form values. These rely on the "name" attributes
var Title = req.body.title;
var Author = req.body.author;
db.put({
author: Author,
Title : Title,
}, Title, function (err, response) {
console.log(err || response);
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
else {
// Redirect to booklist - Display booklist
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
});
Note: When inserting a document into the books database the docid for the document is set to be the same as the book Title itself
7
4
Updating a book
To update a document we need to input the document id. Also the document to be updated should use the "_rev" field which is obtained when we get the document. The values to be input are taken with the changeuser form
block content
h1= "Update a book"
form#formUpdateBook(name="addbook",method="post",action="/updatebook")
input#inputDocId(type="text", placeholder="DocId", name="docid")
input#inputBookTitle(type="text", placeholder="Title", name="title")
input#inputBookAuthor(type="text", placeholder="Author", name="author")
button#btnSubmit(type="submit") submit
a(href='/') Home
The values obtained are used to populate the document as follows
db.get(DocId, function(err, response) {
db.put({
_id: DocId,
_rev: response._rev,
author: Author,
Title : Title,
}, function(err, response) {
if (err) {
// If it failed, return error
res.send("There was a problem updating the information to the database.");
}
else {
// If it worked, redirect to display books
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
});
});
6
5
Deleting a document
To delete a document we need the document id which is taken with the rembook.jade form
block content
h1= "Delete a book"
form#formDeleteBook(name="addbook",method="post",action="/deletebook")
input#DocId(type="text", placeholder="DocId", name="docid")
button#btnSubmit(type="submit") submit
a(href='/') Home
//Deleting document book1
db.get(DocId, function(err, doc) {
db.remove(doc, function(err, response) {
if (err) {
// If it failed, return error
res.send("There was a problem removing the information to the database.");
}
else {
// Redirect to booklist
res.location("booklist");
// And forward to success page
res.redirect("booklist");
}
console.log(err || response);
});
});
In the diagram below docid 'book3' is deleted
13
8
Important tips
  1. If you run into issues while create a Jade template then do the following
npm install jade --g
You can check your jade template for correctness using
jade
If the response is 'rendered .html' then the template is fine.
  1. If there are problems with deploying the application or if the application crashes you check the cf logs as follows for the issue
cf logs --recent
As mentioned the  code can be forked from Devops from bluemix-cloudant-exp. You can also clone the code from Github from bluemix-cloudant-exp
Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions

Monday, September 1, 2014

A Cloud medley with IBM Bluemix, Cloudant DB and Node.js

Here is an interesting Cloud medley based on IBM's Bluemix PaaS platform, Cloudant DB and Node.js. This application  creates a Webserver using Node.js and uses REST APIs to perform CRUD operations on a Cloudant DB. Cloudant DB is a NoSQL Database as a service (DBaaS) that can handle a wide variety of data types like JSON, full text and geo-spatial data. The documents  are stored, indexed and distributed across a elastic datastore spanning racks, datacenters and perform replication of data across datacenters.Cloudant  allows one to work with self-describing JSON documents through  RESTful APIs making every document in the Cloudant database accessible as JSON via a URL.
This application on Bluemix uses REST APIs to perform the operations of inserting, updating, deleting and listing documents on the Cloudant DB.  The code can be forked from Devops at bluemix-cloudant. The code can also be clone from GitHub at bluemix-cloudant.
1) Once the code is forked the application can be deployed on to Bluemix using
cf login -a https://api.ng.bluemix.net
cf push bm-cloudant -p . -m 512M
2) After this is successful go to the Bluemix dashboard and add the Cloudant DB service.  The CRUD operations can be performed by invoking REST API calls using an appropriate REST client like SureUtils ot Postman in the browser of your choice.
Here are the details of the Bluemix-Cloudant application
3) Once the Cloudant DB service has been added to the Web started Node.js application we need to parse the process.env variable to obtain the URL of the Cloudant DB and the port and host to be used for the Web server.
The Node.js Webserver is started based on the port and host values obtained from process.env
require('http').createServer(function(req, res) {
//Set up the DB connection
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse for  the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
....
}
....
// Perform CRUD operations through REST APIs
// Insert document
if(req.method == 'POST') {
insert_records(req,res);
}
// List documents
else if(req.method == 'GET') {
list_records(req,res);
}
// Update a document
else if(req.method == 'PUT') {
update_records(req,res);
}
// Delete a document
else if(req.method == 'DELETE') {
delete_record(req,res);
}
}).listen(port, host);
2) Access to the Cloudant DB Access to Cloudant DB is obtained as follows
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);
Access to the Cloudant DB is through the cloudant.url shown above
3)  Once the access to the DB is setup we can perform CRUD operations. There are many options for the backend DB. In this application I have PouchDB.
4) Inserting a document: To insert documents into the Cloudant DB based on Pouch DB we need to do the following
var insert_records = function(req, res) {
//Parse the process.env for the port and host that we've been assigned
if (process.env.VCAP_SERVICES) {
// Running on Bluemix. Parse the port and host that we've been assigned.
var env = JSON.parse(process.env.VCAP_SERVICES);
var host = process.env.VCAP_APP_HOST;
var port = process.env.VCAP_APP_PORT;
console.log('VCAP_SERVICES: %s', process.env.VCAP_SERVICES);
// Also parse Cloudant settings.
var cloudant = env['cloudantNoSQLDB'][0]['credentials'];
}
var db = new pouchdb('books'),
remote =cloudant.url + '/books';
opts = {
continuous: true
};
// Replicate the DB to remote
console.log(remote);
db.replicate.to(remote, opts);
db.replicate.from(remote, opts);
// Put 3 documents into the DB
db.put({
author: 'John Grisham',
Title : 'The Firm'
}, 'book1', function (err, response) {
console.log(err || response);
});
...
...
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write("3 documents is inserted");
res.end();
}; // End insert_records
The nice part about Cloudant DB is that you can access your database through the URL. The steps are shown below. Once your application is running. Click on your application. You should see the screen as below.
1
Click on Cloudant as shown by the arrow.
Next click on the "Launch' icon
2
This should bring up the Cloudant dashboard. The database will be empty.
3
If you use a REST API Client to send a POST API call then the Application will insert 3 documents.
4
The documents inserted can be seen by sending the GET REST API call.
5
The nice part of Cloudant DB is that you can use the URL to see your database. If you refresh your screen you should see the "books" database added. Clicking this database you should see the 3 documents that have been added
6
If you click "Edit doc" you should see the details of the document
7
5) Updating a document
The process to update a document in the database is shown below
// Update book3
db.get('book3', function(err, response) {
console.log(response);
return db.put({
_id: 'book3',
_rev: response._rev,
author: response.author,
Title : 'The da Vinci Code',
});
}, function(err, response) {
if (err) {
console.log("error " + err);
else {
console.log("Success " + response);
}
});
This is performed with a PUT REST API call
8
The updated list is shown below
9
This can be further verified in the Cloudant DB dashboard for book3.
10
6) Deleting a document
The code to delete a document in PouchDB is shown below
//Deleting document book1
db.get('book1', function(err, doc) {
db.remove(doc, function(err, response) {
console.log(err || response);
});
});
The REST calls to delete a document and the result  are shown below
11
12
Checking the Cloudant dashboard we see that only book2 & book3 are present and book1 has been deleted
13
7) Displaying documents in the database
The code for displaying the list of documents is shown below
var docs = db.allDocs(function(err, response) {
val = response.total_rows;
var details = "";
j=0;
for(i=0; i < val; i++) {
db.get(response.rows[i].id, function (err,doc){
j++;
details= details + JSON.stringify(doc.Title) + " by  " +  JSON.stringify(doc.author) + "\n";
// Kludge because of Node.js asynchronous handling. To be fixed - T V Ganesh
if(j == val) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write(details);
res.end();
console.log(details);
}
}); // End db.get
} //End for
}); // End db.allDocs
If you happened to notice, I had to use a kludge to work around Node.js' idiosyncracy of handling asynchronous calls. I was fooled by the remarkable similarity of Node.js & hence  javascript to C language that I thought functions within functions would work sequentially. However I had undergo much grief  trying to get Node.js to work sequentially. I wanted to avoid the 'async' module but was unsuccessful with trying to code callbacks. So the kludge! I will work this out eventually but this workaround will have to do for now!
As always you can use the "Files and Logs" in the Bluemix dashboard to get any output that are written to stdout.
Note: As always I can't tell how useful the command
'cf  logs -- recent is for debugging.
Hope you enjoyed this Cloud Medley of Bluemix, Cloudant and Node.js!
Disclaimer: This article represents the author’s viewpoint only and doesn’t necessarily represent IBM’s positions, strategies or opinions
[polldaddy rating="7295683"]
Find me on Google+