¶ ↑
rubyzoho<img src=“https://travis-ci.org/amalc/rubyzoho.png?branch=master” alt=“Build Status” /> <img src=“https://gemnasium.com/amalc/rubyzoho.png” alt=“Dependency Status” /> <img src=“https://codeclimate.com/github/amalc/rubyzoho.png” /> <img src=“https://coveralls.io/repos/amalc/rubyzoho/badge.png?branch=master” alt=“Coverage Status” /> <img src=“https://badge.fury.io/rb/rubyzoho.svg” alt=“Gem Version” /> <img src=“https://img.shields.io/gem/dt/rubyzoho.svg” alt=“Downloads” />
Abstracting Zoho’s API into a set of Ruby classes, with reflection of Zoho’s fields using a more familiar ActiveRecord lifecycle, but without ActiveRecord. Current focus is on Zoho CRM.
Release notes are at the end of this page.
¶ ↑
Installgem install rubyzoho
¶ ↑
Configure¶ ↑
RailsPut the following in an initializer (e.g. <RAILS_ROOT>/config/initializers/zoho.rb
):
require 'ruby_zoho' RubyZoho.configure do |config| config.api_key = '<< API Key from Zoho>>' # config.crm_modules = ['Accounts', 'Contacts', 'Leads', 'Potentials'] # Defaults to free edition if not set # config.crm_modules = ['Quotes', 'SalesOrders', 'Invoices'] # Depending on what kind of account you've got, adds to free edition modules # config.ignore_fields_with_bad_names = true # Ignores field with special characters in the name (Release 1.8) # Currently only Quotes are supported end
You can reduce the number of API calls made during development and production by adding
config.cache_fields = true
to the initializer. You can also limit the number of modules in use, so if you’re only using ‘Leads’ for instance, set the gem to only load field data from ‘Leads’ by setting
config.crm_modules = ['Leads']
and only meta data from ‘Leads’ will be loaded.
In Test or Continous Integration(CI) environments, one strategy is not to initialize the gem at all, so for example,
RubyZoho.configure do |config| config.api_key = '<< API Key from Zoho>>' config.crm_modules = ['Accounts'] config.cache_fields = true if Rails.env.development? end unless Rails.env.test?
and wrap the code calling the API in a begin ... rescue
block.
¶ ↑
RubyMake sure the following block is executed prior to making calls to the gem.
require 'ruby_zoho' RubyZoho.configure do |config| config.api_key = '<< API Key from Zoho>>' # config.crm_modules = ['Accounts', 'Contacts', 'Leads', 'Potentials'] # Defaults to free edition if not set # config.crm_modules = ['Quotes', 'SalesOrders', 'Invoices'] # Depending on what kind of account you've got, adds to free edition modules # config.ignore_fields_with_bad_names = true # Ignores field with special characters in the name (Release 1.8) # Currently only Quotes are suported end
Please be aware that Zoho limits API calls. So running tests repeatedly will quickly exhaust your daily allowance. See below for some optimizations during development and testing.
¶ ↑
UseRubyZoho attempts to follow the ActiveRecord lifecycle, i.e. new, save, update and delete. See examples below. (N.B. Fields cannot have special characters in them.)
To get a list of supported attributes for a Zoho CRM contact:
require 'ruby_zoho' c = RubyZoho::Crm::Contact.new c.attr_writers # => List of updatable attributes c.fields # => Array of all fields
Attributes are reflected from the current API instance of Zoho, dynamically on initialization of the API, when the RubyZoho.configure block is called. This includes custom fields.
Another example:
l = RubyZoho::Crm::Lead.new l.attr_writers # => List of updatable attributes l.fields # => Array of all fields
To retrieve an existing record:
l = RubyZoho::Crm::Lead.find_by_email('email@domain.com')
Returns one or more records matching the query. The find_by_<attribute> follows ActiveRecord style reflections, so if the attribute is present in the API, it can be queried. There is currently a single attribute limitation imposed by the Zoho API. Note, what is returned is an Array class which is also Enumerable. Use .each
, .map
, .first
, .last
, etc to navigate through the result set.
Equality is the only match currently supported.
To get a list of all accounts:
a = RubyZoho::Crm::Account.all a.each do |account| pp account.account_name end
Or for all task subjects:
t = RubyZoho::Crm::Task.all pp t.collect { |task| task.subject } # => ['Subject 1'], ['Subject 2'], ... ['Subject n']
Or for all quotes:
q = RubyZoho::Crm::Quote.all q.each do |quote| pp quote.subject pp quote.quote_name end
To get the first quote:
q.first
Or the last one:
q.last
Since the result is Enumerable:
q.map { |m| m.last_name }
works.
To sort a result set:
r = RubyZoho::Crm::Contact.all sorted = r.sort {|a, b| a.last_name <=> b.last_name } pp sorted.collect { |c| c.last_name } # => ['Name 1', ['Name 2'], ... ['Name n']]
To find by ID, note well, ID is a string:
leads = RubyZoho::Crm::Lead.all l = RubyZoho::Crm::Lead.find_by_leadid(leads.last.leadid)
To create a new record:
c = RubyZoho::Crm::Contact.new( :first_name => 'First Name', :last_name => 'Last Name', :email => 'email@domain.com', etc. ) c.save r = RubyZoho::Crm::Contact.find_by_email('email@domain.com') r.first.contactid # => Has the newly created contact's ID
To add a contact to an existing account:
a = RubyZoho::Crm::Account.find_by_account_name('Very Big Account') c = RubyZoho::Crm::Contact.new( :first_name => 'First Name', :last_name => 'Last Name', :email => 'email@domain.com', :account_name => a.first.account_name, :accountid => a.first.accountid # accountid instead of account_id because of Zoho's convention etc. ) c.save
To update a record (Note, that the attribute is :id):
l = RubyZoho::Crm::Lead.find_by_email('email@domain.com') RubyZoho::Crm::Lead.update( :id => l.first.leadid, :email => 'changed_email@domain.com' )
Custom fields are like any other field or method in Ruby:
a = RubyZoho::Crm::Account.find_by_account_name('Very Big Account') pp a.custom_field # => 'Custom field content'
Or:
c = RubyZoho::Crm::Contact.new( :first_name => 'First Name', :last_name => 'Last Name', :email => 'email@domain.com', :account_name => a.first.account_name, :accountid => a.first.accountid, # accountid instead of account_id because of Zoho's convention :custom_field_2 => 'Custom text' ) pp c.save # Reflects back the new Zoho record ID, and various create and modify times and users
To attach a file to a record (Tested for Accounts
, Contacts
, Leads
, Potentials
and Tasks
only):
l = RubyZoho::Crm::Lead.find_by_email('email@domain.com') l.attach_file(file_path, file_name) # Can only be attached to a pre-existing record
To grab any attachments from a record:
attachments = RubyZoho.configuration.api.related_records('Contacts', 'contact_id', 'Attachments') RubyZoho.configuration.api.download_file('Contacts', attachments.first[:id])
Classes (Zoho modules) currently supported are:
RubyZoho::Crm::Account RubyZoho::Crm::Contact RubyZoho::Crm::Lead RubyZoho::Crm::Potential RubyZoho::Crm::Task RubyZoho::Crm::Quote RubyZoho::Crm::User
¶ ↑
Error HandlingErrors, i.e. situations where the Zoho API either returns an http code something other than 200 or where the Zoho API sends back an explicit error code which isn’t in the set
['4422', '5000']
a standard Ruby RuntimeError
exception is raised with the Zoho’s API message.
¶ ↑
Optimizations for Development and TestingSet config.cache_fields = true
in the configuration block. This caches module field lists and is useful during development and testing, to reduce total API calls during start up. Defaults to false. We do not recommend use of this in production. The gem will need write access to its own directory for this to work.
RubyZoho.configure do |config| # Other stuff for initialization config.cache_fields = true end
¶ ↑
Idiosyncractic BehaviorFrom freedictionary.com id·i·o·syn·cra·sy ( d - -s ng kr -s ). n. pl. id·i·o·syn·cra·sies. 1. A structural or behavioral characteristic peculiar to an individual or group.
The Zoho API is definitely opinionated. And we have yet to be able plumb the depths of its views. If it behaves unexpectedly, try the Zoho forums before opening an issue here. It just may be the way the API works…
An example of this is retrieving related records. You would think that since a Task can be related to an Account or a Potential etc. that you should be able to retrieve it by either the related module’s record id, which is stored with the Task. But no, can’t be done.
¶ ↑
Bugs and EnhancementsPlease open an issue on GitHub. Or better yet, send in a pull request with the fix or enhancement!
¶ ↑
Known Bugs or Issues-
If you’re having trouble with updating custom fields, be sure to check the permission of the user that created the custom field.
-
Only text fields can be updated as custom fields. At this point it isn’t clear what to send the Zoho API to have it accept anything else. Please send in a PR if you figure it out.
¶ ↑
Roadmap (Ranked)-
AR style master/detail updates e.g. where
a
is an account.a << RubyZoho::Crm::Contact.new( :last_name => 'Last Name', :first_name => 'First Name' )
-
Get related records using AR style syntax, e.g.
pp a.contacts
to get contacts associated with an account.
-
Support for multiple find fields.
¶ ↑
Contributing to rubyzoho-
Pull requests with unit tests or specs and a version branch are welcomed.
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet.
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it.
-
Fork the project.
-
Start a feature/bugfix branch.
-
Commit and push until you are happy with your contribution.
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
¶ ↑
AcknowledgementsGiant buckets of Gratitude to the giants, sung and unsung heroes who put together and support the Open Source movement, Linux, Ruby and Rails. We stand on the shoulders of giants. Thank you.
¶ ↑
Credits and ContributionsThanks to a growing and wonderful community! @aeldaly @fheemeyer @kjcpass @qume @richkettle @summera @swithik @tjsousa @wcgiles @benknowles
Drop me a line if I’ve left anybody out and my advance apologies.
¶ ↑
TrademarksZoho, the Zoho suite and related applications are owned, trademarked and copyrighted by the Zoho Corporation Pvt. Ltd. This software is not associated in anyway with the Zoho Corporation Pvt. Ltd.
¶ ↑
CopyrightCopyright © 2013 - 2015 amalc (@amalc). Released under the MIT license. See LICENSE.txt for further details.
¶ ↑
ReleasesSemantic Versioning)¶ ↑
Release Candidates (Uses¶ ↑
Development- 0.8.0
-
<< syntax for Account/Tasks on Master/Detail relationships
-
ActiveRecord style syntax for Class.new, Class.delete, Class.find, Class.update, Object.save
-
Modules Supported: Accounts, Contacts, Leads, Potentials, Quotes, Tasks and Users
-
- 0.7.0
-
Option in config to ignore fields with improper field names
-
- 0.6.0
-
Support for testing without calling Zoho to prevent crushing API call limits in CI.
-
¶ ↑
Released- 0.5.0
-
Replaces
getSearchRecords
withsearchRecords
in the Zoho API. The direct impact of this is increasing the number of API calls you can make. However, this search method appears to be asynchronous, so if you update a record and then immediately look for it, it will not updated or in the event of a create, will return a nil. This applies to deletes as well. So a deleted record will show up in a search which immediately follows. Empirical evidence shows about 30 - 45 seconds before search is updated. Be warned! Thanks to @summera PR#33. -
Dropped support for Ruby 1.9.3.
-
- 0.4.0
-
Fixed major bug with retrieving records thanks to @kjcpass PR#28
-
- 0.3.0
-
Added activating workflows thanks to @pjsim PR#23
-
- 0.2.0
-
Added related entities feature thanks to @richkettle and @swithik.
-
Refresh dependencies
-
Remove Cucumber
-
Remove Relish
-
Fix production dependencies to reduce gem footprint
-
- 0.1.11
-
Incorporate fix to namespace collision between Devise and RubyZoho, User renamed to CRMUser thanks to @qume.
-
Other fixes from @tjsousa, @aeldaly and @fheemeyer.
-
Refactor of the code base to improve modularization and test coverage.
-
- 0.1.8 - 0.1.10
-
Various forks out in the community so bumped the release number to 0.1.11 prevent confusion.
- 0.1.7
-
Bug for attach_file method, respect the file_name parameter.
-
:id is the primary key across all Zoho related classes (modules) in addition to Zoho’s existing convention.
-
- 0.1.1 - 0.1.6
-
Alpha Releases
-
Configuration block signature changed
-
- 0.0.1 - 0.0.5
-
Alpha Releases