The Desk Ruby Gem
====================
A Ruby wrapper for the [Desk.com API](http://dev.desk.com/)
Installation
------------
gem install desk
What's new in 1.0.0?
--------------------
Completely rewritten for Desk.com API v2
For those upgrading from API v2 (Desk gem v0.3.x), check out the [transition
guide](TRANSITION.mkd)
Help! I'm getting: "Did not recognize your engine specification. Please specify either a symbol or a class. (RuntimeError)"
---------------------------------------------------------------------------------------------------------------------------
You'll need to explicitly require a JSON library.
We recommend [yajl-ruby](http://github.com/brianmario/yajl-ruby).
Overview
--------------
Desk.com's API v2 follows a standard structure for (almost) every endpoint (see
the last section of the examples for the irregularities). Each endpoint
impliments some, or all, of the following actions: list, search, show, create,
update and delete. Additionally, some endpoints impliment sub-endpoints that
utilize the same list of actions.
The endpoint actions, and sub-endpoint actions, are implimented as methods in
the following way:
[action]_[endpoint] or [action]_[endpoint]_[sub-endpoint]
http://dev.desk.com/API/cases
The cases endpoint is a great example. It impliments the list, search, show,
create and updated actions. It additionally impliments sub-endpoints for
messages, replies, notes and attachments related to cases.
See the above link for more information.
For the Case endpoint, the create action would look like:
Desk.create_case(args)
For the Reply sub-endpoint under Cases, the update action would look like:
Desk.update_case_reply(case_id, reply_id, args)
Take note, as reflected in the Desk.com API documentation, that the list and
search actions change the plurality of the endpoint or sub-endpoint. Such as:
Desk.search_cases
Desk.list_case_replies(case_id)
Aliases
-------------
For ease of use, the list and show endpoint and sub-endpoint methods have
aliases that drop the action. These translate as follows:
list_[endpoint plural] => [endpoint plural]
show_[endpoint] => [endpoint]
list_[endpoint]_[sub-endpoint pluaral] => [endpoint]_[sub-endpoint plural]
show_[endpoint]_[sub-endpoint] => [endpoint]_[sub-endpoint]
For the Case endpoint and Reply sub-endpoint that would look like:
Desk.cases
Desk.case(case_id)
Desk.case_replies(case_id)
Desk.case_reply(case_id, reply_id)
Additionally, for endpoints that impliment the search action, the list and list
alias will intelligently use the correct API action for the provided arguments.
Meaning, all of the following are valid:
Desk.cases
Desk.cases(:page => 2)
Desk.cases(:status => "new,open")
Desk.cases(:status => "new,open", :page => 2, :per_page => 10)
Responses
--------------
While the raw API responses are available (see below), results are by default
translated into cleaner, more accessible Ruby objects, allowing the following:
cases = Desk.cases
cases.each do |c|
puts c.priority
puts c.status
end
For actions like show, create and update the endpoint fields are accessible in
the object root, such as:
c = Desk.case(case_id)
puts c.priority
puts c.status
Additionally, the new "\_links" in API v2 are easily accessible in this way as
well. Because each link (like self, first, next, etc) contain a fully formated
API callback, we're able to directly load the results of that link and return
the resulting object. This allows for clean, simple code like the following to
page though all the avaiable cases:
cases = Desk.list_cases
while cases
cases.each do |c|
# do something with each case
end
cases = cases.next
end
Or to easily access a case's assigned user and assigned group:
c = Desk.show_case(case_id)
user_object = c.assigned_user
group_object = c.assigned_group
Raw Responses
--------------
While almost all of the Desk.com API results are accessible, in some form, using
the simple object keys above the raw results are still avaiable via the "raw" key.
This allows for:
c = Desk.show_case(case_id)
puts c.raw["_links"]["self"]["class"]
Usage Examples
--------------
require "rubygems"
require "desk"
# All methods require authentication. To get your Desk OAuth credentials,
# register an app in the Desk.com admin for your account at http://your-domain.desk.com/admin
Desk.configure do |config|
config.support_email = "help@example.com"
config.subdomain = YOUR_DESK_SUBDOMAIN
config.consumer_key = YOUR_CONSUMER_KEY
config.consumer_secret = YOUR_CONSUMER_SECRET
config.oauth_token = YOUR_OAUTH_TOKEN
config.oauth_token_secret = YOUR_OAUTH_TOKEN_SECRET
end
######
# List examples
######
# List cases
Desk.cases
# List customers
Desk.customers
# List site settings
Desk.site_settings
# List twitter users
Desk.twitter_users
# List article translations
Desk.article_translations(1)
# List case notes
Desk.case_notes(12345)
######
# Search examples
######
# Search articles
Desk.articles(:text => "happy", :topic_ids => "1,2,4")
# Search cases
Desk.cases(:since_id => 12345)
# Search companies
Desk.companies(:q => "acme")
# Search customers
Desk.customers(:last_name => "Smith", :custom_field => "IS 5416")
######
# Show examples
######
# Get a specific custom field
Desk.custom_field(1)
# Get a specific facebook user
Desk.facebook_user(1234)
# Get a specific case
Desk.case(12345)
# Get a specific twitter account
Desk.twitter_account(2)
######
# Create examples
######
# Create a new phone case
Desk.create_case(
:type => "phone",
:subject => "Creating a case via the API",
:priority => 4,
:status => "open",
:labels => [ "Spam", "Ignore" ],
:_links => {
:customer => {
:href => "/api/v2/customers/1",
:class => "customer"
},
:assigned_user => {
:href => "/api/v2/users/1",
:class => "user"
},
:assigned_group => {
:href => "/api/v2/groups/1",
:class => "group"
},
:locked_by => {
:href => "/api/v2/users/1",
:class => "user"
},
:entered_by => {
:href => "/api/v2/users/1",
:class => "user"
}
},
:message => {
:direction => "out",
:body => "Please assist me with this case",
}
)
# Create a new label
Desk.create_label(
:name => "MyLabel",
:description => "A Test Label",
:types => [ "case", "macro" ],
:color => "blue"
)
# Create a new topic
Desk.create_topic(
:name => "Social Media",
:allow_questions => true,
:in_support_center => true
)
######
# Update examples
######
# Update a customer
Desk.update_customer(123,
:first_name => "Johnny",
:emails => [
{ :type => "work", :value => "johnny@acme.com" },
{ :type => "other", :value => "johnny@other.com" }
],
:custom_fields => { :level => "super" }
)
# Update an integration URL
Desk.update_integration_url(10, :enabled => false)
# Update a macro
Desk.update_macro(5, :name => "Macro 5")
######
# Delete examples
######
# Delete a case
Desk.delete_case(12345)
# Delete a label
Desk.delete_label(2)
# Delete a macro
Desk.delete_macro(10)
######
# Sub-endpoint examples
######
# Get the original message for a specific case
Desk.case_message(12345)
# Get the cases for a specifc filter
Desk.filter_cases(8)
# Output all replies for a specific case
Desk.case_replies(12345).each { |r| puts r.body }
# Update the translation for a specific topic
Desk.update_topic_translation(1, "ja", :name => "The Japanese Translation")
# Delete a specifc attachment for a specific case
Desk.delete_case_attachment(12345, 10)
######
# _link helper examples
######
# Output the original message and all replies using the _link helpers
c = Desk.case(12345)
puts c.message.body
c.replies.each { |r| puts r.body }
# Output all article subjects, who created them and who last updated them
Desk.articles.each do |a|
puts a.subject
puts "Created at: #{a.created_at} by #{a.created_by.public_name}"
puts "Updated at: #{a.updated_at} by #{a.updated_by.public_name}"
end
# For all customers who have been created since 01/01/2013, output the
# original message for all cases for those customers
Desk.customers(:since_created_at => 1385856000).each do |customer|
customer.cases.each do |c|
puts c.message.body
end
end
######
# Helper methods
######
# Add an address, email and phone
# number to an existing customer
customer = Desk.customer(12345)
customer_add_address(customer, "12545 Riata Vista Cir, Austin, TX 78727", "work")
customer_add_email(customer, "ruby@desk.com")
customer_add_phone_number(customer, "123-456-7890", "other")
# Delete a specific address, email and
# phone number from an existing customer
customer = Desk.customer(12345)
customer_delete_address(customer, "12545 Riata Vista Cir, Austin, TX 78727")
customer_delete_email(customer, "ruby@desk.com")
customer_delete_phone_number(customer, "123-456-7890")
# Delete all addresses and phone
# numbers of a specific type
customer = Desk.customer(12345)
customer_delete_address(customer, "work")
customer_delete_phone_number(customer, "other")
# The delete helpers also support mixing
# and matching multiple items
customer = Desk.customer(12345)
customer_delete_address(customer, "work", "other", " "12545 Riata Vista Cir, Austin, TX 78727")
customer_delete_email(customer, "ruby@desk.com", "gem@desk.com")
customer_delete_phone_number(customer, "work", "123-456-7890", "908-456-321")
######
# "non-standard" examples
######
# Get a case url
Desk.case_url(12345)
# Get the history for a sepcific case
Desk.case_history(12345)
# Show insights meta data
Desk.insights_meta
# Create insights report
Desk.create_insights_report(
:resolution => "days",
:min_date => "2013-12-01",
:max_date => "2013-12-16",
:dimension1_name => "*",
:dimension1_values => "*",
:dimension2_name => "*",
:dimension2_values => "*"
)
# Show the daily system message
Desk.system_message
Contributing
------------
In the spirit of [free software](http://www.fsf.org/licensing/essays/free-sw.html), **everyone** is encouraged to help improve this project.
Here are some ways *you* can contribute:
* by using alpha, beta, and prerelease versions
* by reporting bugs
* by suggesting new features
* by writing or editing documentation
* by writing specifications
* by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace)
* by refactoring code
* by closing [issues](http://github.com/zencoder/desk/issues)
* by reviewing patches
All contributors will be added to the [HISTORY](https://github.com/zencoder/desk/blob/master/HISTORY.mkd)
file and will receive the respect and gratitude of the community.
Submitting an Issue
-------------------
We use the [GitHub issue tracker](http://github.com/zencoder/desk/issues) to track bugs and
features. Before submitting a bug report or feature request, check to make sure it hasn't already
been submitted. You can indicate support for an existing issuse by voting it up. When submitting a
bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any
details that may be necessary to reproduce the bug, including your gem version, Ruby version, and
operating system. Ideally, a bug report should include a pull request with failing specs.
Submitting a Pull Request
-------------------------
1. Fork the project.
2. Create a topic branch.
3. Implement your feature or bug fix.
4. Add documentation for your feature or bug fix.
5. Run bundle exec rake doc:yard. If your changes are not 100% documented, go back to step 4.
6. Add specs for your feature or bug fix.
7. Run bundle exec rake spec. If your changes are not 100% covered, go back to step 6.
8. Commit and push your changes.
9. Submit a pull request. Please do not include changes to the gemspec, version, or history file. (If you want to create your own version for some reason, please do so in a separate commit.)
Copyright
---------
Copyright (c) 2012 Chris Warren/[Zencoder](http://zencoder.com)
See [LICENSE](https://github.com/zencoder/desk/blob/master/LICENSE.mkd) for details.