Giter Club home page Giter Club logo

zendesk_api_client_rb's Introduction

Zendesk API Client

Test Gem Version Code Climate

Documentation

This Ruby gem is a generic wrapper around Zendesk's REST API. Follow this README and the wiki for how to use it.

You can interact with all the resources defined in resources.rb. Basically we have some cleaver code to convert Ruby objects into HTTP requests.

Please refer to our API documentation for the specific endpoints and once you understand the mapping between Ruby and the HTTP endpoints you should be able to call any endpoint.

The Yard generated documentation is available in at RubyDoc.

Please report any bug in the Github issues page.

You might want to try out this gem in a REPL for exploring your options, if so, check out this project.

Product Support

This Ruby gem supports the REST API's for Zendesk Support, Zendesk Guide, and Zendesk Talk. It does not yet support other Zendesk products such as Zendesk Chat, Zendesk Explore, and Zendesk Sell.

Installation

The Zendesk API client can be installed using Rubygems or Bundler.

Rubygems

gem install zendesk_api

Bundler

Add it to your Gemfile

gem "zendesk_api"

Then bundle as usual.

Configuration

Configuration is done through a block returning an instance of ZendeskAPI::Client.

require 'zendesk_api'

client = ZendeskAPI::Client.new do |config|
  # Mandatory:

  config.url = "<- your-zendesk-url ->" # e.g. https://yoursubdomain.zendesk.com/api/v2

  # Basic / Token Authentication
  config.username = "[email protected]"

  # Choose one of the following depending on your authentication choice
  # More information on obtaining API tokens can be found here:
  # https://developer.zendesk.com/api-reference/introduction/security-and-auth/#api-token
  config.token = "your zendesk token"

  # OAuth Authentication
  # More information on obtaining OAuth access tokens can be found here:
  # https://developer.zendesk.com/api-reference/introduction/security-and-auth/#oauth-access-token
  config.access_token = "your OAuth access token"

  # Optional:

  # Retry uses middleware to notify the user
  # when hitting the rate limit, sleep automatically,
  # then retry the request.
  config.retry = true

  # Raise error when hitting the rate limit.
  # This is ignored and always set to false when `retry` is enabled.
  # Disabled by default.
  config.raise_error_when_rate_limited = false

  # Logger prints to STDERR by default, to e.g. print to stdout:
  require 'logger'
  config.logger = Logger.new(STDOUT)

  # Disable resource cache (this is enabled by default)
  config.use_resource_cache = false

  # Changes Faraday adapter
  # config.adapter = :patron

  # Merged with the default client options hash
  # config.client_options = {:ssl => {:verify => false}, :request => {:timeout => 30}}

  # When getting the error 'hostname does not match the server certificate'
  # use the API at https://yoursubdomain.zendesk.com/api/v2

  # Change retry configuration (this is disabled by default)
  config.retry_on_exception = true

  # Error codes when the request will be automatically retried. Defaults to 429, 503
  config.retry_codes = [ 429 ]
end

Usage

The result of configuration is an instance of ZendeskAPI::Client which can then be used in two different methods.

One way to use the client is to pass it in as an argument to individual classes.

Note: all method calls ending in ! will raise an exception when an error occurs, see the wiki page for more info.

ZendeskAPI::Ticket.new(client, :id => 1, :priority => "urgent") # doesn't actually send a request, must explicitly call #save!

ZendeskAPI::Ticket.create!(client, :subject => "Test Ticket", :comment => { :value => "This is a test" }, :submitter_id => client.current_user.id, :priority => "urgent")
ZendeskAPI::Ticket.find!(client, :id => 1)
ZendeskAPI::Ticket.destroy!(client, :id => 1)

You can also update ticket objects.

ticket = ZendeskAPI::Ticket.find!(client, :id => 1)
ticket.update(:comment => { :value => "This is a test reply." })

ticket.save!

Another way is to use the instance methods under client.

client.tickets.first
client.tickets.find!(:id => 1)
client.tickets.build(:subject => "Test Ticket")
client.tickets.create!(:subject => "Test Ticket", :comment => { :value => "This is a test" }, :submitter_id => client.current_user.id, :priority => "urgent")
client.tickets.destroy!(:id => 1)

The methods under ZendeskAPI::Client (such as .tickets) return an instance of ZendeskAPI::Collection, a lazy-loaded list of that resource. Actual requests may not be sent until an explicit ZendeskAPI::Collection#fetch!, ZendeskAPI::Collection#to_a!, or an applicable methods such as #each.

Caveats

Resource updating is implemented by sending only the changed? attributes to the server (see ZendeskAPI::TrackChanges). Unfortunately, this module only hooks into Hash meaning any changes to an Array not resulting in a new instance will not be tracked and sent.

zendesk_api_client_rb $ bundle console
> a = ZendeskAPI::Trackie.new(:test => []).tap(&:clear_changes)
> a.changed?(:test)
 => false
> a.test << "hello"
 => ["hello"]
> a.changed?(:test)
 => false
> a.test += %w{hi}
 => ["hello", "hi"]
> a.changed?(:test)
 => true

Pagination

ZendeskAPI::Collections can be paginated:

# Note that CBP (cursor based pagination) is the default and preferred way
# and has fewer limitations on deep pagination
tickets = client.tickets.per_page(3)
page1 = tickets.fetch! # GET /api/v2/tickets?page[after]={cursor}&page[size]=3
page2 = tickets.next # GET /api/v2/tickets?page[after]={cursor}&page[size]=3
# ...

# OR...
# Note that OBP (offset based pagination) can incur to various limitations
tickets = client.tickets.page(2).per_page(3)

next_page = tickets.next # => 3
tickets.fetch! # GET /api/v2/tickets?page=3&per_page=3
previous_page = tickets.prev # => 2
tickets.fetch! # GET /api/v2/tickets?page=2&per_page=3

Iteration over all resources and pages is handled by Collection#all:

client.tickets.all! do |resource|
  # every resource, from all pages, will be yielded to this block
end

If given a block with two arguments, the page number is also passed in.

client.tickets.all! do |resource, page_number|
  # all resources will be yielded along with the page number
end

Cursor Based Pagination

A few endpoints related to organizations, tickets, triggers and groups will now make use of cursor based pagination by default. It is also recommended to use CBP whenever the Zendesk developer documentation says it's supported. Pass page[size]=number in the parameters to attempt a CBP request, like the example below:

client.connection.get('/api/v2/suspended_tickets', page: { size: 100 }).body
{"suspended_tickets"=>[...], "meta"=>{"has_more"=>true, "after_cursor"=>" ... ", "before_cursor"=>nil}, "links"=>{"prev"=>nil, "next"=>"..."}}

Callbacks

Callbacks can be added to the ZendeskAPI::Client instance and will be called (with the response env) after all response middleware on a successful request.

client.insert_callback do |env|
  puts env[:response_headers]
end

Resource management

Individual resources can be created, modified, saved, and destroyed.

ticket = client.tickets[0] # ZendeskAPI::Ticket.find(client, :id => 1)
ticket.priority = "urgent"
ticket.attributes # => { "priority" => "urgent" }
ticket.save! # Will PUT => true
ticket.destroy! # => true

ZendeskAPI::Ticket.new(client, { priority: "urgent" })
ticket.new_record? # => true
ticket.save! # Will POST

Side-loading

To facilitate a smaller number of requests and easier manipulation of associated data we allow "side-loading," or inclusion, of selected resources.

For example: A ZendeskAPI::Ticket is associated with ZendeskAPI::User through the requester_id field. API requests for that ticket return a structure similar to this:

"ticket": {
  "id": 1,
  "url": "http.....",
  "requester_id": 7,
  ...
}

Calling ZendeskAPI::Ticket#requester automatically fetches and loads the user referenced above (/api/v2/users/7). Using side-loading, however, the user can be partially loaded in the same request as the ticket.

tickets = client.tickets.include(:users)
# Or client.tickets(:include => :users)
# Does *NOT* make a request to the server since it is already loaded
tickets.first.requester # => #<ZendeskAPI::User id=...>

# OR

ticket = client.tickets.find!(:id => 1, :include => :users)
ticket.requester # => #<ZendeskAPI::User id=...>

Currently, this feature is limited to only a few resources and their associations. They are documented on developer.zendesk.com.

Recommended Approach

For better control over your data and to avoid large response sizes, consider fetching related resources explicitly. This approach can help you manage data loading more precisely and can lead to optimized performance for complex applications.

ticket = ZendeskAPI::Ticket.find(id: 1)
requester = ZendeskAPI::User.find(id: ticket.requester_id)

By explicitly fetching associated resources, you can ensure that your application only processes the data it needs, improving overall efficiency.

Omnichannel

Support for the Agent Availability API

An agent’s availability includes their state (such as online) for each channel (such as messaging), and their unified state across channels. It also includes the work items assigned to them.

# All agent availabilities
client.agent_availabilities.fetch

# fetch availability for one agent, their channels and work items
agent_availability = ZendeskAPI::AgentAvailability.find(client, 386390041152)
agent_availability.channels
agent_availability.channels.first.work_items

# Using the agent availability filter
ZendeskAPI::AgentAvailability.search(client, { select_channel: 'support' })
ZendeskAPI::AgentAvailability.search(client, { channel_status: 'support:online' })

Search

Searching is done through the client. Returned is an instance of ZendeskAPI::Collection:

client.search(:query => "my search query") # /api/v2/search.json?query=...
client.users.search(:query => "my new query")  # /api/v2/users/search.json?query=...

Special case: Custom resources paths

API endpoints such as tickets/recent or topics/show_many can be accessed through chaining. They will too return an instance of ZendeskAPI::Collection.

client.tickets.recent
client.topics.show_many(:verb => :post, :ids => [1, 2, 3])

Special Case: Current user

Use either of the following to obtain the current user instance:

client.users.find!(:id => 'me')
client.current_user

Special Case: Importing a ticket

Bulk importing tickets allows you to move large amounts of data into Zendesk.

ticket = ZendeskAPI::Ticket.import(client, :subject => "Help", :comments => [{ :author_id => 19, :value => "This is a comment" }])

Further documentation can be found on developer.zendesk.com

Attaching files

Files can be attached to ticket comments using either a path or the File class and will be automatically uploaded and attached.

ticket = ZendeskAPI::Ticket.new(client, :comment => { :value => "attachments" })
ticket.comment.uploads << "img.jpg"
ticket.comment.uploads << File.new("img.jpg")
ticket.save!

Apps API

v1.1.0 introduces support for the Zendesk Apps API

Creating Apps

upload = client.apps.uploads.create!(:file => "path/to/app.zip")
client.apps.create!(:name => "test", :upload_id => upload.id)

# Or

app = ZendeskAPI::App.new(client, :name => "test")
app.upload = "path/to/app.zip"
app.save!

# Or

upload = ZendeskAPI::App::Upload.new(client, :file => "path/to/app.zip")
upload.save!

app = ZendeskAPI::App.new(client, :name => "test")
app.upload_id = upload.id
app.save!

# Or

client.apps.create!(:name => "test", :upload => "app.zip")

Note: job statuses are currently not supported, so you must manually poll the job status API for app creation.

body = {}
until %w{failed completed}.include?(body["status"])
  response = client.connection.get(app.response.headers["Location"])
  body = response.body

  sleep(body["retry_in"])
end

Updating Apps

upload = client.apps.uploads.create!(:file => "NewApp.zip")

# Then

client.apps.update!(:id => 123, :upload_id => upload.id)

# Or

app = ZendeskAPI::App.new(client, :id => 123)
app.upload_id = upload.id
app.save!

# Or

ZendeskAPI::App.update!(client, :id => 123, :upload_id => upload.id)

Deleting Apps

client.apps.destroy!(:id => 123)

app = ZendeskAPI::App.new(client, :id => 123)
app.destroy!

ZendeskAPI::App.destroy!(client, :id => 123)

Installing an App

Installation name is required

installation = ZendeskAPI::AppInstallation.new(client, :app_id => 123, :settings => { :name => 'Name' })
installation.save!

# or

client.apps.installations.create!(:app_id => 123, :settings => { :name => 'Name' })

# or

ZendeskAPI::AppInstallation.create!(client, :app_id => 123, :settings => { :name => 'Name' })

List Installations

apps = client.app.installations
apps.fetch!

Update Installation

client.app.installations.update!(:id => 123, :settings => { :title => "My New Name" })

installation = ZendeskAPI::AppInstallation.new(client, :id => 123)
installation.settings = { :title => "My New Name" }
installation.save!

ZendeskAPI::AppInstallation.update!(client, :id => 123, :settings => { :title => "My New Name" })

Delete Installation

client.app.installations.destroy!(:id => 123)

installation = ZendeskAPI::AppInstallation.new(client, :id => 123)
installation.destroy!

ZendeskAPI::AppInstallation.destroy!(client, :id => 123)

Running the gem locally

See .github/workflows/main.yml to understand the CI process.

bundle exec rake # Runs the tests
bundle exec rubocop # Runs the lint (use `--fix` for autocorrect)

Releasing a new gem version

  1. From updated master: git checkout -b bump-vX.X.X, according to SemVer
  2. Ensure the CHANGELOG is correct and updated, this is your last opportunity
  3. Execute bundle exec bump:patch # minor|major, this bumps the version in a new commit, and adds the relative git tag
  4. Push to GitHub git push origin vX.X.X -u && git push --tags
  5. Raise a PR (example) including the code diff (example)
  6. Get it approved and merged
  7. Post a message in Slack #rest-api (example TODO), so advocacy are aware that we are going to release a new gem, just in case any customer complains about something related to the gem
  8. After 2 hours from the above message, you can approve the release of the gem

Contributing

  1. Fork the project.
  2. Make your feature addition or bug fix.
  3. Add tests for it. This is important so that we don't break it in a future version unintentionally.
  4. Commit. Do not alter Rakefile, version, or history. (If you want to have your own version, that is fine, but bump version in a commit by itself that we can ignore when we pull.)
  5. Submit a pull request.

Note: Live specs will likely fail for external contributors. The Zendesk devs can help with that. If you have permissions and some live specs unexpectedly fail, that might be a data error, see the REPL for that.

Merging contributors pull requests

External contributions don't run live specs, so we need to use a workaround. Assuming a PR from author:author/branch to default_branch:

  1. Create a branch in our repo author_branch
  2. Change the destination branch of the PR to author_branch
  3. Merge
  4. Create a pr in our repo from default_branch
    • Make sure they know the commits still carry their name
    • Example

Copyright and license

Copyright 2015-2023 Zendesk

See LICENSE.

zendesk_api_client_rb's People

Contributors

adammw avatar andreionut avatar bquorning avatar ciaranarcher avatar codealchemy avatar cryptomail avatar dlee avatar dugjason avatar ecoologic avatar elaineoc avatar fbvilela avatar gabetax avatar ggrossman avatar grosser avatar jbdietrich avatar jinhuangatzen avatar johannesengl avatar nakulpathak3 avatar nhat-zendesk avatar nickfz3n avatar nogates avatar orien avatar otoyo avatar pschambacher avatar sandlerr avatar shanitang avatar staugaard avatar steved avatar wpeterson avatar yoihito 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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zendesk_api_client_rb's Issues

ruby gem isn't up to date

Github version is 0.1.0 while rubygem is still 0.0.9
This is critical because the attachment fix is included in 0.1.0

ZendeskAPI is not missing constant User!

I just installed the gem on a new project and now the app won't load. Running Rails 3.0.10.

I get this error:

/Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:479:in `load_missing_constant': ZendeskAPI is not missing constant User! (ArgumentError)
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:183:in `const_missing_not_from_s3_library'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:181:in `each'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:181:in `const_missing_not_from_s3_library'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/aws-s3-0.6.2/lib/aws/s3/extensions.rb:206:in `const_missing'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/association.rb:233:in `const_get'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/association.rb:233:in `get_class'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/association.rb:120:in `has'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/resources/misc.rb:4
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:593:in `new_constants_in'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:2
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:593:in `new_constants_in'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api/client.rb:7
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:593:in `new_constants_in'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:225:in `load_dependency'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/activesupport-3.0.10/lib/active_support/dependencies.rb:239:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/zendesk_api-0.0.9/lib/zendesk_api.rb:7
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:68:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `each'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:66:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `each'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler/runtime.rb:55:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/bundler-1.1.5/lib/bundler.rb:119:in `require'
    from /Users/gregdevore/Rails/screensteps_live/config/application.rb:7
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/railties-3.0.10/lib/rails/commands.rb:21:in `require'
    from /Users/gregdevore/.rvm/gems/ruby-1.8.7-p352/gems/railties-3.0.10/lib/rails/commands.rb:21
    from script/rails:6:in `require'
    from script/rails:6

Works but display tons of 404s ?

Hello,

I started playing with the gem, It seems to work as I successfully created a user and a ticket but I keep getting lot's of 404 in my rails console.

Anyone know what's up with that ?

ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:42:in `block in save_associations'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:40:in `each'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:40:in `save_associations'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:20:in `save'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/rescue.rb:26:in `block (2 levels) in rescue_client_error'
/home/pate/something/git/rails_site/bazaar/lib/zendesk/client.rb:26:in `create_ticket'
(pry):45:in `<main>'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:249:in `eval'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:249:in `re'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:227:in `rep'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:207:in `block (3 levels) in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:206:in `loop'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:206:in `block (2 levels) in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:205:in `catch'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:205:in `block in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:204:in `catch'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:204:in `repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_class.rb:139:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'
    {"error"=>"RecordNotFound", "description"=>"Not found"}
the server responded with status 404
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/response/raise_error.rb:6:in `on_complete'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/response.rb:9:in `block in call'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/response.rb:63:in `on_complete'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/request/authorization.rb:36:in `call'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in `run_request'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/faraday-0.8.1/lib/faraday/connection.rb:87:in `get'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/association.rb:145:in `block (2 levels) in has'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/rescue.rb:35:in `rescue_client_error'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/association.rb:144:in `block in has'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:42:in `block in save_associations'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:40:in `each'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:40:in `save_associations'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/actions.rb:20:in `save'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/bundler/gems/zendesk_api_client_rb-497c1c8dae6f/lib/zendesk_api/rescue.rb:26:in `block (2 levels) in rescue_client_error'
/home/pate/something/git/rails_site/bazaar/lib/zendesk/client.rb:26:in `create_ticket'
(pry):45:in `<main>'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:249:in `eval'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:249:in `re'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:227:in `rep'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:207:in `block (3 levels) in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:206:in `loop'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:206:in `block (2 levels) in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:205:in `catch'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:205:in `block in repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:204:in `catch'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_instance.rb:204:in `repl'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/pry-0.9.9.6/lib/pry/pry_class.rb:139:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
/home/pate/.rvm/gems/ruby-1.9.3-p194@bazaar/gems/railties-3.2.2/lib/rails/commands.rb:41:in `<top (required)>'
script/rails:6:in `require'
script/rails:6:in `<main>'
    "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />\n  <title>The page you were looking for doesn't exist (404)</title>\n  <link href=\"/external/error_pages.css\" media=\"all\" rel=\"stylesheet\" type=\"text/css\" />\n</head>\n\n<body>\n  <!-- This file lives in public/404.html -->\n  <div class=\"dialog\">\n    <div id=\"contents\">\n      <h1>Oops.<br/>The page you were looking for doesn't exist.</h1>\n      <div class=\"box home\">\n        <p>You may have mistyped the address or the page may have moved.</p>\n        <ul><li><a href=\"/\">Take me back to the home page</a></li></ul>\n      </div>\n    </div>\n  </div>\n</body>\n</html>\n"
=> true

RuntimeError: missing dependency for Faraday::Adapter::Patron: no such file to load -- patron

I was able to configure a client, but when I try to access a topic, I get a following error
client.topics.find(:id =>'21472643')
RuntimeError: missing dependency for Faraday::Adapter::Patron: no such file to load -- patron
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/middleware.rb:20:in new' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:43:inbuild'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from (irb):57:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in each' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:74:inapp'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in run_request' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:87:inget'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/actions.rb:69:in orig_find' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:insend'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in find' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:62:infind'
from (irb):57

this error happens when I call a find in other collections:

client.users.find(:id => '217679681')
RuntimeError: missing dependency for Faraday::Adapter::Patron: no such file to load -- patron
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/middleware.rb:20:in new' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:43:inbuild'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from (irb):32:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in each' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:74:inapp'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in run_request' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:87:inget'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/actions.rb:69:in orig_find' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:insend'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in find' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:62:infind'
from (irb):32
client.tickets[2]
RuntimeError: missing dependency for Faraday::Adapter::Patron: no such file to load -- patron
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/middleware.rb:20:in new' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:43:inbuild'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from (irb):44:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in each' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:74:inapp'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in run_request' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:87:inget'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:146:in send' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:146:inorig_fetch'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in send' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:infetch'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:163:in to_a' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:216:inmethod_missing'
from (irb):44>> client.tickets.first
RuntimeError: missing dependency for Faraday::Adapter::Patron: no such file to load -- patron
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/middleware.rb:20:in new' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:43:inbuild'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from (irb):45:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in each' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:ininject'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/builder.rb:78:in to_app' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:74:inapp'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in run_request' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/faraday-0.8.1/lib/faraday/connection.rb:87:inget'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:146:in send' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:146:inorig_fetch'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in send' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:infetch'
from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:163:in to_a' from /Users/naoyamakino/.rvm/gems/ree-1.8.7-2011.03@themis/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:216:inmethod_missing'

do you have any idea why this happens?
I appreciate your help and thanks for working on this.
regards

IOError: not opened for reading

Hi,

Thank you for a cool gem. I managed to fetch ticket, but to create one. I am getting this error with this configuration:

@client = Zendesk.configure do |config|
# Mandatory:

# Must be https URL unless it is localhost or 127.0.0.1
  config.url = params[:url]

  config.username = params[:username]
  config.password = params[:password]

  # Optional:

  # Retry uses middleware to notify the user
  # when hitting the rate limit, sleep automatically,
  # then retry the request.
  config.retry = true
  # Logger prints to STDOUT by default
  config.logger = true
  # Logger prints out requests to STDERR
  require 'logger'
  config.logger = Logger.new(STDERR)
  # Changes Faraday adapter
  # config.adapter = :net_http

  # Merged with the default client options hash
  # config.client_options = { :ssl => true }

# When getting the error 'hostname does not match the server certificate'
# use the API at https://yoursubdomain.zendesk.com/api/v2
end

Zendesk::Ticket.create(client, :subject => "Test Ticket", :description => "This is a test", :submitter_id => client.me.id, :priority => "urgent")
post https://zaloraindonesia1338549562.zendesk.com/api/v2/tickets
Accept: "application/json"
Accept-Encoding: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
User-Agent: "Zendesk API 0.0.4"
Authorization: "Basic ZmZpcmRhdXNAemFsb3JhLmNvLmlkOlBAc3N3MHJk"
IOError: not opened for reading
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:207:in each' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:207:into_a'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:207:in as_json' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:55:inblock in as_json'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:77:in check_for_circular_references' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:54:inas_json'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:242:in block in as_json' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:242:ineach'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:242:in map' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:242:inas_json'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:47:in block in encode' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:77:incheck_for_circular_references'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:46:in encode' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:252:inblock in encode_json'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:252:in each' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.3/lib/active_support/json/encoding.rb:252:inmap'
... 48 levels...
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:8:in call' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response/logger.rb:20:incall'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:8:in call' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/response.rb:8:incall'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in run_request' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.1/lib/faraday/connection.rb:99:inpost'
from /usr/local/rvm/gems/ruby-1.9.3-p194/bundler/gems/zendesk_api_client_rb-8314bc2e174e/lib/zendesk/actions.rb:38:in save' from /usr/local/rvm/gems/ruby-1.9.3-p194/bundler/gems/zendesk_api_client_rb-8314bc2e174e/lib/zendesk/rescue.rb:10:inblock (2 levels) in rescue_client_error'
from /usr/local/rvm/gems/ruby-1.9.3-p194/bundler/gems/zendesk_api_client_rb-8314bc2e174e/lib/zendesk/actions.rb:82:in create' from /usr/local/rvm/gems/ruby-1.9.3-p194/bundler/gems/zendesk_api_client_rb-8314bc2e174e/lib/zendesk/rescue.rb:10:inblock (2 levels) in rescue_client_error'
from (irb):2
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands/console.rb:47:in start' from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands/console.rb:8:instart'
from /usr/local/rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.3/lib/rails/commands.rb:41:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'1.9.3p194 :003 >

Slight alteration to README

You say to add this into the gemfile

gem "zendesk", :git => "git://github.com/zendesk/zendesk_api_client_rb.git"

When it should probably be more like this

gem "zendesk", :git => "git://github.com/zendesk/zendesk_api_client_rb.git", :tag => 'v0.0.1'

Semantics, but it allows for us to rely on your releases to be consistent

5 Failing tests on ree and 1.9.3

bundle exec rake
Failed examples:

rspec ./spec/collection_spec.rb:181 # Zendesk::Collection with real data pagination with no options should find the next page by calling fetch
rspec ./spec/collection_spec.rb:189 # Zendesk::Collection with real data pagination with no options should find the prev page by calling fetch
rspec ./spec/collection_spec.rb:201 # Zendesk::Collection with real data pagination with options should increase page option and not call fetch
rspec ./spec/collection_spec.rb:205 # Zendesk::Collection with real data pagination with options should decrease page option and not call fetch
rspec ./spec/collection_spec.rb:216 # Zendesk::Collection with real data pagination with options with page == 1 should do nothing on #prev
rake aborted!

Issues with multipart in rails app

I'm unable to post a ticket in my rails app. Here's a gist with all the information I could get:
https://gist.github.com/4017925

I am able to post the ticket if I edit lib/zendesk_api/client.rb and comment out builder.request :multipart. Of course that's no solution, because it would break file uploads.

TicketFields not being destroyed

So I'm attempting to wipeout my ticket fields for an acc, but it doesn't seem to be working.
I've copied the console session below, any ideas?

Sorry for being so vague, not sure how else to phrase this.

Loading development environment (Rails 3.2.11)
[1] pry(main)> ZendeskClient.instance.ticket_fields.to_a.size
=> 7
[2] pry(main)> ZendeskClient.instance.ticket_fields.to_a.each {|f| f.destroy }; nil
=> nil
[3] pry(main)> ZendeskClient.instance.ticket_fields.to_a.each {|f| puts f.destroyed? }; nil
true
true
true
true
true
true
true
=> nil
[4] pry(main)> ^D
robertross:~/Sites/someapp (master) $ rails c
Loading development environment (Rails 3.2.11)
[1] pry(main)> ZendeskClient.instance.ticket_fields.to_a.each {|f| puts f.destroyed? }; nil
false
false
false
false
false
false
false
=> nil
[2] pry(main)> 

Persistent caching

Is there any plan to add persistent caching to this gem? Or, is it already supported, and I've just missed it?

For our use, it would be ok (even good) to very aggressively cache API responses. We're calculating some stats for a dashboard that require us to load several months worth of tickets for each client. However, it's not important that the stats are live -- they can be a bit out of date. So we could cache all that stuff for a week or so. This would massively reduce the number of requests we need to make as well as making our dashboard much quicker.

Any tips?

Is search supported?

From what I can figure out, it looks like methods correspond to URLs, with some intelligence/guessing:

# the query option is silently dropped
# https://github.com/zendesk/zendesk_api_client_rb/issues/47 maybe?
> $zendesk.ticket(query: 'moon').first
get https://juniper.zendesk.com/api/v2/tickets

# typos are passed to ZenDesk API
> $zendesk.tickts(query: 'moon').first
get https://juniper.zendesk.com/api/v2/tickts?query=moon
the server responded with status 404
{"error"=>"InvalidEndpoint", "description"=>"Not found"}

# notice that user becomes users:
 > $zendesk.user(query: 'moon').count
get https://juniper.zendesk.com/api/v2/users?query=moon

$zendesk.search(query: 'moon').first
NoMethodError: undefined method `superclass' for ZendeskAPI::Search:Module

How would I run a search, such as the following (which is a valid call)?

# simple
curl "https://juniper.zendesk.com/api/v2/search.json?query=type:moon" -v -u email:pasword
# typed:
 curl "https://juniper.zendesk.com/api/v2/search.json?query=type:ticket%20moon" -v -u email:pasword

Edit: #29 suggests client.users.search(:query => email). How would I find this user's tickets?

Thanks!

Fails to create an organization

I found that a call to create an organization fails. It appears that the required values are being removed on the Zendesk side?

>> org = client.organization.create({:name => 'Testing'})
WARNING: Removed restricted keys ["name"] from parameters according to whitelist
the server responded with status 422
    {"details"=>{"name"=>[{"description"=>"Name cannot be blank", "type"=>"blank"}]}, "description"=>"Record validation errors", "error"=>"RecordInvalid"}
=> nil

This problem was just recently reported here (https://support.zendesk.com/entries/21475108-x-zendesk-api-warn-removed-restricted-keys-error) by someone else when creating a user.

Note, I have also tried it this way with the same results

org = Zendesk::Organization.create(client, {:name => 'Testing'})

And also this way:

>> org = Zendesk::Organization.new(client, {:name => 'Testing'})
=> organization: #<Zendesk::Trackie name="Testing">
>> org.name
=> "Testing"
>> org.save
WARNING: Removed restricted keys ["name"] from parameters according to whitelist
the server responded with status 422
    {"details"=>{"name"=>[{"description"=>"Name cannot be blank", "type"=>"blank"}]}, "description"=>"Record validation errors", "error"=>"RecordInvalid"}
=> false

Error handling

When using the resource style of the api erros are "swalloved".
i.e

client.tickets.create(:subject => "ticket.subject", :description => "ticket.description", :requester_id => "10001", :submitter_id => "10001", ...)

will not throw an error. but only logg the error But

client.connection.get("/api/v2/users/10001/tickets/requested.json")

throws an Faraday::Error::ClientError.
Is this intentional and is there a way to get the error in the first example?

Unable to do a search on users

client.users.search(:query => '[email protected]').first
NoMethodError: undefined method map' for #<String:0x000000092b9590> from /app/vendor/bundle/ruby/1.9.1/gems/zendesk_api-0.2.2/lib/zendesk_api/collection.rb:189:infetch'
from /app/vendor/bundle/ruby/1.9.1/gems/zendesk_api-0.2.2/lib/zendesk_api/rescue.rb:28:in block (2 levels) in rescue_client_error' from /app/vendor/bundle/ruby/1.9.1/gems/zendesk_api-0.2.2/lib/zendesk_api/collection.rb:201:into_a'
from /app/vendor/bundle/ruby/1.9.1/gems/zendesk_api-0.2.2/lib/zendesk_api/collection.rb:285:in method_missing' from (irb):8 from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:47:instart'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands/console.rb:8:in start' from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.2.11/lib/rails/commands.rb:41:in<top (required)>'
from script/rails:6:in require' from script/rails:6:in

'

Collection#each_page method useful but confusing

The Collection#each_page does a very useful thing, namely allow you to iterate through a collection without worrying about doing pagination manually. However, given the name of the method, I was very surprised that the first parameter passed to the block was an element of the collection, rather than the "page" - I initially expected the first parameter to be a collection containing all the elements on the page.

Also, the variable naming in the README example for using each_page with 2 params is a bit misleading; it might be clearer if you call the second parameter page_number, rather than page.

One potential improvement: make the "paper over page boundaries" behaviour either the default or a configurable option of the #each method, and repurposing #each_page to iterate through pages, not items.

Request hangs after getting results

Just getting started..

    client.tickets.first.to_json

I'll see the results printed out in the console, but after that execution halts-- I have to force quit the server and start again.

No tags update from << method

# broken:
> t.tags
 => ["sms"] 
1.9.3-p194 :049 > t.tags << 'wqer'
 => ["sms", "wqer"] 
1.9.3-p194 :050 > t.save
# <snip>
> t.tags
 => ["sms"] 


# working:
> t.tags
 => ["sms"] 
1.9.3-p194 :049 > t.tags = ['sms', 'wqer']
 => ["sms", "wqer"] 
1.9.3-p194 :050 > t.save
# <snip>
> t.tags
 => ["sms", "wqer" ]

Organizations not caching properly for pagination

There appears to be minor caching bug when organizations are paged. The following symptoms are observed:
In trying to iterated over every single organization the following should work

client = ZendeskAPI::Client.new # config the client
page = 1
loop do
  orgs = client.organizations.page(page)
  break if orgs.empty?
  page += 1
  orgs.each{|o| puts o.name }
end

Luckily, there is a workaround, just use next:

orgs = client.organizations
loop do
    orgs.each{|o| puts o.name } 
    orgs.next
    break if orgs.empty?
end

How to recover from 500 error

When paging through tickets using:

@client.search(query: query).each_page(&:block)

there is the occasional error:

{"error"=>"unavailable", "description"=>"Sorry, we could not complete your search query. Please try again in a moment."}

Stacktrace:

the server responded with status 500
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/response/raise_error.rb:8:in `on_complete'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/response.rb:9:in `block in call'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/response.rb:63:in `on_complete'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/response.rb:8:in `call'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/request/authorization.rb:36:in `call'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/connection.rb:226:in `run_request'
/var/lib/gems/1.9.1/gems/faraday-0.8.4/lib/faraday/connection.rb:87:in `get'
/var/lib/gems/1.9.1/gems/zendesk_api-0.2.6/lib/zendesk_api/collection.rb:174:in `fetch'
/var/lib/gems/1.9.1/gems/zendesk_api-0.2.6/lib/zendesk_api/rescue.rb:43:in `block (2 levels) in rescue_client_error'
/var/lib/gems/1.9.1/gems/zendesk_api-0.2.6/lib/zendesk_api/collection.rb:201:in `to_a'
/var/lib/gems/1.9.1/gems/zendesk_api-0.2.6/lib/zendesk_api/collection.rb:285:in `method_missing'
/var/lib/gems/1.9.1/gems/zendesk_api-0.2.6/lib/zendesk_api/collection.rb:210:in `each_page'

How is it possible to recover and retry the fetch in those cases?

client is not meant to be an end-user?

I am just starting to dig into the Zendesk API and this client. I am creating a customer portal integrated with other applications, part of it's functionality will be Zendesk tickets.

This gem seems almost perfect (as long as client is the actual end-user and not a Zendesk admin user). However, it seems that the Zendesk API calls are only available to Zendesk Admin users and thus the "client" needs to be an Admin user and not an end-user.

Or am I confused on this?

If this is the case then calling client.tickets does not help me as it will give me all the tickets in my system.

I need the API gem to authenticate with an admin user but then set client to the current end-user using the system. Thus when I call client.tickets I will get only that end-user's tickets.

I appreciate any direction in how to use this gem properly.

update:
I just tried to use the account API token as the password for the admin user and an end-user and on both accounts the client.current_user was set to "Anonymous user".
This seems like an error if I understand the documentation correctly.

Custom Fields

Hello,

I am creating tickets using the ruby client for a bulk import and wanted to know if custom fields are accessible?

Creating tickets doesn't work per documentation

Docs say to do client.tickets.create(:description => "...

That doesn't work. I get errors back saying that WARNING: Removed restricted keys ["description", "subject", etc.

If I do this:

client.tickets.create(:ticket => {:description => "blah..."})  

then that works.

But I can't figure out how to set the requester.

Docs here say I should be able to pass in a request-email and it will either find or create the requester. If I do this:

c.tickets.create(:ticket => {:description => "Test", 'requester-name' => "Greg DeVore", 'requester-email' => "[email protected]"})

I get a warning that restricted params requester-name and requester-email have been removed and the ticket is created as if I submitted it.

Can't attach an uploaded file to ticket

Hey,
i'm getting the following error when sending an attached file that has been uploaded from the client.

@ticket= ZendeskAPI::Ticket.new(@client , :subject => subject, :comment => { :value => params[:feedback_text] },:requester_id => zendesk_user['id'])

@ticket.comment.uploads << params[:file]

@ticket.save

gives me

{"error"=>"RecordInvalid", "description"=>"Record validation errors", "details"=>{"filename"=>[{"description"=>"cannot be blank"}]}}

This only happens with files that are uploaded to the controller from the client using POST (ActionDispatch::Http::UploadedFile)

I'm using v0.1.1 of the gem.

How to search using API client?

How do I search using the API client? The documentation shows the API supports it using a "search" action on a user (for instance). - http://developer.zendesk.com/documentation/rest_api/users.html

Specifically, I'm trying to search for a user by email.

All the following attempts return the full list of users paged in 100's.

zendesk_user = Zendesk::User.find(client, {:email => '[email protected]'})
zendesk_user = Zendesk::User.find(client, :params => {:search => '[email protected]'})
zendesk_user = Zendesk::User.find(client, :search => {:email => '[email protected]'})

How do I use the API client to search for Users, Organizations, etc? I looked in the gem but didn't see any code or tests for this feature.

What is the best approach to initialize zendesk in Rails?

In the readme you say that 'Configuration is done through a block returning an instance of ZendeskAPI::Client'. Where in your opinion should be this block? I guess that having such code in model or controller action is not the best approach.

Is there any way to initialize zendesk api gem somewhere so that then I'll be able just to call for example @zendesk_client.tickets anywhere in Rails?

Thanks.

Issue with using Token Auth (README) with Ruby Gems Version of this Library 0.1.9

Following the current README documentation will lead to errors on the Ruby Gems Version of this Library when using token auth.

require 'zendesk_api'

client = ZendeskAPI::Client.new do |config|
  # Mandatory:

  config.url = "<- your-zendesk-url ->" # e.g. https://mydesk.zendesk.com/api/v2

  config.username = "[email protected]"

  # Choose one of the following depending on your authentication choice
  config.token = "your zendesk token"
  config.password = "your zendesk password"

  # Optional:

  # Retry uses middleware to notify the user
  # when hitting the rate limit, sleep automatically,
  # then retry the request.
  config.retry = true

  # Logger prints to STDERR by default, to e.g. print to stdout:
  require 'logger'
  config.logger = Logger.new(STDOUT)

  # Changes Faraday adapter
  # config.adapter = :patron

  # Merged with the default client options hash
  # config.client_options = { :ssl => false }

  # When getting the error 'hostname does not match the server certificate'
  # use the API at https://yoursubdomain.zendesk.com/api/v2
end

Resulting in the error

NoMethodError: undefined method `token=' for #<ZendeskAPI::Configuration:0x007fe3c32caef8>
    from /Users/ben/Dropbox/Web/zendesk/hubby/app/models/zendesk.rb:14:in `block in assign_desk'
    from /Users/ben/.rvm/gems/ruby-1.9.3-p194@general/gems/zendesk_api-0.1.3/lib/zendesk_api/client.rb:72:in `initialize'
    from /Users/ben/Dropbox/Web/zendesk/hubby/app/models/zendesk.rb:6:in `new'
    from /Users/ben/Dropbox/Web/zendesk/hubby/app/models/zendesk.rb:6:in `assign_desk'
    from (irb):4
    from /Users/ben/.rvm/gems/ruby-1.9.3-p194@general/gems/railties-3.2.8/lib/rails/commands/console.rb:47:in `start'
    from /Users/ben/.rvm/gems/ruby-1.9.3-p194@general/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in `start'
    from /Users/ben/.rvm/gems/ruby-1.9.3-p194@general/gems/railties-3.2.8/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

The Ruby Gems version has not been updated yet.

In order this get this working either modify the config code to:

  config.username = "[email protected]/token" # add /token
  config.password = "your zendesk token" # Use password field and not token

Or in your Gemfile use

  gem 'zendesk_api', :git => 'git://github.com/zendesk/zendesk_api_client_rb.git'

This will get the latest version of the ruby gem library when you re-run 'bundle install' in the console.

Namespace clash

We run the client inside a Rails app and have one of our models named Ticket. Loading the client and calling user.requested_tickets result in an error:

rails_console > user.requested_tickets
NoMethodError: undefined method `resource_name' for Ticket:Class
    from /Users/michael/.rvm/gems/ruby-1.9.3-p125/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:24:in `initialize'
    from /Users/michael/.rvm/gems/ruby-1.9.3-p125/gems/zendesk_api-0.0.9/lib/zendesk_api/association.rb:205:in `new'
    from /Users/michael/.rvm/gems/ruby-1.9.3-p125/gems/zendesk_api-0.0.9/lib/zendesk_api/association.rb:205:in `block in has_many'

Renaming our model removes the problem so it seems like a name space issue.
Looking in the code around the Associations#get_class line 233 seems it load the class from a global scope which finds our Ticket class first. A few quick fix ideas like replacing
get_const with some ZendeskAPI scope like ZendeskAPi.get_const or ZendeskAPI.get_class resulted in specs failing.

Any current way to hit '/api/v2/tickets/{id}/metrics.json' via the gem?

Hey,

Is there currently a way to hit the API call '/api/v2/tickets/{id}/metrics.json' via the gem?

As currently a call like:

Zendesk.client.tickets.find(:id=>1).metrics

Makes two REST requests. One for the ticket object ('GET /api/v2/tickets/{id}.json') and the other for the ticket_metric object.

Unable to catch 404 on find with no match

Recently the API changed from returning a nil to raising a 404.

Old Example:

client.organizations.find(:id => 123)
#=> nil

New behavior:

client.organizations.find(:id => 123)

ZendeskAPI::Organization - find
the server responded with status 404
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/response/raise_error.rb:6:in `on_complete'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/response.rb:9:in `call'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/response.rb:63:in `on_complete'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/response.rb:8:in `call'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/request/authorization.rb:36:in `call'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/connection.rb:226:in `run_request'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/faraday-0.8.1/lib/faraday/connection.rb:87:in `get'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/zendesk_api-0.0.9/lib/zendesk_api/actions.rb:69:in `orig_find'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in `send'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/zendesk_api-0.0.9/lib/zendesk_api/rescue.rb:26:in `find'
/home/mark/.rvm/gems/ruby-1.8.7-p358@canvas/gems/zendesk_api-0.0.9/lib/zendesk_api/collection.rb:62:in `find'
(irb):3:in `test_crap'
(irb):9:in `irb_binding'
/home/mark/.rvm/rubies/ruby-1.8.7-p358/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'
/home/mark/.rvm/rubies/ruby-1.8.7-p358/lib/ruby/1.8/irb/workspace.rb:52
    {"error"=>"RecordNotFound", "description"=>"Not found"}
=> nil

No matter what I do, I cannot catch/rescue the exception. A begin/rescue surrounding block never fires the contents of the rescue and yet the call fails. It appears to be putting the above error output directly to StandardError console output and skipping anything that I can catch.

How should code look that tries to do a find where the value is wrong and be able to handle the exception?

Clone and install fails when older RSpec gems used

I can't get the gem to work in my Rails 2.3 application and I'm trying to narrow the problems down. So, this was found trying to test in IRB outside of my Rails application, ran into some problems.

With the older rails app, I have older RSpec dependencies as well.

After cloning the repository (0.0.2) and with "rspec (1.3.2)", "rspec-rails (1.3.4)", the "rake install" failed.

$ rake install
rake aborted!
no such file to load -- rspec/core/rake_task

In order to install, I had to modify Rakefile and comment out:

  • require 'rspec/core/rake_task'
  • The "Run specs" task
  • The "Run live specs" task

Error handling with callbacks is counterintuituve

This is more a design issue rather than a specific bug, but I personally find having to handle API error cases with callbacks instead of exceptions bewildering (so much so that we've created our own wrapper for the zendesk_api gem). Here's an example from #71:

class SearchError < Exception; end

client.insert_callback do |env|
  if env[:status] == 500 && env[:url].request_uri =~ %r{/search}
    # Must not be a Faraday::Error::ClientError, but could be any standard ruby error
    raise SearchError
  end
end

This pattern forces each app that uses the zendesk_api gem to know intimate details of the Zendesk REST API (the error conditions for which aren't documented anywhere, to my knowledge). While I understand the perils of abstracting away the distributed nature of the API access completely, this feels like a very leaky abstraction - isn't the whole point of a wrapper to hide precisely these kinds of details from the application developer?

My proposed solution would be to raise (and document!) pre-defined exceptions for error cases known in advance (e.g. authentication error, validation errors, transient unavailability errors) by default, or alternatively follow the Rails method semantics and have methods ending with ! raise exceptions and methods without ! returning false or nil.

Can't create a ticket.

zendesk_client = ZendeskAPI::Client.new do |config|
  config.url = "url v2"
  config.username = "login"
  config.password = "pass"
  config.retry = true
  require 'logger'
  config.logger = Logger.new(STDOUT)
end

zendesk_client.tickets.create(:subject => 'test api')

This code produces the following error:

NoMethodError (undefined method merge' for #JSON::Ext::Generator::State:0xb38db004)`

However I can get access to existed tickets, for example

zendesk_client.tickets.find(:id => 123)

works as expected.

Zendesk::User seems to conflict with project User

In a Rails 2.3.x application that has a User model, the Zendesk gem appears to fail to initialize.

/lib/zendesk/association.rb#get_class and self.get_class.

Faraday: you may want to install system_timer for reliable timeouts
Faraday: you may want to install system_timer for reliable timeouts
/home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/activesupport-2.3.14/lib/active_support/dependencies.rb:443:in load_missing_constant': Zendesk is not missing constant User! (ArgumentError) from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/activesupport-2.3.14/lib/active_support/dependencies.rb:106:inconst_missing_not_from_s3_library'
from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/aws-s3/lib/aws/s3/extensions.rb:206:in rake_original_const_missing' from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/rake-0.9.2.2/lib/rake/ext/module.rb:36:inconst_missing'
from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/activesupport-2.3.14/lib/active_support/dependencies.rb:124:in send' from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/gems/activesupport-2.3.14/lib/active_support/dependencies.rb:124:inconst_missing'
from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/bundler/gems/zendesk_api_client_rb-0f33b3cc8681/lib/zendesk/association.rb:194:in const_get' from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/bundler/gems/zendesk_api_client_rb-0f33b3cc8681/lib/zendesk/association.rb:194:inget_class'
from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/bundler/gems/zendesk_api_client_rb-0f33b3cc8681/lib/zendesk/association.rb:84:in `has'
from /home/mark/.rvm/gems/ruby-1.8.7-p358@mygems/bundler/gems/zendesk_api_client_rb-0f33b3cc8681/lib/zendesk/resources/misc.rb:4

It appears that it might only need to be scoped with "Zendesk::" before it to work.

ticket.import and comments

Hello again,

I was able to get things moving with ticket.create and wanted to try ticket.import.

losedticket=client.tickets.import( :subject => ": Ticket IMPORT",
:description => "ran the scripts on their DB and it is fixed",
:submitter_id => client.users.find(:id => 'me'),
:priority => "normal",
:requester_id => user[0].id,
:assignee_id => "239174448",
:group_id => "20056381",
:comments => "This is a comment",
:fields => [{:id =>20972946, :value => 17}],
:tags => ["Import", "Test"],
:status => "pending")

My other API calls go fine but this one is oddly silent in it's failure. Also, comments seem to be blocked on create? Is that expected? API message below:

x-zendesk-api-version: "v2"
x-zendesk-api-warn: "Removed restricted keys ["comments"] from parameters according to whitelist"

Thanks in advance!

Installation instructions or register with rubygems

Unable to install the gem.

The following line in my gemfile doesn't install the gem.

gem 'zendesk_api_client_rb'

It appears the gem is not registered with RubyGems. Also failing to install from git source. Please update readme with instructions on how users should install.

Gracefully handle unauthenticated error

Currently, unauthenticated looks like this. Presumably, it would be nice to have this error noticed, and an exception thrown. Would be happy to work on such a commit should that be desirous.

Edit: also good to handle: (Stripe rubygem has a good way of handling errors like this https://github.com/stripe/stripe-ruby/tree/master/lib/stripe/errors)

{"error"=>{"title"=>"Forbidden", "message"=>"You do not have access to this page. Please contact the account owner of this help desk for further help."}}
  Accept: "application/json"
  Accept-Encoding: "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
  User-Agent: "ZendeskAPI API 0.1.7"
Status 401
  server: "nginx/1.0.15"
  date: "Wed, 24 Oct 2012 20:55:16 GMT"
  content-type: "application/json; charset=utf-8"
  connection: "close"
  status: "401 Unauthorized"
  www-authenticate: "Basic realm=\"Web Password\""
  content-length: "38"
  x-zendesk-origin-server: "app29.sys.zendesk.com"
{"error"=>"Couldn't authenticate you"}
#<ZendeskAPI::Collection:0x007fc9fa67d740> - fetch
the server responded with status 401
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/response/raise_error.rb:8:in `on_complete'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/response.rb:9:in `block in call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/response.rb:63:in `on_complete'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/response.rb:8:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/request/authorization.rb:36:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/connection.rb:226:in `run_request'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/faraday-0.8.4/lib/faraday/connection.rb:87:in `get'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/zendesk_api-0.1.7/lib/zendesk_api/collection.rb:158:in `fetch'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/zendesk_api-0.1.7/lib/zendesk_api/rescue.rb:26:in `block (2 levels) in rescue_client_error'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/zendesk_api-0.1.7/lib/zendesk_api/collection.rb:197:in `to_a'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/zendesk_api-0.1.7/lib/zendesk_api/collection.rb:277:in `method_missing'
/Users/peter/Rails/myapp/app/controllers/support_controller.rb:80:in `twilio_inbound'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/abstract_controller/base.rb:167:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/rendering.rb:10:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/abstract_controller/callbacks.rb:18:in `block in process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:414:in `_run__1479243886447860838__process_action__2262410119493339627__callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:405:in `__run_callback'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/abstract_controller/callbacks.rb:17:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/rescue.rb:29:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/instrumentation.rb:30:in `block in process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:in `block in instrument'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/notifications.rb:123:in `instrument'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/instrumentation.rb:29:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/params_wrapper.rb:207:in `process_action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/abstract_controller/base.rb:121:in `process'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/abstract_controller/rendering.rb:45:in `process'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal.rb:203:in `dispatch'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_controller/metal.rb:246:in `block in action'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/routing/route_set.rb:73:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/routing/route_set.rb:73:in `dispatch'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/routing/route_set.rb:36:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/journey-1.0.4/lib/journey/router.rb:68:in `block in call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/journey-1.0.4/lib/journey/router.rb:56:in `each'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/journey-1.0.4/lib/journey/router.rb:56:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/routing/route_set.rb:600:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-pjax-0.6.0/lib/rack/pjax.rb:12:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/mongoid-3.0.9/lib/rack/mongoid/middleware/identity_map.rb:33:in `block in call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/mongoid-3.0.9/lib/mongoid/unit_of_work.rb:39:in `unit_of_work'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/mongoid-3.0.9/lib/rack/mongoid/middleware/identity_map.rb:33:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/warden-1.2.1/lib/warden/manager.rb:35:in `block in call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/warden-1.2.1/lib/warden/manager.rb:34:in `catch'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/warden-1.2.1/lib/warden/manager.rb:34:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/etag.rb:23:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/conditionalget.rb:25:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/head.rb:14:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/remotipart-1.0.2/lib/remotipart/middleware.rb:30:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/params_parser.rb:21:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/flash.rb:242:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:205:in `context'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:200:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/cookies.rb:339:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:405:in `_run__1722688666307380800__call__2508220806090863030__callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:405:in `__run_callback'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:385:in `_run_call_callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/callbacks.rb:81:in `run_callbacks'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/callbacks.rb:27:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/reloader.rb:65:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/remote_ip.rb:31:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/rack/logger.rb:26:in `call_app'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/rack/logger.rb:16:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/request_id.rb:22:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/methodoverride.rb:21:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/runtime.rb:17:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/activesupport-3.2.8/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/lock.rb:15:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/static.rb:62:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/engine.rb:479:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/application.rb:223:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/content_length.rb:14:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/rack/log_tailer.rb:17:in `call'
/Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/rack-1.4.1/lib/rack/handler/webrick.rb:59:in `service'
/Users/peter/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
/Users/peter/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
/Users/peter/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
    {"error"=>"Couldn't authenticate you"}


Started GET "/zendesk" for 127.0.0.1 at 2012-10-24 13:55:16 -0700
Processing by SupportController#twilio_inbound as HTML
  MOPED: 127.0.0.1:27017 COMMAND      database=admin command={:ismaster=>1} (0.7079ms)
  MOPED: 127.0.0.1:27017 QUERY        database=jnprmongo_development collection=users selector={"$query"=>{}, "$orderby"=>{:_id=>-1}} flags=[] limit=-1 skip=0 fields=nil (0.2961ms)
Completed 500 Internal Server Error in 783ms

NoMethodError (undefined method `priority=' for nil:NilClass):
  app/controllers/support_controller.rb:81:in `twilio_inbound'


  Rendered /Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.2ms)
  Rendered /Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.9ms)
  Rendered /Users/peter/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (10.7ms)

Question: Getting Views Count

Hey there, is it possible to get views count using the ruby gem? e.g (via the Zendesk API)

curl https://{subdomain}.zendesk.com/api/v2/views/{id}/count.json \
  -v -u {email_address}:{password}

Move to repo zendesk_api?

Can we move the repo to "zendesk_api", since that's the name of the gem and the file we're supposed to require?

Can't *add* new comments to an existing ticket

Hi,

when I load a ticket with client.tickets.find(id: 1), it does not retrieve the comments. ticket.comment and ticket.comments returns nil. I can successfully add one comment to an existing ticket by using Zendesk::Ticket#comment=, but it will replace the existing comment.

So, how would you add a comment to an existing ticket, without overwriting the existing one ?

Thanks.

Catching Faraday/HTTP Net Errors

Hey guys,

Does anyone know what the best practice way to catch Faraday/HTTP Net exceptions with the zendesk api gem?

I'm hitting timeout issues when iterating through .each_page on the Search API

e.g

client.search(:query => "my search query").each_page do |resource, page|
  # all resources will be yielded along with the page
end

insert_callback only works when the connection successfully returns and not when there is a timeout.

e.g

client.insert_callback do |env|
  puts env[:response_headers]
end

what's your plans to store vcr cassets in future?

some tests are highly dependend on how zendesk account is configured

e.g. we add x-on-behalf-of to gem

but when we want to test is it really works, we have to check current user ( client.users.find(:id =-> :me) )
we can create that user and after each test ensure to delete it - but if we could cache vcr cassetes as long as the api would not change we would be able to reuse them

problem is with authorization data that are stored as part of url - and you don't want to share them from obvious reason - still it would be good to solve this issue

what's your thoughts ?

Searching be external_id doesn't return a result

The scenario is:

  • I create a Zendesk Ticket with an external_id
  • I immediately try to lookup that ticket with the same external_id and get no results
  • I wait 10 minutes or so, and its starts showing up.
external_id = SecureRandom.uuid
  #=> "7cfde8e8-5004-4911-9d62-e21e68447d9b"

zendesk_ticket = ::ZendeskAPI::Ticket.new(ZENDESK_CLIENT, {
  :subject => subject,
  :group_id => group_id,
  :external_id => "1234-5678",
  :comment => {
    :value => comment,
    :public => false
  },
  :requester => {
    :name => name,
    :email => email
  }
})

zendesk_ticket.save

found_ticket = ::ZendeskAPI::Search.search(ZENDESK_CLIENT, {
  :query => "type:ticket external_id:#{external_id}"
}).first

# found_ticket will be nil here

Can't create tickets using the lib

Hi guys,

I'm trying to create tickets with the gem but normally I got an error, the code I'm using is as follows:

ticket = api.tickets.create :subject => 'testing', :description => 'testing', :submitter_id => api.current_user.id 

The actual code is on this line of my project:

https://github.com/hybridgroup/taskmapper-zendesk/blob/171-zendesk-wrapper-removal/lib/provider/ticket.rb#L66

I tried without my wrapper and even when I can create a ticket without a problem the gem is throwin an exception, I'll update this issue with the exception as soon as I can.

Thanks in advance.

Client tries to fetch obviously non-existent associations.

The following code makes a request to the API, even though it is impossible to find the associated record because the _id column is nil.

# client is already initialized and valid
result = client.tickets.find(id: 3)
puts result.assignee_id == nil
# makes invalid request to Zendesk API, resulting in a 404.
result.assignee

Using 0.1.9 version of the gem.

Finding Tickets for an Organization

Howdy!

Back with another good one here. After looping over all the organizations and putting them into a simple "name"=>"orgId" hash I'm now trying to find all the orgs that have 0 tickets. To do this I'm calling the client like so:

tix = client.ticket(:organization_id => 22227936)
puts tix.count

It works on the first call and I see a GET request in the logs and the count is correct.
GET https://solium.zendesk.com/api/v2/tickets?organization_id=22227936

The issue is subsequent calls are not issuing the GET request as I'd expect. A simple example is:

tix = client.ticket(:organization_id => 22227936) # => does a get
puts tix.count # => has correct count

tickets = client.ticket(:organization_id => 143898)  # => doesn't issue a get
puts tickets.count # => gets old count from tix

Instinct tells me I need to flush the client or something but I'm not clear on how.

As ever, thanks for your help!

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.