A ruby client for interacting with the Salesforce Metadata and Services API's.
Clone or download
Latest commit 2e13c1f Oct 26, 2014



Build Status Code Climate Dependency Status

Metaforce is a Ruby gem for interacting with the Salesforce Metadata and Services APIs.



Add this line to your application's Gemfile:

gem 'metaforce'

And then execute:

$ bundle

Or install it yourself as:

$ gem install metaforce



Username and Password

To initialize a new client, you call Metaforce.new with a hash that specifies the :username, :password, and :security_token.

client = Metaforce.new :username => 'username',
  :password => 'password',
  :security_token => 'security token'

Or you can specify the username, password and security token with environment variables:

export SALESFORCE_USERNAME="username"
export SALESFORCE_PASSWORD="password"
export SALESFORCE_SECURITY_TOKEN="security token"
client = Metaforce.new

Asynchronous Tasks

Some calls to the SOAP API's are performed asynchronously (such as deployments), meaning the response needs to be polled for. Any call to the SOAP API's that are performed asynchronously will return a Metaforce::Job object, which can be used to subscribe to on_complete and on_error callbacks. The Metaforce::Job class will poll the status of the asynchronous job in a thread until it completes or fails.

deploy(path, options={})

Takes a path (can be a path to a directory, or a zip file), and a set of DeployOptions and returns a Metaforce::Job::Deploy.

  .on_complete { |job| puts "Finished deploy #{job.id}!" }
  .on_error    { |job| puts "Something bad happened!" }
#=> #<Metaforce::Job::Deploy @id='1234'>

retrieve_unpackaged(manifest, options={})

Takes a manifest (Metaforce::Manifest or a path to a package.xml file) and a set of RetrieveOptions and returns a Metaforce::Job::Retrieve.

manifest = Metaforce::Manifest.new(:custom_object => ['Account'])
#=> #<Metaforce::Job::Retrieve @id='1234'>

create(type, metadata={})

Takes a Symbol type and a Hash of Metadata Attributes and returns a Metaforce::Job::CRUD.

client.create(:apex_page, full_name: 'Foobar', content: 'Hello World!')
  .on_complete { |job| puts "ApexPage created." }
#=> #<Metaforce::Job::CRUD @id='1234'>

update(type, current_name metadata={})

Takes a Symbol type, the current full_name of the resource, and a Hash of Metadata Attributes and returns a Metaforce::Job::CRUD.

client.update(:apex_page, 'Foobar', content: 'Hello World! Some new content!')
  .on_complete { |job| puts "ApexPage updated." }
#=> #<Metaforce::Job::CRUD @id='1234'>

delete(type, *args)

Takes a Symbol type, and the full_name of a resource and returns a Metaforce::Job::CRUD.

client.delete(:apex_page, 'Foobar')
  .on_complete { |job| puts "ApexPage deleted." }
#=> #<Metaforce::Job::CRUD @id='1234'>


Sends a SingleEmailMessage using Salesforce.

  to_addresses: ['foo@bar.com'],
  subject: 'Hello World',
  plain_text_body: 'Hello World'

If you're using Rails, check out the metaforce-delivery_method gem, which allows you to use Salesforce as the delivery mechanism for sending emails.


Metaforce also comes with a handy command line utility that can deploy and retrieve code from Salesforce. It also allows you to watch a directory and deploy when anything changes.

When you deploy, it will also run all tests and provide you with a report, similar to rspec.

$ metaforce deploy ./src
Deploying: ./src
$ metaforce watch ./src
Watching: ./src
$ metaforce retrieve ./src
Retrieving: ./src/package.xml

$ metaforce retrieve ./src/package.xml ./other-location
Retrieving: ./src/package.xml


The metaforce command will pull it's configuration from a .metaforce.yml file, if present. You can provide options for multiple environments, then use the -e swtich on the command line to use an environment. See the examples directory for an example.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request