slack-ruby-client 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -1
- data/.rubocop_todo.yml +23 -6
- data/.travis.yml +3 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +2 -0
- data/README.md +89 -1
- data/RELEASING.md +3 -1
- data/UPGRADING.md +26 -0
- data/bin/commands.rb +20 -0
- data/bin/commands/api.rb +14 -0
- data/bin/commands/auth.rb +12 -0
- data/bin/commands/channels.rb +140 -0
- data/bin/commands/chat.rb +47 -0
- data/bin/commands/emoji.rb +12 -0
- data/bin/commands/files.rb +61 -0
- data/bin/commands/groups.rb +158 -0
- data/bin/commands/im.rb +53 -0
- data/bin/commands/mpim.rb +53 -0
- data/bin/commands/oauth.rb +16 -0
- data/bin/commands/pins.rb +37 -0
- data/bin/commands/reactions.rb +53 -0
- data/bin/commands/rtm.rb +15 -0
- data/bin/commands/search.rb +40 -0
- data/bin/commands/stars.rb +37 -0
- data/bin/commands/team.rb +32 -0
- data/bin/commands/usergroups.rb +73 -0
- data/bin/commands/users.rb +48 -0
- data/bin/slack +50 -0
- data/examples/hi_real_time/Gemfile +2 -0
- data/examples/hi_real_time_and_web/Gemfile +2 -0
- data/examples/hi_real_time_async/Gemfile +5 -0
- data/examples/hi_real_time_async/hi.rb +29 -0
- data/lib/slack-ruby-client.rb +2 -2
- data/lib/slack/real_time/client.rb +72 -30
- data/lib/slack/real_time/concurrency.rb +8 -0
- data/lib/slack/real_time/concurrency/celluloid.rb +92 -0
- data/lib/slack/real_time/concurrency/eventmachine.rb +39 -0
- data/lib/slack/real_time/config.rb +23 -1
- data/lib/slack/real_time/socket.rb +50 -12
- data/lib/slack/version.rb +1 -1
- data/lib/slack/web/api/endpoints.rb +2 -0
- data/lib/slack/web/api/endpoints/groups.rb +1 -1
- data/lib/slack/web/api/endpoints/team.rb +1 -1
- data/lib/slack/web/api/endpoints/usergroups.rb +113 -0
- data/lib/slack/web/api/error.rb +6 -0
- data/lib/slack/web/api/schema/group.json +14 -0
- data/lib/slack/web/api/tasks/generate.rake +19 -3
- data/lib/slack/web/api/templates/command.erb +34 -0
- data/lib/slack/web/api/templates/commands.erb +5 -0
- data/lib/slack/web/config.rb +2 -0
- data/lib/slack/web/faraday/connection.rb +3 -2
- data/lib/slack/web/faraday/response/raise_error.rb +2 -1
- data/slack-ruby-client.gemspec +4 -2
- data/spec/fixtures/slack/web/429_error.yml +83 -0
- data/spec/fixtures/slack/web/rtm_start.yml +1 -1
- data/spec/fixtures/slack/web/users_list.yml +72 -0
- data/spec/integration/integration_spec.rb +88 -0
- data/spec/slack/real_time/client_spec.rb +8 -5
- data/spec/slack/real_time/concurrency/celluloid_spec.rb +58 -0
- data/spec/slack/real_time/concurrency/eventmachine_spec.rb +49 -0
- data/spec/slack/slack_spec.rb +52 -0
- data/spec/slack/web/api/endpoints/auth_spec.rb +6 -1
- data/spec/slack/web/api/endpoints/users_spec.rb +13 -0
- data/spec/slack/web/api/error_spec.rb +14 -0
- data/spec/slack/web/client_spec.rb +16 -0
- data/spec/support/real_time/concurrency/mock.rb +31 -0
- data/spec/support/real_time/connected_client.rb +5 -2
- metadata +55 -8
- data/spec/slack/real_time/socket_spec.rb +0 -46
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'websocket/driver'
|
2
|
+
require 'socket'
|
3
|
+
require 'forwardable'
|
4
|
+
require 'celluloid/io'
|
5
|
+
|
6
|
+
module Slack
|
7
|
+
module RealTime
|
8
|
+
module Concurrency
|
9
|
+
module Celluloid
|
10
|
+
class Socket < Slack::RealTime::Socket
|
11
|
+
include ::Celluloid::IO
|
12
|
+
include ::Celluloid::Logger
|
13
|
+
|
14
|
+
BLOCK_SIZE = 4096
|
15
|
+
|
16
|
+
extend ::Forwardable
|
17
|
+
def_delegator :socket, :write
|
18
|
+
def_delegators :driver, :text, :binary, :close
|
19
|
+
|
20
|
+
attr_reader :socket
|
21
|
+
|
22
|
+
def initialize(*args)
|
23
|
+
super
|
24
|
+
@driver = build_driver
|
25
|
+
end
|
26
|
+
|
27
|
+
# @yieldparam [WebSocket::Driver] driver
|
28
|
+
def connect!
|
29
|
+
super
|
30
|
+
|
31
|
+
driver.start
|
32
|
+
future.run_loop
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_loop
|
36
|
+
loop { read } if socket
|
37
|
+
rescue EOFError
|
38
|
+
# connection closed
|
39
|
+
end
|
40
|
+
|
41
|
+
def read
|
42
|
+
buffer = socket.readpartial(BLOCK_SIZE)
|
43
|
+
driver.parse buffer
|
44
|
+
end
|
45
|
+
|
46
|
+
def start_async
|
47
|
+
future = yield self if block_given?
|
48
|
+
|
49
|
+
Actor.new(future)
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
class Actor
|
55
|
+
attr_reader :future
|
56
|
+
|
57
|
+
def initialize(future)
|
58
|
+
@future = future
|
59
|
+
end
|
60
|
+
|
61
|
+
def join
|
62
|
+
@future.value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def connected?
|
67
|
+
!@connected.nil?
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_socket
|
71
|
+
socket = TCPSocket.new(addr, port)
|
72
|
+
socket = SSLSocket.new(socket, build_ssl_context) if secure?
|
73
|
+
socket
|
74
|
+
end
|
75
|
+
|
76
|
+
def build_ssl_context
|
77
|
+
OpenSSL::SSL::SSLContext.new(:TLSv1_2_client)
|
78
|
+
end
|
79
|
+
|
80
|
+
def build_driver
|
81
|
+
::WebSocket::Driver.client(self)
|
82
|
+
end
|
83
|
+
|
84
|
+
def connect
|
85
|
+
@socket = build_socket
|
86
|
+
@connected = @socket.connect
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'faye/websocket'
|
2
|
+
require 'eventmachine'
|
3
|
+
|
4
|
+
module Slack
|
5
|
+
module RealTime
|
6
|
+
module Concurrency
|
7
|
+
module Eventmachine
|
8
|
+
class Socket < Slack::RealTime::Socket
|
9
|
+
def start_async
|
10
|
+
thread = ensure_reactor_running
|
11
|
+
|
12
|
+
yield self if block_given?
|
13
|
+
|
14
|
+
thread
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_data(message)
|
18
|
+
driver.send(message)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
# @return [Thread]
|
24
|
+
def ensure_reactor_running
|
25
|
+
return if EventMachine.reactor_running?
|
26
|
+
|
27
|
+
reactor = Thread.new { EventMachine.run }
|
28
|
+
Thread.pass until EventMachine.reactor_running?
|
29
|
+
reactor
|
30
|
+
end
|
31
|
+
|
32
|
+
def connect
|
33
|
+
@driver = ::Faye::WebSocket::Client.new(url, nil, options)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module Slack
|
2
2
|
module RealTime
|
3
3
|
module Config
|
4
|
+
class NoConcurrencyError < StandardError; end
|
5
|
+
|
4
6
|
extend self
|
5
7
|
|
6
8
|
ATTRIBUTES = [
|
7
9
|
:token,
|
8
10
|
:websocket_ping,
|
9
|
-
:websocket_proxy
|
11
|
+
:websocket_proxy,
|
12
|
+
:concurrency
|
10
13
|
]
|
11
14
|
|
12
15
|
attr_accessor(*Config::ATTRIBUTES)
|
@@ -15,6 +18,25 @@ module Slack
|
|
15
18
|
self.websocket_ping = 30
|
16
19
|
self.websocket_proxy = nil
|
17
20
|
self.token = nil
|
21
|
+
self.concurrency = method(:detect_concurrency)
|
22
|
+
end
|
23
|
+
|
24
|
+
def concurrency
|
25
|
+
(val = @concurrency).respond_to?(:call) ? val.call : val
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def detect_concurrency
|
31
|
+
[:Eventmachine, :Celluloid].each do |concurrency|
|
32
|
+
begin
|
33
|
+
return Slack::RealTime::Concurrency.const_get(concurrency)
|
34
|
+
rescue LoadError
|
35
|
+
false # could not be loaded, missing dependencies
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
fail NoConcurrencyError, 'Missing concurrency. Add faye-websocket or celluloid-io to your Gemfile.'
|
18
40
|
end
|
19
41
|
end
|
20
42
|
|
@@ -3,40 +3,78 @@ module Slack
|
|
3
3
|
class Socket
|
4
4
|
attr_accessor :url
|
5
5
|
attr_accessor :options
|
6
|
+
attr_reader :driver
|
6
7
|
|
7
8
|
def initialize(url, options = {})
|
8
9
|
@url = url
|
9
10
|
@options = options
|
11
|
+
@driver = nil
|
10
12
|
end
|
11
13
|
|
12
|
-
def send_data(
|
13
|
-
|
14
|
+
def send_data(message)
|
15
|
+
case message
|
16
|
+
when Numeric then driver.text(message.to_s)
|
17
|
+
when String then driver.text(message)
|
18
|
+
when Array then driver.binary(message)
|
19
|
+
else false
|
20
|
+
end
|
14
21
|
end
|
15
22
|
|
16
|
-
def connect!
|
23
|
+
def connect!
|
17
24
|
return if connected?
|
18
25
|
|
19
|
-
|
20
|
-
|
21
|
-
@ws.on :close do |event|
|
22
|
-
close(event)
|
23
|
-
end
|
26
|
+
connect
|
24
27
|
|
25
|
-
yield
|
28
|
+
yield driver if block_given?
|
26
29
|
end
|
27
30
|
|
28
31
|
def disconnect!
|
29
|
-
|
32
|
+
driver.close
|
30
33
|
end
|
31
34
|
|
32
35
|
def connected?
|
33
|
-
|
36
|
+
!driver.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
def start_sync(&block)
|
40
|
+
thread = start_async(&block)
|
41
|
+
thread.join if thread
|
42
|
+
rescue Interrupt
|
43
|
+
thread.exit if thread
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [#join]
|
47
|
+
def start_async
|
48
|
+
fail NotImplementedError, "Expected #{self.class} to implement #{__method__}."
|
34
49
|
end
|
35
50
|
|
36
51
|
protected
|
37
52
|
|
53
|
+
def addr
|
54
|
+
URI(url).host
|
55
|
+
end
|
56
|
+
|
57
|
+
def secure?
|
58
|
+
port == URI::HTTPS::DEFAULT_PORT
|
59
|
+
end
|
60
|
+
|
61
|
+
def port
|
62
|
+
case (uri = URI(url)).scheme
|
63
|
+
when 'wss'.freeze, 'https'.freeze
|
64
|
+
URI::HTTPS::DEFAULT_PORT
|
65
|
+
when 'ws', 'http'.freeze
|
66
|
+
URI::HTTP::DEFAULT_PORT
|
67
|
+
else
|
68
|
+
uri.port
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def connect
|
73
|
+
fail NotImplementedError, "Expected #{self.class} to implement #{__method__}."
|
74
|
+
end
|
75
|
+
|
38
76
|
def close(_event)
|
39
|
-
@
|
77
|
+
@driver = nil
|
40
78
|
end
|
41
79
|
end
|
42
80
|
end
|
data/lib/slack/version.rb
CHANGED
@@ -16,6 +16,7 @@ require 'slack/web/api/endpoints/rtm'
|
|
16
16
|
require 'slack/web/api/endpoints/search'
|
17
17
|
require 'slack/web/api/endpoints/stars'
|
18
18
|
require 'slack/web/api/endpoints/team'
|
19
|
+
require 'slack/web/api/endpoints/usergroups'
|
19
20
|
require 'slack/web/api/endpoints/users'
|
20
21
|
|
21
22
|
module Slack
|
@@ -38,6 +39,7 @@ module Slack
|
|
38
39
|
include Search
|
39
40
|
include Stars
|
40
41
|
include Team
|
42
|
+
include Usergroups
|
41
43
|
include Users
|
42
44
|
end
|
43
45
|
end
|
@@ -21,7 +21,7 @@ module Slack
|
|
21
21
|
# This method closes a private group.
|
22
22
|
#
|
23
23
|
# @option options [group] :channel
|
24
|
-
# Group to
|
24
|
+
# Group to close.
|
25
25
|
# @see https://api.slack.com/methods/groups.close
|
26
26
|
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/groups.close.json
|
27
27
|
def groups_close(options = {})
|
@@ -31,7 +31,7 @@ module Slack
|
|
31
31
|
# @option options [Object] :app_id
|
32
32
|
# Filter logs to this API application. Defaults to all logs.
|
33
33
|
# @option options [user] :user
|
34
|
-
# Filter logs generated by this user
|
34
|
+
# Filter logs generated by this user's actions. Defaults to all logs.
|
35
35
|
# @option options [Object] :change_type
|
36
36
|
# Filter logs with this change type. Defaults to all logs.
|
37
37
|
# @see https://api.slack.com/methods/team.integrationLogs
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# This file was auto-generated by lib/slack/web/api/tasks/generate.rake
|
2
|
+
|
3
|
+
module Slack
|
4
|
+
module Web
|
5
|
+
module Api
|
6
|
+
module Endpoints
|
7
|
+
module Usergroups
|
8
|
+
#
|
9
|
+
# This method is used to create a user group.
|
10
|
+
#
|
11
|
+
# @option options [Object] :name
|
12
|
+
# A name for the user group. Must be unique among user groups.
|
13
|
+
# @option options [Object] :handle
|
14
|
+
# A mention handle. Must be unique among channels, users and user groups.
|
15
|
+
# @option options [Object] :description
|
16
|
+
# A short description of the user group.
|
17
|
+
# @option options [Object] :channels
|
18
|
+
# A comma separated string of encoded channel IDs for which the user group uses as a default.
|
19
|
+
# @option options [Object] :include_count
|
20
|
+
# Include the number of users in each user group.
|
21
|
+
# @see https://api.slack.com/methods/usergroups.create
|
22
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.create.json
|
23
|
+
def usergroups_create(options = {})
|
24
|
+
throw ArgumentError.new('Required arguments :name missing') if options[:name].nil?
|
25
|
+
post('usergroups.create', options)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# This method disables an existing user group.
|
30
|
+
#
|
31
|
+
# @option options [Object] :usergroup
|
32
|
+
# The encoded ID of the user group to disable.
|
33
|
+
# @option options [Object] :include_count
|
34
|
+
# Include the number of users in the user group.
|
35
|
+
# @see https://api.slack.com/methods/usergroups.disable
|
36
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.disable.json
|
37
|
+
def usergroups_disable(options = {})
|
38
|
+
throw ArgumentError.new('Required arguments :usergroup missing') if options[:usergroup].nil?
|
39
|
+
post('usergroups.disable', options)
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# This method enables a user group which was previously disabled.
|
44
|
+
#
|
45
|
+
# @option options [Object] :usergroup
|
46
|
+
# The encoded ID of the user group to enable.
|
47
|
+
# @option options [Object] :include_count
|
48
|
+
# Include the number of users in the user group.
|
49
|
+
# @see https://api.slack.com/methods/usergroups.enable
|
50
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.enable.json
|
51
|
+
def usergroups_enable(options = {})
|
52
|
+
throw ArgumentError.new('Required arguments :usergroup missing') if options[:usergroup].nil?
|
53
|
+
post('usergroups.enable', options)
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# This method returns a list of all user groups in the team. This can optionally include disabled user groups.
|
58
|
+
#
|
59
|
+
# @option options [Object] :include_disabled
|
60
|
+
# Include disabled user groups.
|
61
|
+
# @option options [Object] :include_count
|
62
|
+
# Include the number of users in each user group.
|
63
|
+
# @option options [Object] :include_users
|
64
|
+
# Include the list of users for each user group.
|
65
|
+
# @see https://api.slack.com/methods/usergroups.list
|
66
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.list.json
|
67
|
+
def usergroups_list(options = {})
|
68
|
+
post('usergroups.list', options)
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# This method updates the properties of an existing user group.
|
73
|
+
#
|
74
|
+
# @option options [Object] :usergroup
|
75
|
+
# The encoded ID of the user group to update.
|
76
|
+
# @option options [Object] :name
|
77
|
+
# A name for the user group. Must be unique among user groups.
|
78
|
+
# @option options [Object] :handle
|
79
|
+
# A mention handle. Must be unique among channels, users and user groups.
|
80
|
+
# @option options [Object] :description
|
81
|
+
# A short description of the user group.
|
82
|
+
# @option options [Object] :channels
|
83
|
+
# A comma separated string of encoded channel IDs for which the user group uses as a default.
|
84
|
+
# @option options [Object] :include_count
|
85
|
+
# Include the number of users in the user group.
|
86
|
+
# @see https://api.slack.com/methods/usergroups.update
|
87
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.update.json
|
88
|
+
def usergroups_update(options = {})
|
89
|
+
throw ArgumentError.new('Required arguments :usergroup missing') if options[:usergroup].nil?
|
90
|
+
post('usergroups.update', options)
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# This method updates the list of users that belong to a user group. This method replaces all users in a user group with the list of users provided in the users parameter.
|
95
|
+
#
|
96
|
+
# @option options [Object] :usergroup
|
97
|
+
# The encoded ID of the user group to update.
|
98
|
+
# @option options [Object] :users
|
99
|
+
# A comma separated string of encoded user IDs that represent the entire list of users for the user group.
|
100
|
+
# @option options [Object] :include_count
|
101
|
+
# Include the number of users in the user group.
|
102
|
+
# @see https://api.slack.com/methods/usergroups.users
|
103
|
+
# @see https://github.com/dblock/slack-api-ref/blob/master/methods/usergroups.users.json
|
104
|
+
def usergroups_users(options = {})
|
105
|
+
throw ArgumentError.new('Required arguments :usergroup missing') if options[:usergroup].nil?
|
106
|
+
throw ArgumentError.new('Required arguments :users missing') if options[:users].nil?
|
107
|
+
post('usergroups.users', options)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/slack/web/api/error.rb
CHANGED