Build a mobile phone book for your Salesforce contacts

27 June 2014
PDF (362 KB)
Share:
Photo of Joseph McCarthy

Joseph McCarthy

Java Developer, Dun & Bradstreet

Joseph McCarthy

Keeping track of frequently changing customer and supplier contacts can be time-consuming for a business. An online CRM tool like Salesforce.com alleviates some of the work. I came up with a convenient way to access my Salesforce client-account data without needing to log into Salesforce: an authenticated Node.js application that queries the Salesforce API to get a list of my clients and their details. I built a cloud-based web version with IBM® Bluemix™. Then I migrated the web app quickly to a mobile version that I use as a personal phone book.

What you'll need to build a similar app

 
  • Basic familiarity with Node.js and Express
  • A Bluemix account and a DevOps Services (formerly JazzHub) account
  • AngularJS, an open source JavaScript framework for creating single-page applications (SPAs)
  • Ionic, an open source front-end framework for developing hybrid mobile apps in HTML5
  • The development tools for your mobile platform

Step 1. Create an authenticated Salesforce application

 
  1. If you don't have a Salesforce developer account, create one and log in.
  2. Click Setup, then expand the Create menu under the Build heading. Click Apps to see the list of applications associated with your account.
Screenshot of create application menu in Salesforce.com dashboard
  1. In the Connected Apps panel, click New. In the screen that opens, under Basic Information, enter values (with no spaces) for Connected App Name, API Name, and Contact Email. In the API (Enable OAuth Settings) section, select Enable OAuth Settings. The application won't use callbacks, but you still need a value for Callback URL. Under Available OAuth Scopes, select Access and manage your data (api) and shuttle it to Selected OAuth Scopes. Click Save to create the application.
Screenshot of settings for Salesforce.com connected application
  1. Make a note of the values for Consumer Key and Consumer Secret on the screen that opens, and keep them secure.
Screenshot of application settings for Salesforce.com connected application
  1. Only a valid Salesforce username and password can access the application in its current state. To bypass this requirement, you'll include an authorisation token — a string that combines your account password and your security token — in every request. For example, if your password is myPassword and your security token is mySecurityToken, the authorisation token is myPasswordmySecurityToken.

    To get your security token, open My Settings from your Salesforce home screen. Expand the Personal section and select Reset My Security Token. Click the Reset Security Token button to send your security token to the email address associated with your account.

Image shows personal menu in Salesforce dashboard

Now that the application is registered, you no longer need to access the Salesforce website.

WATCH:Getting started with Node.js (video demo)

READ:OAuth 2.0 authentication

Step 2. Fork the existing project on DevOps Services

 

Click the Get the code button above. On the DevOps Services project page, click Edit Code, and on the page that opens, click Fork. Give the forked project a name, leave the make it private check box empty if you prefer, and click Save.

Step 3. Modify the code

 

I'll take you through each file in the existing project so you understand how the application is structured and see what code changes to make in your own project.

package.json

This JSON document contains information about the application:

{
  "name": "salesForceMobilePhonebook",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "*"
  }
}

package.json must contain, at minimum, the following attributes:

  • name of the application, which can be any string
  • version of this release
  • private to indicate whether npm will publish the application

The package.json file also includes:

  • scripts— A JSON child document containing scripts to be called at various points in the application's lifecycle. I specify that the application is to be started with the node app.js command.
  • dependencies— A JSON child document containing the application's module dependencies and versions. I specify the most recent version (indicated by the *) of the Express module.

manifest.yml

The manifest file contains information on how the application is to be deployed on Bluemix.

applications:
- name: SalesForceMobilePhonebook
  framework: node
  memory: 128M
  instances: 1
  host: salesforcemobilephonebook
  domain: ng.bluemix.net
  path: .     
  command: node app.js

The first line of an application definition in a manifest is applications:, left-aligned. Note that each definition begins with a hyphen and a space, and that string literals do not need to be enclosed in inverted commas. Within the definition are the attributes used to deploy the application:

  • name— The application name
  • memory— The memory, in megabytes, to be allocated to the application.
  • instances— The number of instances of the application to start.
  • host— The domain name that the application will be deployed to on Bluemix.
  • domain— The parent domain name for the application. All Bluemix runtimes will use mybluemix.net.
  • path— The path in your project to the file to launch the application, here app.js. If the file is in the root directory, use a single dot.
  • command— The command to launch the application.

app.js

The app.js file contains the main code for the server application.

Check Saleforce.com to see the supported versions of the Salesforce API. The page's final entry is the latest release.

In app.js, all the application variables are created first. The apiVersion variable specifies the version of the salesforce.com API to be called.

var apiVersion = '/services/data/v29.0/';

Next are the environment-variable definitions.

var consumerKey = process.env.salesForceConsumerKey;
var consumerSecret = process.env.salesForceConsumerSecret;
var securityToken = process.env.salesForceSecurityToken;

These three variables point to environment variables you must create in your application's runtime on Bluemix after the app is deployed for the first time (see Step 4).

The access_token and instance_url variables contain the authentication token and URL of the instance to send all requests to after authentication.

var access_token = '';
var instance_url = '';

The Express application uses the following configuration code to accept requests from external applications (namely, the HTML5 application you'll develop in this article's last step).

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
	next();
});

By default, Express uses the definition in the routes directory as a response to a request to the root domain — / — so the following code reconfigures it to send the index.html file (which I'll get to in a moment) from the public directory instead:

app.get('/', function(req, res) {
	res.sendfile('./public/index.html');
});

Two endpoints are declared in two app.get() blocks. Both are set up in a similar manner. A JSON document contains the configuration for a HTTP request:

  • host— Determined by the instance_url returned during authentication with salesforce.com
  • path— The path determines which endpoint the request goes to:
    • The accounts endpoint sends a query to the Salesforce API using SOQL, an SQL-like query language used to query the Salesforce.com datastore. The query is stored in a JSON document and serialized using the querystring.stringify method.
    • The account endpoint requests the account details from the /sobjects/Account/ endpoint using an account ID.
  • method— The method used to send the request. Requests to both endpoints for your application will use GET. You can consider rewriting the endpoints to accept POST requests.
  • headers— The authentication token is included in the Authorization attribute.

The request is created using the https.request method. As each chunk of data is returned, it is stored in a buffer. When the transfer is complete, the data is parsed into JSON and sent back as a response.

When the server is created, the application authenticates with the Salesforce.com API. First, an HTTPS request is sent to the OAuth service with these parameters and values:

  • grant_type"password"
  • client_id— The consumer key from your application dashboard
  • client_secret— The consumer secret from your application dashboard
  • username— Your Salesforce login
  • password— Authorization token (combination of your Salesforce password and security token)

These attributes are stored in JSON document and serialized using querystring.stringify. The options variable contains the attributes for the request.

When the call completes, the server responds with a UTF-8 encoded JSON document containing five parameters. Only two are needed: access_token (the token to be included with all further requests to the API) and instance_url (the host to send all API requests to). The returned data is parsed using JavaScript's built-in JSON parser. The two local variables access_token and instance_url store the values.

public/index.html

This is the page users see when they open the deployed application. The file imports two minified Angular libraries and the salesForceProxy module definition. The route definition from the module is used to determine what's displayed in the <div> tag.

public/templates/accounts.html

This file iterates through the list of accounts in the JSON object returned from the accounts endpoint by using the Angular ng-repeat directive. And it uses the Angular ng-href directive to display each one in an HTML anchor tag in the div with the ng-href directive in index.html.

public/templates/account.html

This file displays the details of a single account in the div with the ng-href directive in index.html.

public/js/salesForceAPIProxy.js

This file contains the definition of the salesForceProxy Angular module.

All Angular module definitions take two parameters: a string containing the name of the module and an array containing the names of any dependencies — in this case, the ngRoute directive to use routing.

Next are two controller definitions, one to call each endpoint. Both work on similar principles: A variable is created in the $scope object to hold the response to a call to the endpoint. The $http service is invoked to call the endpoint, and the result is stored in the variable. The AccountsCtrl controller uses the $routeParams service to retrieve the account ID from the call made when you click a link created in the ng-repeat loop on the accounts.html page.

Two routes decide which template to display on the index.html page. Each route definition handles a different URL — either the default / or the /:id that's called when you click a link on the default page.

Step 4. Deploy the app to Bluemix, set runtime environment variables, and re-deploy

 
  1. Deploy the code to Bluemix using the Deploy button in your DevOps Services project.
  2. Log into your Bluemix account from your browser.
  3. In the settings for the deployed app, click Runtime. Under Environment variables, select User Defined and create the consumerKey, consumerSecret, securityToken, salesForceUsername, and salesForcePassword variables, using the values from Step 1. Do not include the process.env. string in the variables. Screenshot of Setting user-defined runtime environment variables in Bluemix
  4. Click Save and restart your application from the Bluemix dashboard.

When the app launches, you should be able to view the list of accounts at the root URL. Click any one to view the account details.

Step 5. Using Ionic, migrate the application to mobile

 

These instructions are the same for all mobile platforms. If you don't use Android, substitute the relevant platform name.

Now you can implement the AngularJS application as a mobile app that you develop locally.

  1. If you don't have Node.js installed on your system, click Install on the Node.js home page to download the installer for your OS, and install it.
  2. Install Ionic in your development environment with the npm install -g ionic command. Then run ionic start nodeJSProxyIonic, which creates a seed project in a directory called nodeJSProxyIonic, where you'll build the mobile app.
  3. You'll rebuild the nodeJSProxyIonic/www/index.html file using the index.html file from the DevOps Services project as a guide. Start by adding the viewport metatag to the file in the seed project.
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no"/>
  4. Ionic comes packaged with a customised version of AngularJS, as well as its own libraries and CSS files. Replace the imports of Angular libraries in the header with:
    <link rel="stylesheet" href="lib/css/ionic.css"/>
                      <script src="lib/js/ionic.js"></script>
                      <script src="lib/js/angular/angular.js"></script>
                      <script src="lib/js/angular/angular-animate.js"></script>
                      <script src="lib/js/angular/angular-sanitize.js"></script>
                      <script src="lib/js/angular-ui/angular-ui-router.js"></script>
                      <script src="lib/js/ionic-angular.js"></script>
                      <script src="lib/js/angular/angular-route.js"></script>
                      <script src="lib/js/angular/angular-touch.js"></script>
                      <script type="text/javascript" src="cordova.js"></script>

    The final entry — cordova.js — is added dynamically to the platform by Cordova when the project is built.
  5. Copy salesForceProxy.js into the js directory and update the link in the index.html header to point to it. In salesForcyProxy.js, add the ionic directive to the array in the declaration of the salesForceProxy module. The mobile application must send the requests to the host name of the application running on Bluemix: http://yourappname.mybluemix.net, so update both controllers to send their requests to the Bluemix host.
  6. Create account.html and accounts.html files in the templates directory and copy into them the code from the same-named files in your DevOps Services workspace.
  7. To enable the user to call phone numbers from the account details screen, edit the account.html file in the templates directory to change the Phone entry to:
    <div>
       <a ng-href="tel:{{account.Phone}}">{{account.Phone}}</a>
    </div>
  8. For Android development, the Android SDK sdk/platform-tools and sdk/tools/ directories must be on your path for the build to succeed.

    Build the project: Run cordova platform add android in a command window from the nodeJSProxyIonic directory to add the Android platform to the project. When that command completes, run cordova build android.
  9. At the time of writing, a known issue with Cordova causes two alert boxes appear when you open an application. You can safely ignore them by clicking Cancel.

    When the build completes, run cordova serve android to run the finished application in the built-in server. Open http://localhost:8000/ and select Android from the list to see the list of accounts. Select any one to view its details.
  10. Enable USB debugging on your Android device in the Developer Options screen, then connect it to your PC with a USB cable. Run cordova run android to deploy the app to the device. After a few minutes, the application will launch on your device.

Migration to mobile complete. You can now use your mobile device to call your clients who are registered on Salesforce.com.

Conclusion

 

I've demonstrated how to register an authenticated application with Salesforce.com, use it to provide REST endpoints on a Node.js server, consume the endpoints from an AngularJS desktop application, and easily migrate the app to a mobile device.

For further development, you can look into using the nav-view tag instead to render the text, and using animation to switch between the screens on your mobile device. AngularJS recently introduced the states directive to replace the existing routing directive. The states directive is subject to change but stable enough to replace the basic routing implemented in the article. The authentication token issued by Salesforce.com has a limited lifespan. You can work around this issue by manually restarting the application, or you can investigate how to handle responses from the API indicating that the token has expired.


BLUEMIX SERVICE USED IN THIS TUTORIAL:The SDK for Node.js runtime helps you develop, deploy, and scale server-side JavaScript apps with ease.

Add a comment

Note: HTML elements are not supported within comments.


1000 characters left

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Cloud computing, Mobile development
ArticleID=964890
ArticleTitle=Build a mobile phone book for your Salesforce contacts
publish-date=06272014