Git Product home page Git Product logo

slack-ruby-client's People

Contributors

alexagranov avatar blowfishpro avatar chrisbloom7 avatar dblock avatar dependabot[bot] avatar duffn avatar felixbuenemann avatar greggroth avatar ioquatix avatar irphilli avatar jcraigk avatar jmanian avatar kstole avatar manuelmeurer avatar marfoldi avatar michaelherold avatar mikz avatar nbgoodall avatar olleolleolle avatar peterzhu2118 avatar phigrofi avatar rodneyu215 avatar rthbound avatar schinery avatar seuros avatar sonicdoe avatar sunny avatar wasabigeek avatar web-flow avatar wedgex 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

slack-ruby-client's Issues

Protection against flood loop

You may be interested in:

  1. respecting https://api.slack.com/docs/rate-limits
  2. ignoring message from itself
    These things together can loop and flood the server with messages.

I'm lazy to write tests so I'll just leave my monkey-patch for gem v0.3.0. Instead of rewriting dispatch one probably could wrap each "message" callback in one for check but it would be harder with dynamic adding callbacks.

Slack::RealTime::Api::Message.module_eval do
  alias :message_old :message
  def message *args
    message_old *args
    sleep 1
  end
end

Slack::RealTime::Client.class_eval do
  alias :old_initialize :initialize
  def initialize *args
    old_initialize *args
    @callbacks = Hash.new{ |h, k| h[k] = [] }
  end
  protected
  def dispatch event
    return false unless event.data
    data = JSON.parse event.data
    return false unless type = data["type"]
    return false unless callbacks = @callbacks[type]
    callbacks.each do |c|
      c.call data unless type == "message" && self.self["id"] == data["user"]
    end.empty? ^ true
  end
end

Where to post the client.start! code?

This example works great in the rails console.

  1. Where would you put it in the app (in a controller, in a config file, etc)?
  2. If the app is using the Puma web server, does the WebSocket that this code creates consume a worker or does it consume a thread?

Thanks for any advice!

missing dependency for FaradayMiddleware::ParseJson: cannot load such file -- json (RuntimeError)

Under Amazon Linux:

/home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/middleware.rb:20:in `new': missing dependency for FaradayMiddleware::ParseJson: cannot load such file -- json (RuntimeError)
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:48:in `build'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:162:in `block in to_app'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:162:in `each'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:162:in `inject'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:162:in `to_app'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:152:in `app'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:139:in `build_response'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/connection.rb:377:in `run_request'
        from /home/ec2-user/.gem/ruby/2.0/gems/faraday-0.9.1/lib/faraday/connection.rb:177:in `post'
        from /home/ec2-user/.gem/ruby/2.0/gems/slack-ruby-client-0.3.0/lib/slack/web/faraday/request.rb:25:in `request'
        from /home/ec2-user/.gem/ruby/2.0/gems/slack-ruby-client-0.3.0/lib/slack/web/faraday/request.rb:10:in `post'
        from /home/ec2-user/.gem/ruby/2.0/gems/slack-ruby-client-0.3.0/lib/slack/web/api/endpoints/rtm.rb:19:in `rtm_start'
        from /home/ec2-user/.gem/ruby/2.0/gems/slack-ruby-client-0.3.0/lib/slack/real_time/client.rb:39:in `block in start!'
        from /home/ec2-user/.gem/ruby/2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `call'
        from /home/ec2-user/.gem/ruby/2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run_machine'
        from /home/ec2-user/.gem/ruby/2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run'
        from /home/ec2-user/.gem/ruby/2.0/gems/slack-ruby-client-0.3.0/lib/slack/real_time/client.rb:38:in `start!'

Brutally fixed by adding json to my Gemfile. Either gem's .gemspec should be fixed or faraday.

Supply a custom Faraday connection

I'm using the files.upload API, and started getting this error on a few files:

Faraday::TimeoutError Net::ReadTimeout
vendor/gems/ruby/2.1.0/gems/slack-ruby-client-0.2.1/lib/slack/web/faraday/request.rb:25:in `request'
vendor/gems/ruby/2.1.0/gems/slack-ruby-client-0.2.1/lib/slack/web/faraday/request.rb:10:in `post'
vendor/gems/ruby/2.1.0/gems/slack-ruby-client-0.2.1/lib/slack/web/api/endpoints/files.rb:70:in `files_upload'

The Net::ReadTimeout is coming from using Faraday's default adapter, ie net/http. That happens when the read_timeout is exceeded, which defaults to 60 seconds http://ruby-doc.org/stdlib-2.1.1/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout

It's probably not great to go past this in general, but it might be expected for large files. It should be possible to customize the read_timeout when the Faraday::Connection is constructed, but I'm not seeing any way to customize this: https://github.com/dblock/slack-ruby-client/blob/e4c39604b6d00da1e419d63db68e30032f5a08e1/lib/slack/web/faraday/connection.rb#L16-L25

I realize I'm on an older version, so I will try upgrading but I don't think that will change anything. I'm still debugging the file in question to determine how big it is, but I figured I'd drop this in case anyone runs into similar.

Consider using keyword arguments and require Ruby 2.1

Ruby 2.1 has required keyword arguments, that could clean up a lot manual checking for existence of a key in options.

Would you consider requiring Ruby 2.1 ? I'd say it is not so strict requirement, given Rails 5 will require Ruby 2.2.

See 9174022 how it looks.

Automatically to_json attachments property in chat_postMessage

Posting attachments requires a to_json call on the attachments property. See slackapi/node-slack-sdk#12.

Slack-ruby-client should do it for you.

.chat_postMessage(
  channel: ...,
  text: 'Hello World',
  as_user: true,
  attachments: [
        {
            fallback: "New ticket from Andrea Lee - Ticket #1943: Can't rest my password - https://groove.hq/path/to/ticket/1943",
            pretext: "New ticket from Andrea Lee",
            title: "Ticket #1943: Can't reset my password",
            title_link: "https://groove.hq/path/to/ticket/1943",
            text: "Help! I tried to reset my password but nothing happened!",
            color: "#7CD197"
        }
    ].to_json

Ruby 2.0 + celluloid-io: No live threads left. Deadlock?

https://travis-ci.org/dblock/slack-ruby-client/jobs/101093592

Failures:
  1) integration test gets hello
     Failure/Error: socket.start_async { run_loop(socket, &block) }

     fatal:
       No live threads left. Deadlock?
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/mailbox.rb:63:in `block in check'
     # ./vendor/bundle/ruby/2.0.0/gems/timers-4.1.1/lib/timers/wait.rb:14:in `for'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/mailbox.rb:58:in `check'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/mailbox.rb:77:in `block in receive'
     # ./vendor/bundle/ruby/2.0.0/gems/timers-4.1.1/lib/timers/wait.rb:14:in `for'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/mailbox.rb:76:in `receive'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/call/sync.rb:50:in `wait'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid.rb:141:in `suspend'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/call/sync.rb:41:in `response'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/call/sync.rb:45:in `value'
     # ./vendor/bundle/ruby/2.0.0/gems/celluloid-0.17.2/lib/celluloid/proxy/sync.rb:38:in `method_missing'
     # ./lib/slack/real_time/client.rb:47:in `start_async'
     # ./spec/integration/integration_spec.rb:22:in `block (2 levels) in <top (required)>'
     # ./spec/integration/integration_spec.rb:44:in `start_server'
     # ./spec/integration/integration_spec.rb:93:in `block (2 levels) in <top (required)>'
     # ./spec/integration/integration_spec.rb:6:in `block (3 levels) in <top (required)>'
     # ./vendor/bundle/ruby/2.0.0/gems/vcr-3.0.1/lib/vcr.rb:244:in `turned_off'
     # ./spec/integration/integration_spec.rb:6:in `block (2 levels) in <top (required)>'
Finished in 6.82 seconds (files took 0.5859 seconds to load)
95 examples, 1 failure, 2 pending

Allow configuring store properties to track

Most clients want a store that knows about the current state of connection (self and team), but not about all other things like channels and users. Add a way to configure the default store to only track a certain amount of things.

Celluloid support is broken

celluloid.rb. Should be using ::Celluloid::Internals::Logger and not ::Celluloid::Logger for current release version of Celluloid (0.17.2)

If you don't think this ought to be fixed, can you know a working combination of ruby-slack-client, Celluloid & Reel versions?

Resolv::DNS::DecodeError: limit exceeded

Has anybody seen this before? I thought this might be a rate limiting issue but I'm not having issues with the web client. I also deleted my Slack app and recreated it but I'm still having this issue.

Resolv::DNS::DecodeError: limit exceeded
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1583:in `get_string'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1631:in `get_label'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1625:in `get_labels'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1598:in `get_name'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1641:in `get_rr'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1515:in `block (2 levels) in decode'
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/core_ext/range/each.rb:5:in `each'
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/core_ext/range/each.rb:5:in `each'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1514:in `block in decode'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1531:in `initialize'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1495:in `new'
    from /usr/local/lib/ruby/2.3.0/resolv.rb:1495:in `decode'
    from /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/dns_resolver.rb:46:in `resolve'
    from /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/tcp_socket.rb:101:in `create_socket'
    from /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/tcp_socket.rb:53:in `initialize'
    from /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/socket.rb:39:in `new'
... 37 levels...
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `block in load'
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:268:in `load_dependency'
    from /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/dependencies.rb:296:in `load'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/commands/rails.rb:6:in `call'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/command_wrapper.rb:38:in `call'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:185:in `block in serve'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:156:in `fork'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:156:in `serve'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:131:in `block in run'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:125:in `loop'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application.rb:125:in `run'
    from /usr/src/bundle/gems/spring-1.6.4/lib/spring/application/boot.rb:18:in `<top (required)>'
    from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
    from -e:1:in `<main>'irb(main):046:0> E, [2016-02-29T15:33:05.306451 #29] ERROR -- : Actor crashed!
Resolv::DNS::DecodeError: limit exceeded
    /usr/local/lib/ruby/2.3.0/resolv.rb:1583:in `get_string'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1631:in `get_label'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1625:in `get_labels'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1598:in `get_name'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1641:in `get_rr'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1515:in `block (2 levels) in decode'
    /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/core_ext/range/each.rb:5:in `each'
    /usr/src/bundle/gems/activesupport-5.0.0.beta3/lib/active_support/core_ext/range/each.rb:5:in `each'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1514:in `block in decode'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1531:in `initialize'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1495:in `new'
    /usr/local/lib/ruby/2.3.0/resolv.rb:1495:in `decode'
    /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/dns_resolver.rb:46:in `resolve'
    /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/tcp_socket.rb:101:in `create_socket'
    /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/tcp_socket.rb:53:in `initialize'
    /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/socket.rb:39:in `new'
    /usr/src/bundle/gems/celluloid-io-0.17.3/lib/celluloid/io/socket.rb:39:in `new'
    /usr/src/bundle/gems/slack-ruby-client-0.6.0/lib/slack/real_time/concurrency/celluloid.rb:72:in `build_socket'
    /usr/src/bundle/gems/slack-ruby-client-0.6.0/lib/slack/real_time/concurrency/celluloid.rb:86:in `connect'
    /usr/src/bundle/gems/slack-ruby-client-0.6.0/lib/slack/real_time/socket.rb:26:in `connect!'
    /usr/src/bundle/gems/slack-ruby-client-0.6.0/lib/slack/real_time/concurrency/celluloid.rb:30:in `connect!'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/calls.rb:28:in `public_send'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/calls.rb:28:in `dispatch'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/call/sync.rb:16:in `dispatch'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/cell.rb:50:in `block in dispatch'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/cell.rb:76:in `block in task'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/actor.rb:339:in `block in task'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/task.rb:44:in `block in initialize'
    /usr/src/bundle/gems/celluloid-0.17.3/lib/celluloid/task/fibered.rb:14:in `block in create'

NoMethodError in replaced raise_error method for Faraday::Response::RaiseError

Stacktrace:

/usr/local/rvm/gems/ruby-2.1.4/gems/slack-ruby-client-0.4.0/lib/slack/web/faraday/response/raise_error.rb:8:in `on_complete': undefined method `[]' for nil:NilClass (NoMethodError)
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/response.rb:9:in `block in call'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/response.rb:57:in `on_complete'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/request/url_encoded.rb:15:in `call'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/request/multipart.rb:14:in `call'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:139:in `build_response'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/connection.rb:377:in `run_request'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/faraday-0.9.2/lib/faraday/connection.rb:177:in `post'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/slack-ruby-client-0.4.0/lib/slack/web/faraday/request.rb:25:in `request'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/slack-ruby-client-0.4.0/lib/slack/web/faraday/request.rb:10:in `post'
    from /usr/local/rvm/gems/ruby-2.1.4/gems/slack-ruby-client-0.4.0/lib/slack/web/api/endpoints/channels.rb:131:in `channels_list'

A guard needs to be added to handle the case when body isn't present

how to set the proxy so I can use Runscope?

Hi, I see in the docs support for proxy:

proxy Optional HTTP proxy.

I want to pass a different URL so that i can use the Runscope gateway URL to monitor how it works with Slack....is there a doc that explains how I would do that?

Inherit Slack::Web::Api::Error from Faraday::ClientError

Currently, it inherits from Faraday::Error. The problem with this is that this doesn't have access to the response that caused the error. If this was [Faraday::ClientError](https://github.com/lostisland/faraday/blob/master/lib/faraday/error.rb#L5) instead, you can catch and access the response object.

Missing ENV[SLACK_API_TOKEN]! (RuntimeError)

running the example @ slack-ruby-client/examples/hi_web/hi.rb

#!/opt/chefdk/embedded/bin/ruby

require 'slack-ruby-client'

Slack.configure do |config|
  config.token = ENV['the API Token...... provided by Slack Admin']
  fail 'Missing ENV[SLACK_API_TOKEN]!' unless config.token
end

client = Slack::Web::Client.new

client.auth_test

client.chat_postMessage(channel: '#gradle', text: 'Hello World', as_user: true)

fails with:

./hi.rb
./hi.rb:7:in block in <main>': Missing ENV[SLACK_API_TOKEN]! (RuntimeError) from /home/skahmed/.chefdk/gem/ruby/2.1.0/gems/slack-ruby-client-0.6.0/lib/slack/config.rb:14:inconfigure'
from ./hi.rb:5:in `

'

/opt/chefdk/embedded/bin/ruby --version
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]

Slack:Config.logger is not working

Whenever creating a client or a bot the log levels are not respected.

Slack::Web::Client.config do |config|
    config.logger = Logger.new("test.log")
    config.logger.level = Logger::UNKNOWN
 end

  Slack::RealTime::Client.config do |config|
    config.logger = Logger.new("test.log")
    config.logger.level = Logger::UNKNOWN
 end

  Slack.configure do |config|
    config.logger = Logger.new("test.log")
    config.logger.level = Logger::UNKNOWN
  end

App will still log everything to STDOUT and do not respect any sort of logging.

Client cleanly ends after periods of inactivity when it shouldn't

Unless I'm misconfiguring something, I have two instances of a chat bot using slack-ruby-client which cleanly exit after periods of inactivity. Is there some way to prevent this?

I'm not setting anything up except the API token. I use client.on twice and then do a "client.start!"

It seems to disconnect within 48 hours.

(The particular source in question is here: https://github.com/dssit/dss-chatbot-slack/blob/master/dss-chatbot.rb)

Introduce non blocking mode.

I want to mix Slack client in the same process as a web server.

That means Slack client can't have blocking loop, but rather just run in the background.

See 1872a12 how it looks. I use it in mikz/october#29 to have a bot with also listens for webhooks.

Include example for `files.upload`

This API is a little different, since it can take an uploaded file. I wanted to be able to upload a file with having to read it all into memory. I found an example on https://github.com/lostisland/faraday and ended up with:

file = Faraday::UploadIO.new(path)
response = client.files_upload(file: faraday_upload)

If there's a better way to do that, definitely would love to ๐Ÿ‘‚ it!

Attachments

It seems like if you include attachments via the real time API they don't show up, but they work if you change client.web_client.chat_postMessage(...). Bug? Thanks!

Add local store

There's an interesting implementation in https://github.com/slackhq/node-slack-client/blob/master/src/client.coffee that caches users, channels, ims and groups.

        for k of data.users
          u = data.users[k]
          @users[u.id] = new User @, u

It then does a lot of bookkeeping for you listening to well-known slack events.

      when "team_join", "user_change"
        u = message.user
        @emit 'userChange', u
        @users[u.id] = new User @, u

Slack::RealTime::Client should implement similar behavior, possibly optionally.

The 2.0 branch does this even better with a clearly defined local store abstracted away.

We want to start with a local store

module Slack
  module RealTime
    module Store
      class Memory
        attr_accessor :users
        attr_accessor :channels
        attr_accessor :dms
        attr_accessor :groups
        attr_accessor :bots
        attr_accessor :teams

        def initialize
          @users = {}
          @channels = {}
          @dms = {}
          @groups = {}
          @bots = {}
          @teams = {}
        end
      end
    end
  end
end

And implement a set of handlers like https://github.com/slackhq/node-slack-client/tree/2.0.0-beta/lib/data-store/message-handlers that manipulate the store.

JRuby support, Faraday::SSLError: No message available

Integration tests are failing against an actual slack service.

1) integration test gets hello
     Got 0 failures and 2 other errors:
     1.1) Failure/Error:
            response = connection.send(method) do |request|
              case method
              when :get, :delete
                request.url(path, options)
              when :post, :put
                request.path = path
                request.body = options unless options.empty?
          Faraday::SSLError:
            No message available
          # ./vendor/bundle/jruby/1.9/gems/webmock-1.22.5/lib/webmock/http_lib_adapters/net_http.rb:109:in `request'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:82:in `perform_request'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:40:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:87:in `with_net_http_connection'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/adapter/net_http.rb:32:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday_middleware-0.10.0/lib/faraday_middleware/response_middleware.rb:30:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/response.rb:8:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/request/url_encoded.rb:15:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/request/multipart.rb:14:in `call'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/rack_builder.rb:139:in `build_response'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/connection.rb:377:in `run_request'
          # ./vendor/bundle/jruby/1.9/gems/faraday-0.9.2/lib/faraday/connection.rb:181:in `post'
          # ./lib/slack/web/faraday/request.rb:25:in `request'
          # ./lib/slack/web/faraday/request.rb:10:in `post'
          # ./lib/slack/web/api/endpoints/rtm.rb:21:in `rtm_start'
          # ./lib/slack/real_time/client.rb:74:in `build_socket'
          # ./lib/slack/real_time/client.rb:46:in `start_async'
          # ./spec/integration/integration_spec.rb:22:in `connection'
          # ./spec/integration/integration_spec.rb:44:in `start_server'
          # ./spec/integration/integration_spec.rb:91:in `(root)'
          # ./spec/integration/integration_spec.rb:6:in `(root)'
          # ./vendor/bundle/jruby/1.9/gems/vcr-3.0.1/lib/vcr.rb:244:in `turned_off'
          # ./spec/integration/integration_spec.rb:6:in `(root)'
     1.2) Failure/Error: fail ThreadError, 'queue empty' if @queue.empty?

Partition this gem?

Have you considered partitioning this gem into (maybe) slack_web_client and slack_real_time_client?

For my own project I have no need of the real time client, and it doesn't look like the web client depends on it at all. This would reduce the amount of code in my project and remove the dependency on faye-websocket too.

The real time client gem could then be built with the web client as a dependency.

Make exceptions in event and command handling non-fatal

From https://github.com/dblock/slack-ruby-bot/issues/47

config.ru:20:in `block (2 levels) in <main>'
E, [2016-02-11T18:38:55.596707 #160] ERROR -- : listen loop error: undefined method `[]=' for nil:NilClass (NoMethodError)
E, [2016-02-11T18:38:55.596840 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/slack-ruby-client-0.6.0/lib/slack/real_time/event_handlers/pref_change.rb:9:in `call'
E, [2016-02-11T18:38:55.596881 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/slack-ruby-client-0.6.0/lib/slack/real_time/client.rb:161:in `run_handlers'
E, [2016-02-11T18:38:55.596909 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/slack-ruby-client-0.6.0/lib/slack/real_time/client.rb:155:in `dispatch'
E, [2016-02-11T18:38:55.596936 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/slack-ruby-client-0.6.0/lib/slack/real_time/client.rb:109:in `block (2 levels) in run_loop'
E, [2016-02-11T18:38:55.596960 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:39:in `call'
E, [2016-02-11T18:38:55.596984 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:39:in `block in emit'
E, [2016-02-11T18:38:55.597012 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:38:in `each'
E, [2016-02-11T18:38:55.597061 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:38:in `emit'
E, [2016-02-11T18:38:55.597108 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/faye-websocket-0.10.2/lib/faye/websocket/api/event_target.rb:45:in `dispatch_event'
E, [2016-02-11T18:38:55.597154 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/faye-websocket-0.10.2/lib/faye/websocket/api.rb:106:in `receive_message'
E, [2016-02-11T18:38:55.597202 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/faye-websocket-0.10.2/lib/faye/websocket/api.rb:40:in `block in initialize'
E, [2016-02-11T18:38:55.597253 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:39:in `call'
E, [2016-02-11T18:38:55.597285 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:39:in `block in emit'
E, [2016-02-11T18:38:55.597310 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:38:in `each'
E, [2016-02-11T18:38:55.597334 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/event_emitter.rb:38:in `emit'
E, [2016-02-11T18:38:55.597378 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/hybi.rb:400:in `emit_message'
E, [2016-02-11T18:38:55.597427 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/hybi.rb:383:in `emit_frame'
E, [2016-02-11T18:38:55.597465 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/hybi.rb:121:in `parse'
E, [2016-02-11T18:38:55.597490 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/websocket-driver-0.6.3/lib/websocket/driver/client.rb:63:in `parse'
E, [2016-02-11T18:38:55.597530 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/faye-websocket-0.10.2/lib/faye/websocket/api.rb:145:in `parse'
E, [2016-02-11T18:38:55.597591 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/faye-websocket-0.10.2/lib/faye/websocket/client.rb:71:in `receive_data'
E, [2016-02-11T18:38:55.597641 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/eventmachine-1.0.9.1/lib/eventmachine.rb:193:in `run_machine'
E, [2016-02-11T18:38:55.597690 #160] ERROR -- : /app/vendor/bundle/ruby/2.2.0/gems/eventmachine-1.0.9.1/lib/eventmachine.rb:193:in `run'
E, [2016-02-11T18:38:55.597740 #160] ERROR -- : config.ru:20:in `block (2 levels) in <main>'
E, [2016-02-11T18:41:38.821515 #160] ERROR -- : Slack::Web::Api::Error: code_already_used

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.