Integrating Force.com and Heroku Applications

Last Updated: 18 November 2013

force.com ruby salesforce

Table of Contents

This tutorial demonstrates how to create a web application on Heroku that lets users authorize using the Force.com platform’s OAuth, and then perform API calls to Force.com. It can serve as the basis of a more complex integration scenario.

The tutorial uses the Ruby language, but the main concepts, configuration and architecture can be just as easily applied to any other language supported by Heroku.

Sample code for the demo application is available on GitHub. Edits and enhancements are welcome. Just fork the repository, make your changes and send us a pull request.

Prerequisites

A web application integration scenario

There are two components that typically lie at the core of an integration between applications running on Force.com and Heroku: authentication and API.

Authentication

Salesforce, and in particular the Force.com REST API, supports OAuth 2.0, and if you’re building an integration where a Force.com user can log in, it makes sense to delegate authentication to Force.com.

Every programming language has libraries that support OAuth 2.0 - this article uses OmniAuth.

API

Programmatic access to Force.com applications and data can be made using the Force.com REST API. The API has a clean, REST interface, which you can interact with directly using HTTP calls. This article uses an API client library, the Force gem, which makes invoking each of the major API endpoints a matter of calling a simple Ruby method.

The sample application

The sample app demonstrates the main components of authorization and making API calls, and the rest of this tutorial will highlight various parts of the app. The app is written in Ruby, and uses the Sinatra web framework.

To get started, clone the application:

$ git clone https://github.com/jonmountjoy/heroku-force-workbook-demo
$ cd heroku-force-workbook-demo

The application is reasonably generic, and will work with any Force.com org. However it does require some configuration via config vars. In particular, Force.com has to be configured to permit users to use its OAuth.

Create a Connected App in Salesforce

Configure your Force.com development environment to allow OAuth. You do this by creating a “Connected App”.

  1. Log in to your Salesforce Developer Edition environment at: https://login.salesforce.com
  2. Click on Setup in the upper right-hand menu.
  3. Under “Build” click Create -> Apps.
  4. Scroll to the bottom and click “New” under “Connected Apps.”

Enter the following details for the remote application:

  1. For Connected App Name, enter a name for your Connected App.
  2. The API Name will be filled in automatically. Accept this value.
  3. Enter an email address for Contact Email.
  4. Select “Enable OAuth Settings” under the API dropdown.
  5. For “Callback URL” provide the callback URL of your local app, http://localhost:5000/auth/salesforce/callback.
  6. Give the app “Full access” scope. In production scenarios you may want to limit this scope.

After saving, you’ll see that Force.com provides you two values: a consumer key and a consumer secret. Save these in a new text file called .env in the root directory of the application:

SALESFORCE_KEY=<insert key here>
SALESFORCE_SECRET=<insert secret here>
SECRET=some_random_text_string

The final config var, SECRET, is used by the Ruby application to encrypt session values.

The authorization implementation

At this point you have a working application. Before running it, look at the major components found in myapp.rb:

The following lines ensure we have access to OmniAuth for handling the OAuth work:

require "omniauth"
require "omniauth-salesforce"

The application makes use of sessions, which the configure section enables:

configure do
  enable :logging
  enable :sessions
  set :show_exceptions, false
  set :session_secret, ENV['SECRET']
end

Configuration of the OmniAuth library simply uses the values of the config vars you have already set:

use OmniAuth::Builder do
  provider :salesforce, ENV['SALESFORCE_KEY'], ENV['SALESFORCE_SECRET']
end

The web route of most significance is the callback, which will be invoked at the end of a successful OAuth authentication dance. This method ensures that some data is logged, and that the OAuth token is stored in the session. The data returned by Salesforce at the end of an authentication also includes an instance_url, which should be used for any REST API interactions. This is also stored in the session:

get '/auth/salesforce/callback' do
  logger.info "#{env["omniauth.auth"]["extra"]["display_name"]} just authenticated"
  credentials = env["omniauth.auth"]["credentials"]
  session['token'] = credentials["token"]
  session['refresh_token'] = credentials["refresh_token"]
  session['instance_url'] = credentials["instance_url"]
  redirect '/'
end

The API integration

After the callback is invoked, the session has the instance_url and OAuth tokens needed to make Force.com REST API calls.

The implementation is simple. First, create an API client using these data:

helpers do
  def client
    @client ||= Force.new instance_url:  session['instance_url'],
                          oauth_token:   session['token'],
                          refresh_token: session['refresh_token'],
                          client_id:     ENV['SALESFORCE_KEY'],
                          client_secret: ENV['SALESFORCE_SECRET']
  end
end

Now just use the client to invoke the API. The following code makes a query, listing all the Accounts in the org that the authenticated user has access to:

get '/' do
  logger.info "Visited home page"
  @accounts= client.query("select Id, Name from Account")
  erb :index
end

A template iterates through the result set, listing the fields:

<table>
<tr><th>Account</th><th>ID</th></tr>
<% @accounts.each do |account| %>
  <tr>
     <td><%= account.Name %></td>
     <td><%= account.Id %></td>
  </tr>
<% end %>
</table>

Running the application locally

You have configured your Salesforce org to permit OAuth, and set up your local environment by creating the .env file. Now prepare the app for local execution by downloading the dependencies:

$ bundle install
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Installing daemons (1.1.9)
Using eventmachine (1.0.3)

Start it:

$ foreman start
12:12:31 web.1  | started with pid 27482
12:12:32 web.1  | == Sinatra/1.4.3 has taken the stage on 5000 for development with backup from Thin

Begin the authorization process by visiting http://localhost:5000/authenticate.

This will kick off the OAuth authentication flow, and redirect you to Salesforce:

login

After authenticating, you’ll be asked to authorize your web application. When creating the Connected App you set the OAuth scope to “Full”. As a result, Force.com is now asking you to grant the Heroku app full access to data on your Force.com org - thereby allowing you to later use the API and much more.

authorize

After authorizing, Salesforce will redirect you back to your local application - the callback URL that you specified in the Connected App - which will then make the API calls and display the accounts.

accounts

Done!

Running the application on Heroku

Little needs to change in order to deploy and run the application on Heroku. The only inconvenience arises because the OAuth Connected App configuration species a callback URL - so you will have to create another Connected App configuration in your Salesforce org that references the callback URL of your application on Heroku, instead of localhost.

First, create the Heroku application:

$ heroku create
Creating still-cliffs-2432 in organization heroku... done, region is us
http://still-cliffs-2432.herokuapp.com/ | git@heroku.com:still-cliffs-2432.git

This also creates a domain, in this case still-cliffs-2432.herokuapp.com. Note the domain name in your instance - you’ll need it later when specifying the callback URL.

Now deploy the app:

$ git push heroku master
Counting objects: 1202, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (391/391), done.
Writing objects: 100% (1078/1078), 374.90 KiB | 412.00 KiB/s, done.
Total 1078 (delta 761), reused 990 (delta 684)

-----> Ruby/Rails app detected
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using Bundler version 1.3.2 Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 1.19 KiB | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)

-----> Ruby/Rack app detected
-----> Using Ruby version: ruby-2.0.0
-----> Installing dependencies using Bundler version 1.3.2
       Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin --deployment
       Using daemons (1.1.9)
       Using eventmachine (1.0.3)
…
-----> Discovering process types
       Procfile declares types     -> web
       Default types for Ruby/Rack -> console, rake

-----> Compiled slug size: 26.9MB
-----> Launching... done, v6
       http://still-cliffs-2432.herokuapp.com deployed to Heroku

Log in to your Force.com org and create another Connected Application by repeating the instructions in Create a Connected App in Salesforce, except for the callback URL you will need to use a URL based on your application’s name. For example, if your application is still-cliffs-2432, then your URL will be https://still-cliffs-2432.herokuapp.com/auth/salesforce/callback. Note you must use https here.

If you’ve forgotten your application’s name, type in heroku info.

Take the new key and secret that the Connected App generates, and configure your Heroku application to use them via config vars:

$ heroku config:set SECRET="some_random_string"
$ heroku config:set SALESFORCE_KEY=xxxxxx SALESFORCE_SECRET=yyyyy

That’s it.

Now navigate to the /authenticate route of your deployed application. For example: https://still-cliffs-2432.herokuapp.com/authenticate

Your application, now running on Heroku, will behave just as it did locally - letting you log in, authorize, and make the API calls.

Summary

This tutorial demonstrates how to create a Heroku web application that makes Force.com REST API calls after authorizing users with Force.com OAuth.