class Restforce::Client

def api_path(path)

# => '/services/data/v24.0/sobjects'
api_path('sobjects')

Examples

Internal: Returns a path to an api endpoint
def api_path(path)
  "/services/data/v#{@options[:api_version]}/#{path}"
end

def authenticate!

Public: Force an authentication
def authenticate!
  raise 'No authentication middleware present' unless authentication_middleware
  middleware = authentication_middleware.new nil, self, @options
  middleware.authenticate!
end

def authentication_middleware

Internal: Determines what middleware will be used based on the options provided
def authentication_middleware
  if username_password?
    Restforce::Middleware::Authentication::Password
  elsif oauth_refresh?
    Restforce::Middleware::Authentication::Token
  end
end

def cache

Internal: Cache to use for the caching middleware
def cache
  @options[:cache]
end

def connection

Internal: Internal faraday connection where all requests go through
def connection
  @connection ||= Faraday.new(@options[:instance_url]) do |builder|
    builder.use      Restforce::Middleware::Mashify, self, @options
    builder.use      Restforce::Middleware::Multipart
    builder.request  :json
    builder.use      authentication_middleware, self, @options if authentication_middleware
    builder.use      Restforce::Middleware::Authorization, self, @options
    builder.use      Restforce::Middleware::InstanceURL, self, @options
    builder.response :json
    builder.use      Restforce::Middleware::Caching, cache, @options if cache
    builder.use      FaradayMiddleware::FollowRedirects
    builder.use      Restforce::Middleware::RaiseError
    builder.use      Restforce::Middleware::Logger, Restforce.configuration.logger, @options if Restforce.log?
    builder.adapter  Faraday.default_adapter
  end
  @connection
end

def create(sobject, attrs)

something bad happens
Returns the String Id of the newly created sobject. Returns false if

# => '0016000000MRatd'
client.create('Account', Name: 'Foobar Inc.')
# Add a new account

Examples

Public: Insert a new record.
def create(sobject, attrs)
  create!(sobject, attrs)
rescue *exceptions
  false
end

def create!(sobject, attrs)

something bad happens.
Returns the String Id of the newly created sobject. Raises an error if

See .create
def create!(sobject, attrs)
  response = api_post "sobjects/#{sobject}", attrs
  response.body['id']
end

def decode_signed_request(message)

Returns the Hash context if the message is valid.

message - The POST message containing the signed request from Salesforce.

Public: Decodes a signed request received from Force.com Canvas.
def decode_signed_request(message)
  raise 'client_secret not set' unless @options[:client_secret]
  encryped_secret, payload = message.split('.')
  digest = OpenSSL::Digest::Digest.new('sha256')
  signature = Base64.encode64(OpenSSL::HMAC.hexdigest(digest, @options[:client_secret], payload))
  JSON.parse(Base64.decode64(payload)) if encryped_secret == signature
end

def describe(sobject=nil)

Returns the Hash representation of the describe call.

# => { ... }
client.describe('Account')
# get the describe for the Account object

# => { ... }
client.describe
# get the global describe for all sobjects

Examples

sobject - Stringish name of the sobject (default: nil).

Public: Returns a detailed describe result for the specified sobject
def describe(sobject=nil)
  if sobject
    response = api_get "sobjects/#{sobject.to_s}/describe"
    response.body
  else
    response = api_get 'sobjects'
    response.body['sobjects']
  end
end

def destroy(sobject, id)

Returns true if the sobject was successfully deleted, false otherwise.

client.delete('Account', '0016000000MRatd')
# Delete the Account with Id '0016000000MRatd'

Examples

Public: Delete a record.
def destroy(sobject, id)
  destroy!(sobject, id)
rescue *exceptions
  false
end

def destroy!(sobject, id)

otherwise.
Returns true of the sobject was successfully deleted, raises an error

See .destroy
def destroy!(sobject, id)
  api_delete "sobjects/#{sobject}/#{id}"
  true
end

def exceptions

Internal: Errors that should be rescued from in non-bang methods
def exceptions
  [Faraday::Error::ClientError]
end

def faye

Internal: Faye client to use for subscribing to PushTopics
def faye
  raise 'Instance URL missing. Call .authenticate! first.' unless @options[:instance_url]
  @faye ||= Faye::Client.new("#{@options[:instance_url]}/cometd/#{@options[:api_version]}").tap do |client|
    raise 'OAuth token missing. Call .authenticate! first.' unless @options[:oauth_token]
    client.set_header 'Authorization', "OAuth #{@options[:oauth_token]}"
    client.bind 'transport:down' do
      Restforce.log "[COMETD DOWN]"
    end
    client.bind 'transport:up' do
      Restforce.log "[COMETD UP]"
    end
  end
end

def initialize(options = {})

# => #
:instance_url => 'https://na1.salesforce.com'
Restforce::Client.new :oauth_token => 'access token',
# Initialize a new client with using any authentication middleware:

# => #
:client_secret => 'client secret'
:client_id => 'client id',
:instance_url => 'https://na1.salesforce.com',
:refresh_token => 'refresh token',
Restforce::Client.new :oauth_token => 'access token',
# Initialize a new client using oauth authentication:

# => #
:client_secret => 'client secret'
:client_id => 'client id',
:security_token => 'security token',
:password => 'pass',
Restforce::Client.new :username => 'user',
# Initialize a new client using password authentication:

Examples

:api_version - The String REST api version to use (default: '24.0')

authentication requests (default: 'login.salesforce.com').
:host - The String hostname to use during

:client_secret - The oauth client secret to use.
password and oauth authentication
:client_id - The oauth client id to use. Needed for both

(required if oauth authentication is used).
:instance_url - The String base url for all api requests
authentication is used).
oauth access tokens (required if oauth
:refresh_token - The String refresh token to obtain fresh
authentication is used).
calls (required unless password
:oauth_token - The String oauth access token to authenticate api

(required for password authentication).
:security_token - The String security token to use
:password - The String password to use (required for password authentication).
:username - The String username to use (required for password authentication).
options - A hash of options to be passed in (default: {}).

Public: Creates a new client instance
def initialize(options = {})
  raise 'Please specify a hash of options' unless options.is_a?(Hash)
  @options = {}.tap do |options|
    [:username, :password, :security_token, :client_id, :client_secret, :host,
     :api_version, :oauth_token, :refresh_token, :instance_url, :cache, :authentication_retries].each do |option|
      options[option] = Restforce.configuration.send option
    end
  end
  @options.merge!(options)
end

def list_sobjects

Returns an Array of String names for each SObject.

# => ['Account', 'Lead', ... ]
client.list_sobjects
# get the names of all sobjects on the org

Examples

Public: Get the names of all sobjects on the org.
def list_sobjects
  describe.collect { |sobject| sobject['name'] }
end

def mashify?

Restforce::Middleware::Mashify middleware.
Internal: Returns true if the middlware stack includes the
def mashify?
  connection.builder.handlers.find { |handler| handler == Restforce::Middleware::Mashify }
end

def oauth_refresh?

authentication.
Internal: Returns true if oauth token refresh flow should be used for
def oauth_refresh?
  @options[:refresh_token] &&
    @options[:client_id] &&
    @options[:client_secret]
end

def org_id

Returns the String organization Id

# => '00Dx0000000BV7z'
client.org_id

Examples

Public: Get the current organization's Id.
def org_id
  query('select id from Organization').first['Id']
end

def query(soql)

Returns an Array of Hash for each record in the result if Restforce.configuration.mashify is false.
Returns a Restforce::Collection if Restforce.configuration.mashify is true.

# => ['Foo Bar Inc.', 'Whizbang Corp']
client.query('select Name from Account').map(&:Name)
# Find the names of all Accounts

Examples

soql - A SOQL expression.

Public: Executs a SOQL query and returns the result.
def query(soql)
  response = api_get 'query', q: soql
  mashify? ? response.body : response.body['records']
end

def search(sosl)

Returns an Array of Hash for each record in the result if Restforce.configuration.mashify is false.
Returns a Restforce::Collection if Restforce.configuration.mashify is true.

# => ['GenePoint']
client.search('FIND {genepoint} RETURNING Account (Name)').map(&:Name)
# Find accounts match the term 'genepoint' and return the Name field

# => #
client.search('FIND {bar}')
# Find all occurrences of 'bar'

Examples

sosl - A SOSL expression.

Public: Perform a SOSL search
def search(sosl)
  response = api_get 'search', q: sosl
  response.body
end

def subscribe(channel, &block)

Returns a Faye::Subscription

block - A block to run when a new message is received.
channel - The name of the PushTopic channel to subscribe to.

Public: Subscribe to a PushTopic
def subscribe(channel, &block)
  faye.subscribe "/topic/#{channel}", &block
end

def update(sobject, attrs)

Returns true if the sobject was successfully updated, false otherwise.

client.update('Account', Id: '0016000000MRatd', Name: 'Whizbang Corp')
# Update the Account with Id '0016000000MRatd'

Examples

Public: Update a record.
def update(sobject, attrs)
  update!(sobject, attrs)
rescue *exceptions
  false
end

def update!(sobject, attrs)

otherwise.
Returns true if the sobject was successfully updated, raises an error

See .update
def update!(sobject, attrs)
  id = attrs.has_key?(:Id) ? attrs.delete(:Id) : attrs.delete('Id')
  raise 'Id field missing.' unless id
  api_patch "sobjects/#{sobject}/#{id}", attrs
  true
end

def upsert(sobject, field, attrs)

Returns false if something bad happens.
Returns the Id of the newly created record if the record was created.
Returns true if the record was found and updated.

client.upsert('Account', 'External__c', External__c: 12, Name: 'Foobar')
# Update the record with external ID of 12

Examples

attrs - Hash of attributes for the record.
field - The name of the external Id field to match against.
sobject - The name of the sobject to created.

Public: Update or Create a record based on an external ID
def upsert(sobject, field, attrs)
  upsert!(sobject, field, attrs)
rescue *exceptions
  false
end

def upsert!(sobject, field, attrs)

Raises an error if something bad happens.
Returns the Id of the newly created record if the record was created.
Returns true if the record was found and updated.

See .upsert
def upsert!(sobject, field, attrs)
  external_id = attrs.has_key?(field.to_sym) ? attrs.delete(field.to_sym) : attrs.delete(field.to_s)
  response = api_patch "sobjects/#{sobject}/#{field.to_s}/#{external_id}", attrs
  (response.body && response.body['id']) ? response.body['id'] : true
end

def username_password?

authentication.
Internal: Returns true if username/password (autonomous) flow should be used for
def username_password?
  @options[:username] &&
    @options[:password] &&
    @options[:security_token] &&
    @options[:client_id] &&
    @options[:client_secret]
end

def without_caching(&block)

Returns the result of the block

block - A query/describe/etc.

Public: Runs the block with caching disabled.
def without_caching(&block)
  @options[:perform_caching] = false
  block.call
ensure
  @options.delete(:perform_caching)
end