Coder Social home page Coder Social logo

desk's Introduction

The Desk Ruby Gem

A Ruby wrapper for the Desk.com API

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

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.

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 = "[email protected]"
  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 => "[email protected]" },
    { :type => "other", :value => "[email protected]" }
  ],
  :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, "[email protected]")
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, "[email protected]")
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, "[email protected]", "[email protected]")
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

# Basic authentication with username and password; not recommended

Desk.configure do |config|
  config.support_email = "[email protected]"
  config.subdomain = YOUR_DESK_SUBDOMAIN
  config.consumer_key = YOUR_CONSUMER_KEY
  config.consumer_secret = YOUR_CONSUMER_SECRET
  config.auth_method = Desk::Authentication::Methods:BASIC
  config.basic_auth_username = YOUR_USERNAME
  config.basic_auth_password = YOUR_PASSWORD
end

Contributing

In the spirit of free software, 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
  • by reviewing patches

All contributors will be added to the HISTORY file and will receive the respect and gratitude of the community.

Submitting an Issue

We use the GitHub issue tracker 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 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 See LICENSE for details.

desk's People

Contributors

alexanderdean avatar chriswarren avatar colinc avatar cyu avatar danielmorrison avatar dcrec1 avatar duncan avatar dustin avatar erebor avatar gsomoza avatar ivey avatar jmolina4 avatar jnunemaker avatar kevn avatar kunna-ujet avatar laserlemon avatar leshill avatar pengwynn avatar periclestheo avatar pope avatar queso avatar raymondberg avatar rizwanreza avatar secobarbital avatar sferik avatar stve avatar tstachl avatar urajat avatar wkoffel avatar zmoazeni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

desk's Issues

Desk.com gem ignores client config?

Hi.

I've experienced something weird, but not necessarily a bug. Perhaps I've misunderstood something...

Anyway, after creating a case and returning the case object into a var I then tried to access the "message" property through the "raw" response like this:

new_case_object = desk.create_case(ticket_hash)
mes = new_case_object.raw.message

where "desk" is my initialized Desk.com client.

The case DOES get created, but the code croaks with this error message:
GET https://example.desk.com/api/v2/cases/3600/message: 401

It seems that when the request goes out for the "message" property somehow the subdomain gets reset or even that my initialized client doesn't get used in the request.

Has anybody else observed this behavior?

Best regards,
Thomas Balsløv.

422 error response not parsed correctly

Hi Chris.

It seems the error body is not parsed correctly for 422 errors.
The 422 response format is http://dev.desk.com/API/using-the-api/#validation-codes
which the error_body method is not parsing correctly.

I only get error messages like this missing the body part:
POST https://xxx.desk.com/api/v2/cases: 422

Secondly, it would be useful to be able to access the raw response body for getting the complete info of the error.

Best regards,
Thomas Balsløv.

Desk.delete_case is not working

The delete operation on cases doesn't seem to be supported and according to the README it should be.

Running as the readme example:

Desk.case(2096) # works, case exists
Desk.delete_case(2096) # fails, method is undefined

I get this error message:

NoMethodError: undefined method `delete_case' for Desk:Module

Dependency conflict

I wanted to use gem, but have dependecy version conflicts with some gems. You don't want contributors to change your gemspec, so I just wanted to know if you are planning dependencies update anytime soon? We are using fork in our project now, but it would be nice to use trunk. Thanks.

Bundler could not find compatible versions for gem "simple_oauth":
  In Gemfile:
    desk (>= 0) ruby depends on
      simple_oauth (~> 0.1.4) ruby

    twitter (~> 4.5.0) ruby depends on
      simple_oauth (0.2.0)

Desk.update_customer working?

Hi,
I'm using the following code trying to update a user, but the old email is still being returned without an error. Am I doing something wrong?

Desk.update_customer(107077702, :email => '[email protected]')

collections only respond to each instead of all of Enumerable

I was trying to filter through a list of rules using a regex:

client.rules.select { |r| /custom_string/ =~ r.name }

# which yields a NoMethodError because it tries to call #name on 'raw'

But it looks like only each is implemented on top of the entries collection.

Could this get expanded to implement Enumerable?

Hashie fixed version giving conflicts

Hi.

Back in issue #60 the Hashie gem was fixed to a specific version to avoid breakage in the desk gem.

This version fix is however causing fallout now where the Hashie gem continues to develop with breaking changes.

Specifically the version lock ion #60 is now causing a conflict inn our app with e.g. the Zendesk gem where Hashie version >=3.5.2 is demanded due to a bug fix involving the breaking changes in Hashie 3.5.2.

With every new Hashie version this problem of conflicts will increase.

Is there any chance for an update to allow Hashie >=3.5.2 support?

Best regards, Thomas Balsløv.

Please update faraday dependency / conflicts with google oauth2

Hey,

is it possible to update faraday dependency?

Right now it causes dependency hell along with Google OAuth2

Bundler could not find compatible versions for gem "faraday":
  In Gemfile:
    desk (~> 1.0.0) ruby depends on
      faraday (~> 0.8.0) ruby

    omniauth-google-oauth2 (>= 0) ruby depends on
      faraday (0.9.0)

TooManyRequests not handled by desk gem

First off: big thanks for creating this gem! It's awesome.

I am running desk inside of Celluloid, with 30 workers. It generates a lot of requests, fast. I've started getting errors like this:

E, [2014-03-21T16:36:25.802937 #4775] ERROR -- : Snowplow::DeskRedshiftSyncer::DeskToRedshift::Worker crashed!
Faraday::Error::ParsingError: 757: unexpected token at 'Too Many Requests'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/json-1.8.1/lib/json/common.rb:155:in `parse'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/json-1.8.1/lib/json/common.rb:155:in `parse'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response/parse_json.rb:11:in `block in <class:ParseJson>'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `parse'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:39:in `process_response'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:32:in `block in call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:63:in `on_complete'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:30:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:8:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:8:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/request/url_encoded.rb:14:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/request/multipart.rb:13:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/request/oauth.rb:42:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/faraday/request/multipart_with_file.rb:16:in `call'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/connection.rb:253:in `run_request'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/connection.rb:106:in `get'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/request.rb:51:in `request'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/request.rb:18:in `method_missing'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk.rb:25:in `method_missing'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/deash.rb:46:in `method_missing'
    /vagrant/snowplow/3-enrich/desk-redshift-syncer/lib/desk-redshift-syncer/desk_to_redshift/worker.rb:94:in `write_case_with_message'
    /vagrant/snowplow/3-enrich/desk-redshift-syncer/lib/desk-redshift-syncer/desk_to_redshift/worker.rb:47:in `block in run'
    /vagrant/snowplow/3-enrich/desk-redshift-syncer/lib/desk-redshift-syncer/desk_to_redshift/worker.rb:40:in `loop'
    /vagrant/snowplow/3-enrich/desk-redshift-syncer/lib/desk-redshift-syncer/desk_to_redshift/worker.rb:40:in `run'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `public_send'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/calls.rb:25:in `dispatch'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/calls.rb:122:in `dispatch'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/actor.rb:322:in `block in handle_message'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/actor.rb:416:in `block in task'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/tasks.rb:55:in `block in initialize'
    /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/celluloid-0.15.2/lib/celluloid/tasks/task_fiber.rb:13:in `block in create'

which is a bit odd, because I thought the library is meant to handle rate limiting? In case it's helpful, desk_to_redshift/worker.rb:94 looks like:

id = grep_uuid(cse.message.body, "id:\\s") # where cse is a Desk.com case entity

Any thoughts?

RuntimeError: missing dependency for FaradayMiddleware::Deashify: undefined method `type' for class `Hashie::Mash'

When looking up a customer with email addresses or phone numbers that have a "type" associated with them, the gem fails to parse the response.

Desk.create_customer(
    :first_name => "Joe",
    :last_name => "User",
    :emails => [{:type => "work", :value => "[email protected]"}]
)

Yields this error:

RuntimeError: missing dependency for FaradayMiddleware::Deashify: undefined method type' for class Hashie::Mash'

Faraday::ParsingError: 757: unexpected token at 'Too Many Requests'

I'm getting a faraday error that I could use some help debugging:

/usr/local/lib/ruby/2.1.0/json/
common.rb: 155:in `parse'
/usr/local/lib/ruby/2.1.0/json/
common.rb: 155:in `parse'
…re-0.9.1/lib/faraday_middleware/response/
parse_json.rb:  11:in `block in <class:ParseJson>'
…re-0.9.1/lib/faraday_middleware/
response_middleware.rb:  48:in `call'
…re-0.9.1/lib/faraday_middleware/
response_middleware.rb:  48:in `parse'
…re-0.9.1/lib/faraday_middleware/
response_middleware.rb:  39:in `process_response'
…re-0.9.1/lib/faraday_middleware/
response_middleware.rb:  32:in `block in call'
…/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/
response.rb:  57:in `on_complete'
…re-0.9.1/lib/faraday_middleware/
response_middleware.rb:  30:in `call'
…/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/
response.rb:   8:in `call'
…/ruby/2.1.0/gems/faraday-0.9.0/lib/faraday/
response.rb:   8:in `call'
…/gems/faraday-0.9.0/lib/faraday/request/
url_encoded.rb:  15:in `call'
….0/gems/faraday-0.9.0/lib/faraday/request/
multipart.rb:  14:in `call'
…ddleware-0.9.1/lib/faraday_middleware/request/
oauth.rb:  42:in `call'
…/desk-1.0.3/lib/faraday/request/
multipart_with_file.rb:  16:in `call'
…y/2.1.0/gems/faraday-0.9.0/lib/faraday/
rack_builder.rb: 139:in `build_response'
…uby/2.1.0/gems/faraday-0.9.0/lib/faraday/
connection.rb: 377:in `run_request'
…uby/2.1.0/gems/faraday-0.9.0/lib/faraday/
connection.rb: 140:in `get'
…/bundle/ruby/2.1.0/gems/desk-1.0.3/lib/desk/
request.rb:  51:in `request'
…/bundle/ruby/2.1.0/gems/desk-1.0.3/lib/desk/
request.rb:  18:in `method_missing'
…d/bundle/ruby/2.1.0/gems/desk-1.0.3/lib/desk/
client.rb: 137:in `block (2 levels) in setup_functions'
…n/shared/bundle/ruby/2.1.0/gems/desk-1.0.3/lib/

I have a high amount of requests going to Desk at the moment, so I'm sure I'm hitting the rate limit, but is this failure correct? That it's occurring in Faraday worries me. (If this is inappropriate for this project and needs to be moved to Faraday, just let me know and I'll move)

Output from Assistly requests

I think this is just a newbie question rather than an issue.

I have been able to update existing case records in desk.com using the
Assistly Ruby Gem but how do I see the output from a command like 'Assistly.users' ? I am using a Mac Airbook
with Terminal and sublime.

Thank you
Jim

Create customer failing?

Hey guys,

So trying a simple customer create:

Desk.create_customer(first_name: "Matt", last_name: "Person")

Fails with:

Desk::BadRequest: POST https://soundstreak.desk.com/api/v2/customers.json: 400

Is there an API change that needs to be applied?

Only a subset of results is being made available

The following code only returns the first 20 cases.

Desk.cases.results.each do | results |
  puts results.case
end

Is this a pagination issue? Should I be using different code? I'd appreciate any instructions on how to loop through all existing cases. Thanks!

./assistly.rb:6: uninitialized constant Assistly (NameError)

Forked Assistly code and used Git to clone it local. Assistly.rb is just the basic example file with authorization code and 2 sample commands.

require "rubygems"
require "assistly"

All methods require authentication. To get your Assistly OAuth credentials,

register an app in the Assistly admin for your account at http://your-domain.desk.com/admin

Assistly.configure do |config|
config.support_email = "jcalkins@ebara"
config.subdomain = "pump"
config.consumer_key = ""
config.consumer_secret = ""
config.oauth_token = ""
config.oauth_token_secret = ""
end
Assistly.case(1)
Assistly.update_case(1, :subject => "foo")

Error is below when I try: ruby assistly.rb
Thank you for the assistance.

./assistly.rb:6: uninitialized constant Assistly (NameError)
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in gem_original_require' from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:inrequire'
from assistly.rb:2

macbookair-eec2:assistly jcalkins$ gem list --local

*** LOCAL GEMS ***

actionmailer (3.2.3)
actionpack (3.2.3)
activemodel (3.2.3)
activerecord (3.2.3)
activeresource (3.2.3)
activesupport (3.2.3)
addressable (2.2.8)
arel (3.0.2)
assistly (0.2.6)
builder (3.0.0)
bundler (1.1.3)
coffee-rails (3.2.2)
coffee-script (2.2.0)
coffee-script-source (1.3.3)
erubis (2.7.0)
execjs (1.3.2)
faraday (0.7.6)
faraday_middleware (0.7.0)
hashie (1.2.0, 1.0.0)
hike (1.2.1)
i18n (0.6.0)
journey (1.0.3)
jquery-rails (2.0.2)
json (1.7.3)
mail (2.4.4)
mime-types (1.18)
multi_json (1.3.5, 1.0.4)
multi_xml (0.4.4)
multipart-post (1.1.5)
polyglot (0.3.3)
pony (1.4)
rack (1.4.1)
rack-cache (1.2)
rack-ssl (1.3.2)
rack-test (0.6.1)
rails (3.2.3)
railties (3.2.3)
rake (0.9.2.2)
rash (0.3.2)
rdoc (3.12)
rubygems-bundler (1.0.0)
rvm (1.11.3.3)
sass (3.1.18)
sass-rails (3.2.5)
simple_oauth (0.1.8)
sprockets (2.1.3)
sqlite3 (1.3.6)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
tzinfo (0.3.33)
uglifier (1.2.4)

Let me know if you need anything else

Jim

gem "hashie" issue

After adding "desk" gem to my Gemfile and runnin bundle install I get into below errors:

Bundler could not find compatible versions for gem "hashie":

In Gemfile:

desk (>= 0) ruby depends on
  hashie (~> 1.2.0) ruby

grape (>= 0) ruby depends on
  hashie (2.0.3)

Can "hashie" be upgraded to >= 2.0.3 ?

Invalid OAuth Request on all PUT Requests

Whenever I try to do anything involving a PUT (update_customer, update_case, etc...) I get an Invalid OAuth Request. Authentication is working for all other actions I've tried (POST & GET). Have you experienced something similar?

Problem with the Thread.current in the Configuration

We are using the gem in a rails application and since we have switched from Unicorn to Passenger we have noticed that our desk integration stopped working. We've pinned down the problem to the Desk::Configuration module where you assign the config values to the Thread.current. Do you have a reason to do so? If yes how can you overcome the limitations of using your gem in a multithreaded application?

'Invalid OAuth Request' with Resque

I am trying to run Desk.create_customer in Resque background process. I keep having the same result:

Exception     Faraday::Error::ParsingError
Error         757: unexpected token at 'Invalid OAuth Request'

Here is my Resque class:

require 'rubygems'
require 'json'
require 'desk'
require 'active_record'
require File.expand_path('../../../config/initializers/desk.rb', __FILE__)

class DeskApi
  @queue = :desk

  def self.perform(student_id)
    student = Student.includes(:contacts, :phones).find(student_id)
    attributes = {
      first_name: student.first_name,
      last_name: student.last_name,
      email: student.email,
      phone: student.order_phones_by_primary.first.number,
      extenal_id: student.id,
      custom_mycp_id: student.id,
      custom_other_emails: []
    }
    student.contacts.each do |c|
      attributes[:custom_other_emails] << c.email
    end
    Desk.create_customer(attributes)
  end
end

Running the sample in the console works, but not in the Resque worker. I'm at a loss as to why this is. Any suggestions?

pry(main) > Desk.create_customer(name: "Example Customer", email: "[email protected]"))

Copy-paste errors in ratelimit_remaining

    def ratelimit_limit
      @http_headers.values_at('x-ratelimit-limit', 'X-RateLimit-Limit').detect {|value| value }.to_i
    end

    def ratelimit_remaining
      @http_headers.values_at('x-ratelimit-limit', 'X-RateLimit-Limit').detect {|value| value }.to_i
    end

I think this is a copy-paste error - last strings should be 'x-ratelimit-remaining', 'X-RateLimit-Remaining'.

Faraday parsing errors even after #31

Even after the fixes set out in #31, I'm still getting Faraday::Error::ParsingError:

1.9.3-p545 :013 > results = Parallel.map((1000..100000), :in_threads=>30){|idx| Desk.case(idx) }
Faraday::Error::ParsingError: 757: unexpected token at 'Too Many Requests'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/json-1.8.1/lib/json/common.rb:155:in `parse'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/json-1.8.1/lib/json/common.rb:155:in `parse'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response/parse_json.rb:11:in `block in <class:ParseJson>'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:48:in `parse'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:39:in `process_response'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:32:in `block in call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:63:in `on_complete'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/response_middleware.rb:30:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:8:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/response.rb:8:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/request/url_encoded.rb:14:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/request/multipart.rb:13:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday_middleware-0.9.0/lib/faraday_middleware/request/oauth.rb:42:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/faraday/request/multipart_with_file.rb:16:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/connection.rb:253:in `run_request'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/faraday-0.8.9/lib/faraday/connection.rb:106:in `get'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/request.rb:51:in `request'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/request.rb:18:in `method_missing'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk/client/case.rb:18:in `show_case'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/desk-1.0.0/lib/desk.rb:25:in `method_missing'
    from (irb):13:in `block in irb_binding'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:389:in `call'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:389:in `call_with_index'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:229:in `block (3 levels) in work_in_threads'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:397:in `with_instrumentation'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:227:in `block (2 levels) in work_in_threads'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:221:in `loop'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:221:in `block in work_in_threads'
    from /home/vagrant/.rvm/gems/ruby-1.9.3-p545/gems/parallel-1.0.0/lib/parallel.rb:65:in `block (2 levels) in in_threads'1.9.3-p545 :014 > exit

Desk.insights_meta produces a 404

Using Desk.insights_meta produces a 404:

C:/Ruby200-x64/lib/ruby/2.0.0/json/common.rb:155:in `parse': 757: unexpected token at ' (Faraday::ParsingError) <title>404 - Page Not Found</title> <script type="text/javascript"> var headID = document.getElementsByTagName("head")[0]; var newScript = document.createElement('script'); newScript.type = 'text/javascript'; newScript.src = '//webassets.desk.com/assets/js/analytics/deskanalytics.js'; headID.appendChild(newScript); </script>
            <style>
                    body {
                            background: #f3f3f3;
                            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
                            margin: 0;
                            padding: 0;
                    }
                    #container { position: absolute; width: 100%; height: 100%; }
                    #page { position: relative; width: 100%; height: 100%; }
                    #box {
                            background: #FFF;
                            border: 1px solid #CDCDCD;
                            width: 700px;
                            height: 300px;
                            position: absolute;
                            text-align: center;
                            top: 50%;
                            left: 50%;
                            margin: -200px 0 0 -350px;
                            -moz-border-radius: 5px;
                            -webkit-border-radius: 5px;
                    }
                    #box h1 {
                            font-size: 37px;
                            margin: 65px 0 0;
                    }
                    #box p {
                            color: #888;
                            font-size: 19px;
                            margin: 0;
                    }
                    #box a {
                            background: url("http://webassets.desk.com/new/images/buttons/homepage.png") 0 0 no-repeat;
                            display: block;
                            margin: 50px auto 0;
                            width: 184px;
                            height: 39px;
                            text-indent: -9000px;
                            overflow: hidden;
                    }
                    #box a:hover {
                            background-position: 0 -39px;
                    }
            </style>
    </head>
    <body>
            <div id="container">
                    <div id="page">
                            <div id="box">
                                    <h1>Sorry, we couldn't find that page.</h1>
                                    <p>Maybe it was moved, deleted, or you accidentally mistyped the URL.</p>
                                    <a href="/">Go to Homepage</a>
                            </div>
                    </div>
            </div>
    </body>
' from C:/Ruby200-x64/lib/ruby/2.0.0/json/common.rb:155:in `parse' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response/parse_json.rb:11:in`block in class:ParseJson' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:48:in `call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:48:in`parse' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:39:in `process_response' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:32:in`block in call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/response.rb:57:in `on_complete' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday_middleware-0.9.2/lib/faraday_middleware/response_middleware.rb:30:in`call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/response.rb:8:in`call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/request/url_encoded.rb:15:in `call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/request/multipart.rb:14:in`call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/desk-1.0.8/lib/faraday/request/multipart_with_file.rb:16:in `call' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:139:in`build_response' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/connection.rb:377:in `run_request' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/faraday-0.9.2/lib/faraday/connection.rb:140:in`get' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/desk-1.0.8/lib/desk/request.rb:51:in `request' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/desk-1.0.8/lib/desk/request.rb:18:in`method_missing' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/desk-1.0.8/lib/desk/client/insight.rb:6:in `show_insights_meta' from C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/desk-1.0.8/lib/desk.rb:25:in`method_missing' from C:/xampp/htdocs/desk/cases.rb:84:in `show_insights'

https://gist.github.com/cshimvin/85b5a7a86d2c85fb3752fba736c75607

Incompatible hashie versions when bundled alongside Omniauth 1.0.1

Bundling the Assistly gem alongside Omniauth 1.0.1 results in the following Bundler error:

Bundler could not find compatible versions for gem "hashie":
  In Gemfile:
    assistly (>= 0) ruby depends on
      hashie (~> 1.0.0) ruby

    omniauth (= 1.0.1) ruby depends on
      hashie (1.2.0)

I've forked the Assistly gem and set the hashie dependency version to an explicit '= 1.2.0' and that fixed it, but I don't think that's worthy of a pull request :).

Figured I'd report it in case others had a similar issue.

Cheers,

T.J.

Incorrect from/reply_to address

I am unsure if this is an API issue - I believe it may be a Desk issue - but I'm posting here just in case.

We interact with Desk via the Rails API and have an issue when creating email cases. In short, the emails are always sent using the default outbound mailbox in the account.

The case in Desk shows the correct 'from' address (as provided by the code via the API) but has the 'reply to' address as the default email for the account. However, when the email arrives, it has actually be sent using the default outbound mailbox and therefore both the 'from' and the 'reply to' address are the email from the default outbound mailbox account.

The 'from' address is being set correctly and the rules on the account should therefore specify which outbound mailbox to use, so either the rules are being ignored or there is another way to set the mailbox which I am missing.

I have tried:

  • explicitly setting a 'reply_to' address
  • setting 'suppress_rules' to false
  • putting the 'outbound_mailbox' as a '_link'

I believe this did work correctly in the past, however I may be mistaken there.

Any help would be appreciated.

Unable to activate rash-0.3.2, because hashie-1.0.0 conflicts with hashie (~> 1.2.0)

macbookair-eec2:assistly jcalkins$ ruby assistly-test.rb
/Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:1637:in raise_if_conflicts': Unable to activate rash-0.3.2, because hashie-1.0.0 conflicts with hashie (~> 1.2.0) (Gem::LoadError)
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:746:inactivate'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:780:in activate_dependencies'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:766:ineach'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:766:in activate_dependencies'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/specification.rb:750:inactivate'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems.rb:212:in try_activate'
from /Users/jcalkins/.rvm/rubies/ruby-1.8.7-p248/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:59:inrequire'
from assistly-test.rb:2

*** LOCAL GEMS ***

actionmailer (3.2.3)
actionpack (3.2.3)
activemodel (3.2.3)
activerecord (3.2.3)
activeresource (3.2.3)
activesupport (3.2.3)
addressable (2.2.8)
arel (3.0.2)
assistly (0.2.6)
builder (3.0.0)
bundler (1.1.3)
coffee-rails (3.2.2)
coffee-script (2.2.0)
coffee-script-source (1.3.3)
erubis (2.7.0)
execjs (1.3.2)
faraday (0.7.6)
faraday_middleware (0.7.0)
hashie (1.2.0, 1.0.0)
hike (1.2.1)
i18n (0.6.0)
journey (1.0.3)
jquery-rails (2.0.2)
json (1.7.3)
mail (2.4.4)
mime-types (1.18)
multi_json (1.3.5, 1.0.4)
multi_xml (0.4.4)
multipart-post (1.1.5)
polyglot (0.3.3)
pony (1.4)
rack (1.4.1)
rack-cache (1.2)
rack-ssl (1.3.2)
rack-test (0.6.1)
rails (3.2.3)
railties (3.2.3)
rake (0.9.2.2)
rash (0.3.2)
rdoc (3.12)
rubygems-bundler (1.0.0)
rvm (1.11.3.3)
sass (3.1.18)
sass-rails (3.2.5)
simple_oauth (0.1.8)
sprockets (2.1.3)
sqlite3 (1.3.6)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
tzinfo (0.3.33)
uglifier (1.2.4)

From an email I was told I need to update the gem to use hashie 1.2.0. Can someone give me some direction on how to do this?

Jim

Bug when creating articles

When creating articles through your desk API, articles were created as drafts and couldn't be seen on support center even when I explicitly added :in_support_center. I had to login and manually remove the draft attribute. This bug prevents automation when creating articles.

My API usage example:

Desk.create_article(
  :subject => "subject",
  :body => "body",
  :in_support_center => true,
  :links => {
    :topic => {
       :href => "/api/v2/topics/1",
       :class => "topic"
  }
})

One last release of assistly

A friend of mine got confused trying to install the assistly gem today.

Could you release one last time with a gem dependency on desk or a big fat warning message?

401 "Unauthorised" on all requests.

Hi Guys,
Every time I try and access the assitly API through the gem, it throws me out with a 401 unauthorised.
I wrote a small script to test with, to ensure OAuth itself was working. I assume there's something perhaps not working 100% when it gets through to faraday, but I can't be sure.

Test Code:

http://pastie.org/private/yhbgdqfgpgxutbmjwm2pqw

Output:

$ ../script/runner  -f assitly_gem_test.rb 

ERROR: HTTP 401 thrown
--
#<Net::HTTPOK 200 OK readbody=true>

Installed gems:

# gem list --local

*** LOCAL GEMS ***

abstract (1.0.0)
actionmailer (3.0.9, 2.3.14, 2.3.8)
actionpack (3.0.9, 2.3.14, 2.3.8)
activemodel (3.0.9)
activerecord (3.0.9, 2.3.14, 2.3.8)
activeresource (3.0.9, 2.3.14, 2.3.8)
activesupport (3.0.9, 2.3.14, 2.3.8)
addressable (2.2.6)
adzap-ar_mailer (2.1.5)
archive-tar-minitar (0.5.2)
arel (2.0.10)
assistly (0.2.6, 0.2.4)
builder (2.1.2)
bundler (1.0.17)
calendar_date_select (1.15)
daemon_controller (0.2.6)
erubis (2.6.6)
faraday (0.7.5, 0.6.1)
faraday_middleware (0.7.0, 0.6.5)
fastercsv (1.5.3)
fastthread (1.0.7)
file-tail (1.0.4)
gemcutter (0.4.1)
hashie (1.1.0, 1.0.0)
hoe (2.5.0)
hpricot (0.8.2)
i18n (0.5.0, 0.4.1)
json_pure (1.5.3, 1.2.2)
mail (2.2.19)
mime-types (1.16)
mini_magick (1.2.5)
multi_json (1.0.3, 0.0.5)
multi_xml (0.4.1, 0.2.2)
multipart-post (1.1.3)
mysql (2.8.1)
nokogiri (1.4.1, 1.3.3)
oauth (0.4.5)
passenger (3.0.8, 2.2.5)
pg (0.8.0)
polyglot (0.3.2)
pony (1.3)
rack (1.3.2, 1.2.3, 1.1.2)
rack-mount (0.6.14)
rack-test (0.5.7)
rails (3.0.9, 2.3.14, 2.3.8)
railties (3.0.9)
rake (0.9.2, 0.8.7)
rash (0.3.0)
rcov (0.9.8)
rdoc (3.9.1)
redbox (1.0.4)
rest-client (1.4.0)
rt-client (0.2.2)
ruby-ldap (0.9.11)
ruby-net-ldap (0.0.4)
rubyforge (2.0.4, 2.0.3)
simple_oauth (0.1.5)
snmp (1.0.3)
sqlite3-ruby (1.2.5)
thor (0.14.6)
tmail (1.2.7.1)
treetop (1.4.10)
tzinfo (0.3.29)
validates_timeliness (2.3.1)
xeroizer (0.3.5)
xml-simple (1.0.12)
yajl-ruby (1.0.0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.