/databasedotcom

Ruby client for the Database.com and Chatter APIs

Primary LanguageRubyMIT LicenseMIT

databasedotcom

databasedotcom is a gem to enable ruby applications to access the SalesForce REST API. If you use bundler, simply list it in your Gemfile, like so:

gem 'databasedotcom'

If you don’t use bundler, install it by hand:

gem install databasedotcom

Documentation

Reference documentation is available at rubydoc.info

Source

Source is available at github

Contributions

To contribute, fork this repo, make changes in your fork, then send a pull request. No pull requests without accompanying tests will be accepted. To run tests in your fork, just do

bundle install
rake

Usage

Initialization

When you create a Databasedotcom::Client object, you need to configure it with a client id and client secret that corresponds to one of the Remote Access Applications configured within your Salesforce instance. The Salesforce UI refers to the client id as “Consumer Key”, and to the client secret as “Consumer Secret”.

You can configure your Client object with a client id and client secret in one of several different ways:

Configuration from the environment

If configuration information is present in the environment, the new Client will take configuration information from there.

export DATABASEDOTCOM_CLIENT_ID=foo
export DATABASEDOTCOM_CLIENT_SECRET=bar

Then

client = Databasedotcom::Client.new
client.client_id      #=> foo
client.client_secret  #=> bar

Configuration from a YAML file

If you pass the name of a YAML file when you create a Client, the new Client will read the YAML file and take the client id and client secret values from there.

# databasedotcom.yml
#
---
client_secret: bro
client_id: baz

Then

client = Databasedotcom::Client.new("databasedotcom.yml")
client.client_id      #=> bro
client.client_secret  #=> baz

Configuration from a Hash

If you pass a hash when you create a Client, the new Client will take configuration information from that Hash.

client = Databasedotcom::Client.new :client_id => "sponge", :client_secret => "bob"
client.client_id      #=> sponge
client.client_secret  #=> bob

Configuration precedence

Configuration information present in the environment always takes precedence over that passed in via a YAML file or a Hash.

export DATABASEDOTCOM_CLIENT_ID=foo
export DATABASEDOTCOM_CLIENT_SECRET=bar

Then

client = Databasedotcom::Client.new :client_id => "sponge", :client_secret => "bob"
client.client_id      #=> foo
client.client_secret  #=> bar

Usage in an application deployed on Heroku

You can use the heroku config:add command to set environment variables:

heroku config:add DATABASEDOTCOM_CLIENT_ID=foo
heroku config:add DATABASEDOTCOM_CLIENT_SECRET=bar

Then, when you create your client like:

client = Databasedotcom::Client.new

it will use the configuration information that you set with heroku config:add.

Connect to a SalesForce sandbox account

Specify the :host option when creating your Client, e.g,

Databasedotcom::Client.new :host => "test.salesforce.com", ...

Authentication

The first thing you need to do with the new Client is to authenticate with Salesforce. You can do this in one of several ways:

Authentication via an externally-acquired OAuth access token

If you have acquired an OAuth access token for your Salesforce instance through some external means, you can use it. Note that you have to pass both the token and your Salesforce instance URL to the authenticate method:

client.authenticate :token => "my-oauth-token", :instance_url => "http://na1.salesforce.com"  #=> "my-oauth-token"

Authentication via Omniauth

If you are using the gem within the context of a web application, and your web app is using Omniauth to do OAuth with Salesforce, you can authentication the Client direction via the Hash that Omniauth passes to your OAuth callback method, like so:

client.authenticate request.env['omniauth.auth']  #=> "the-oauth-token"

Authentication via username and password

You can authenticate your Client directly with Salesforce with a valid username and password for a user in your Salesforce instance. Note that, if access to your Salesforce instance requires a security token, the value that you pass for :password must be the password for the user concatenated with her security token.

client.authenticate :username => "foo@bar.com", :password => "ThePasswordTheSecurityToken"  #=> "the-oauth-token"

Authentication via OAuth2 as a rack middleware

These feature is from databasedotcom-oauth2 as merged.

Usage

Minimal

use Databasedotcom::OAuth2::WebServerFlow,
  :token_encryption_key => "replace me",
  :endpoints => {"login.salesforce.com" => {:key => "replace me", :secret => "replace me"}}

Insert above code wherever your Rack Stack is defined. See Required Configuration Parameters for more information on parameters.

Multiple Endpoints

use Databasedotcom::OAuth2::WebServerFlow,
:endpoints => {"login.salesforce.com" => {:key => "replace me", :secret => "replace me"},
             "test.salesforce.com"  => {:key => "replace me", :secret => "replace me"}}

Authentication

use Databasedotcom::OAuth2::WebServerFlow,
  :display   => "touch"        , #default is "page"
  :immediate => true           , #default is false
  :prompt    => "login consent", #default is nil
  :scope     => "full"           #default is "id api refresh_token"

Miscellaneous

use Databasedotcom::OAuth2::WebServerFlow,
  :api_version => "24.0"      , #default is 25.0
  :debugging   => "true"      , #default is false
  :path_prefix => "/auth/sfdc"  #default is /auth/salesforce

Required Configuration Parameters

:endpoints

Hash of remote access applications; at least one is required. Values must be generated via salesforce.com at Setup > App Setup > Develop > Remote Access. Only one remote access application is needed for production, sandbox, or pre-release; separate entries are not necessary for My Domain.

Example:

:endpoints => {"login.salesforce.com" => {:key => "replace me", :secret => "replace me"}
               "test.salesforce.com"  => {:key => "replace me", :secret => "replace me"}}

Default: nil

:token_encryption_key

Encrypts OAuth 2.0 token prior to persistence in session store. Any Rack session store can be used: Rack:Session:Cookie, Rack:Session:Pool, etc. A sufficiently strong key must be generated. It’s recommended you use the following command to generate a random key value.

ruby -ropenssl -rbase64 -e "puts Base64.strict_encode64(OpenSSL::Random.random_bytes(16).to_str)"

It’s also recommended you store the key value as an environment variable as opposed to a string literal in your code. To both create the key value and store as an environment variable, use this command:

export TOKEN=`ruby -ropenssl -rbase64 -e "puts Base64.strict_encode64(OpenSSL::Random.random_bytes(16).to_str)"`

Then, in your code, decrypt prior to use:

require "base64"
Base64.strict_decode64(ENV['TOKEN'])

Default: nil

Optional Configuration Parameters

:display, :immediate, :prompt, :scope

Values passed directly to salesforce.com which control authentication behavior. See OAuth 2.0 Web Server Authentication Flow for detailed explanation as well as valid and default values.

Default: see OAuth 2.0 Web Server Authentication Flow

:display_override, :immediate_override, :prompt_override, :scope_override

Allow correspondingly named parameter to be overridden at runtime via http parameter of same name. For example, if your app is capable of detecting the client device type, set **‘:display_override`** to true and pass a display http parameter to `/auth/salesforce`.

Default: false

:api_version

For explanation of api versions, see What’s New in Version XX.X

Default: 25.0

:debugging

Will enable debug output for both this gem and databasedotcom.

Default: false

:on_failure

A lambda block to be executed upon authentication failure.

Default: redirect to ‘/auth/salesforce/failure` with error message passed via message http parameter.

:path_prefix

The path that signals databasedotcom-oauth2 to initiate authentication with salesforce.com.

Default: /auth/salesforce

Accessing the Sobject API

You can retrieve a list of Sobject defined in your Salesforce instance like so:

client.list_sobjects  #=> ['User', 'Group', 'Contact']

Once you have the name of an Sobject, the easiest way to interact with it is to first materialize it:

contact_class = client.materialize("Contact") #=> Contact

By default, Sobject classes are materialized into the global namespace- if you want materialize into another module, you can easily do configure this:

client.sobject_module = My::Module
client.materialize("Contact") #=> My::Module::Contact

Materialized Sobject classes behave much like ActiveRecord classes:

contact = Contact.find("contact_id")                #=> #<Contact @Id="contact_id", ...>
contact = Contact.find_by_Name("John Smith")        #=> dynamic finders!
contacts = Contact.all                              #=> a Databasedotcom::Collection of Contact instances
contacts = Contact.find_all_by_Company("IBM")       #=> a Databasedotcom::Collection of matching Contacts
contact.Name                                        #=> the contact's Name attribute
contact["Name"]                                     #=> same thing
contact.Name = "new name"                           #=> change the contact's Name attribute, in memory
contact["Name"] = "new name"                        #=> same thing
contact.save                                        #=> save the changes to the database
contact.update_attributes "Name" => "newer name",
  "Phone" => "4156543210"                           #=> change several attributes at once and save them
contact.delete                                      #=> delete the contact from the database

See the documentation for full details.

Accessing the Chatter API

You can easily access Chatter feeds, group, conversations, etc.:

my_feed_items = Databasedotcom::Chatter::UserProfileFeed.find(client)  #=> a Databasedotcom::Collection of FeedItems

my_feed_items.each do |feed_item|
  feed_item.likes                   #=> a Databasedotcom::Collection of Like instances
  feed_item.comments                #=> a Databasedotcom::Collection of Comment instances
  feed_item.raw_hash                #=> the hash returned from the Chatter API describing this FeedItem
  feed_item.comment("This is cool") #=> create a new comment on the FeedItem
  feed_item.like                    #=> the authenticating user likes the FeedItem
end

me = Databasedotcom::Chatter::User.find(client, "me")   #=> a User for the authenticating user
me.followers                                              #=> a Databasedotcom::Collection of Users
me.post_status("what I'm doing now")                      #=> post a new status

you = Databasedotcom::Chatter::User.find(client, "your-user-id")
me.follow(you)                                            #=> start following a user

See the documentation for full details.

License

This gem is licensed under the MIT License.